Skip to content

Commit 9413c09

Browse files
authored
Merge pull request #22 from nocarryr/global-dispatcher
Add "Global Dispatcher"
2 parents 33aafaa + e33b432 commit 9413c09

19 files changed

+521
-15
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ jobs:
1111

1212
runs-on: ubuntu-20.04
1313
strategy:
14+
fail-fast: false
1415
matrix:
1516
python-version: [3.6, 3.7, 3.8, 3.9, "3.10", "3.11"]
1617

doc/source/conftest.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import pytest
2+
3+
@pytest.fixture(autouse=True)
4+
def dispatcher_cleanup():
5+
import pydispatch
6+
pydispatch._GLOBAL_DISPATCHER._Dispatcher__events.clear()
7+
pydispatch.decorators._CACHED_CALLBACKS.cache.clear()
8+
yield
9+
pydispatch._GLOBAL_DISPATCHER._Dispatcher__events.clear()
10+
pydispatch.decorators._CACHED_CALLBACKS.cache.clear()

doc/source/global-dispatcher.rst

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
.. _global-dispatcher:
2+
3+
Global Dispatcher
4+
=================
5+
6+
.. currentmodule:: pydispatch
7+
8+
.. versionadded:: 0.2.2
9+
10+
At the module-level, most of the functionality of :class:`~.dispatch.Dispatcher`
11+
can be used directly as a `singleton`_ instance. Note that this interface only
12+
supports event dispatching (not :ref:`properties`).
13+
14+
When used this way, the concept is similar to the `Signals Framework`_ found in Django.
15+
16+
Basic Usage
17+
-----------
18+
19+
Events can be registered using :func:`register_event`, connected to callbacks
20+
using :func:`bind` and dispatched with the :func:`emit` function.
21+
22+
>>> import pydispatch
23+
24+
>>> def my_callback(message, **kwargs):
25+
... print(f'my_callback: "{message}"')
26+
27+
>>> # register 'event_a' as an event and bind it to my_callback
28+
>>> pydispatch.register_event('event_a')
29+
>>> pydispatch.bind(event_a=my_callback)
30+
31+
>>> # emit the event
32+
>>> pydispatch.emit('event_a', 'hello')
33+
my_callback: "hello"
34+
35+
>>> # unbind the callback
36+
>>> pydispatch.unbind(my_callback)
37+
>>> pydispatch.emit('event_a', 'still there?')
38+
39+
>>> # (Nothing printed)
40+
41+
42+
The @receiver Decorator
43+
-----------------------
44+
45+
To simplify binding callbacks to events, the :func:`~decorators.receiver` decorator may be used.
46+
47+
>>> from pydispatch import receiver
48+
49+
>>> @receiver('event_a')
50+
... def my_callback(message, **kwargs):
51+
... print(f'my_callback: "{message}"')
52+
53+
>>> pydispatch.emit('event_a', 'hello again!')
54+
my_callback: "hello again!"
55+
56+
Note that there is currently no way to :func:`unbind` a callback defined in this way.
57+
58+
59+
Arguments
60+
^^^^^^^^^
61+
62+
If the event name has not been registered beforehand, the ``cache`` and ``auto_register``
63+
arguments to :func:`~decorators.receiver` may be used
64+
65+
cache
66+
"""""
67+
68+
The ``cache`` argument stores the callback and will bind it to the event
69+
once it is registered.
70+
71+
>>> # No event named 'foo' exists yet
72+
>>> @receiver('foo', cache=True)
73+
... def on_foo(message, **kwargs):
74+
... print(f'on_foo: "{message}"')
75+
76+
>>> # on_foo will be connected after the call to register_event
77+
>>> pydispatch.register_event('foo')
78+
>>> pydispatch.emit('foo', 'bar')
79+
on_foo: "bar"
80+
81+
auto_register
82+
"""""""""""""
83+
84+
The ``auto_register`` argument will immediately register the event if it does not exist
85+
86+
>>> @receiver('bar', auto_register=True)
87+
... def on_bar(message, **kwargs):
88+
... print(f'on_bar: "{message}"')
89+
90+
>>> pydispatch.emit('bar', 'baz')
91+
on_bar: "baz"
92+
93+
94+
Async Support
95+
^^^^^^^^^^^^^
96+
97+
If the decorated callback is a :term:`coroutine function` or method,
98+
the :class:`EventLoop <asyncio.BaseEventLoop>` returned by
99+
:func:`asyncio.get_event_loop` will be used as the ``loop`` argument to
100+
:func:`bind_async`.
101+
102+
This will in most cases be the desired behavior unless multiple event loops
103+
(in separate threads) are being used.
104+
105+
106+
107+
.. _singleton: https://en.wikipedia.org/wiki/Singleton_pattern
108+
.. _Signals Framework: https://docs.djangoproject.com/en/4.2/topics/signals/

doc/source/overview.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ Overview
77
dispatcher
88
properties
99
async
10+
global-dispatcher

doc/source/properties.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
.. _properties:
2+
13
Properties
24
==========
35

doc/source/reference/aioutils.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
pydispatch.aioutils module
1+
:mod:`pydispatch.aioutils`
22
==========================
33

44
.. automodule:: pydispatch.aioutils
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
:mod:`pydispatch.decorators`
2+
============================
3+
4+
.. versionadded:: 0.2.2
5+
6+
.. automodule:: pydispatch.decorators
7+
:members:

doc/source/reference/dispatch.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
pydispatch.dispatch module
1+
:mod:`pydispatch.dispatch`
22
==========================
33

44
.. automodule:: pydispatch.dispatch

doc/source/reference/index.rst

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,4 @@ Reference
44
.. toctree::
55
:maxdepth: 3
66

7-
dispatch
8-
properties
9-
utils
10-
aioutils
7+
pydispatch-package

doc/source/reference/properties.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
pydispatch.properties module
1+
:mod:`pydispatch.properties`
22
============================
33

44
.. automodule:: pydispatch.properties

0 commit comments

Comments
 (0)