1
0
Fork 0
forked from github/pelican

Merge pull request #3238 from avaris/ordered-blinker

This commit is contained in:
Justin Mayer 2023-11-02 23:27:15 +01:00 committed by GitHub
commit dc1b6ab14d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 34 additions and 6 deletions

View file

@ -94,9 +94,12 @@ which you map the signals to your plugin logic. Let's take a simple example::
your ``register`` callable or they will be garbage-collected before the
signal is emitted.
If multiple plugins connect to the same signal, there is no way to guarantee or
control in which order the plugins will be executed. This is a limitation
inherited from Blinker_, the dependency Pelican uses to implement signals.
If multiple plugins connect to the same signal, plugins will be executed in the
order they are connected. With ``PLUGINS`` setting, order will be as defined in
the setting. If you rely on auto-discovered namespace plugins, no ``PLUGINS``
setting, they will be connected in the same order they are discovered (same
order as ``pelican-plugins`` output). If you want to specify the order
explicitly, disable auto-discovery by defining ``PLUGINS`` in the desired order.
Namespace plugin structure
--------------------------
@ -341,4 +344,3 @@ custom article, using the ``article_generator_pretaxonomy`` signal::
.. _Pip: https://pip.pypa.io/
.. _pelican-plugins bug #314: https://github.com/getpelican/pelican-plugins/issues/314
.. _Blinker: https://pythonhosted.org/blinker/

View file

@ -1,4 +1,8 @@
from blinker import signal
from blinker import signal, Signal
from ordered_set import OrderedSet
# Signals will call functions in the order of connection, i.e. plugin order
Signal.set_class = OrderedSet
# Run-level signals:

View file

@ -8,6 +8,7 @@ from pelican.plugins._utils import (
load_plugins,
plugin_enabled,
)
from pelican.plugins.signals import signal
from pelican.tests.support import unittest
@ -263,3 +264,23 @@ class PluginTest(unittest.TestCase):
self.assertTrue(plugin_enabled("pelican.plugins.ns_plugin", plugins))
self.assertTrue(plugin_enabled("normal_plugin", plugins))
self.assertFalse(plugin_enabled("unknown", plugins))
def test_blinker_is_ordered(self):
"""ensure that call order is connetion order"""
dummy_signal = signal("dummpy_signal")
functions = []
expected = []
for i in range(50):
# function appends value of i to a list
def func(input, i=i):
input.append(i)
functions.append(func)
# we expect functions to be run in the connection order
dummy_signal.connect(func)
expected.append(i)
input = []
dummy_signal.send(input)
self.assertEqual(input, expected)

View file

@ -29,10 +29,11 @@ classifiers = [
]
requires-python = ">=3.8.1,<4.0"
dependencies = [
"blinker>=1.6.3",
"blinker>=1.7.0",
"docutils>=0.20.1",
"feedgenerator>=2.1.0",
"jinja2>=3.1.2",
"ordered-set>=4.1.0",
"pygments>=2.16.1",
"python-dateutil>=2.8.2",
"rich>=13.6.0",