Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 686fbff

Browse files
author
Oliver Maye
committedJan 8, 2025·
python-ecosys/pymitter: Added legacy branch from the original project.
Signed-off-by: Oliver Maye <maye@ihp-microelectronics.com>
1 parent e4cf095 commit 686fbff

File tree

10 files changed

+749
-0
lines changed

10 files changed

+749
-0
lines changed
 

Diff for: ‎python-ecosys/pymitter/LICENSE

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
Copyright (c) 2014-2021, Marcel Rieger
2+
All rights reserved.
3+
4+
Redistribution and use in source and binary forms, with or without
5+
modification, are permitted provided that the following conditions are met:
6+
7+
* Redistributions of source code must retain the above copyright notice, this
8+
list of conditions and the following disclaimer.
9+
10+
* Redistributions in binary form must reproduce the above copyright notice,
11+
this list of conditions and the following disclaimer in the documentation
12+
and/or other materials provided with the distribution.
13+
14+
* Neither the name of the copyright holder nor the names of its contributors
15+
may be used to endorse or promote products derived from this software without
16+
specific prior written permission.
17+
18+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Diff for: ‎python-ecosys/pymitter/MANIFEST.in

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
include pymitter.py setup.py requirements.txt README.md LICENSE .flake8
2+
global-exclude *.py[cod] __pycache__

Diff for: ‎python-ecosys/pymitter/README.md

+183
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
# pymitter
2+
3+
This is a fork of the [original pymitter project](https://pypi.org/project/pymitter/) by Marcel Rieger.
4+
Sources are from the legacy/py2 branch which is a frozen v0.3.2 of that project.
5+
At this state, the implementation is compatible to Python >= v2.7 including
6+
MicroPython with a language level v3.4.
7+
8+
Later versions of that project make use of type hints, which were introduced
9+
in Python 3.5. Type hints are currently not supported by MicroPython.
10+
11+
12+
## Features
13+
14+
- Namespaces with wildcards
15+
- Times to listen (TTL)
16+
- Usage via decorators or callbacks
17+
- Lightweight implementation, good performance
18+
19+
20+
## Installation
21+
22+
*pymitter* is a registered [MicroPython module](https://github.com/olimaye/micropython-lib),
23+
so the installation with *mip* is quite easy:
24+
25+
```console
26+
mpremote mip install pymitter
27+
```
28+
29+
30+
## Examples
31+
32+
### Basic usage
33+
34+
```python
35+
from pymitter import EventEmitter
36+
37+
38+
ee = EventEmitter()
39+
40+
41+
# decorator usage
42+
@ee.on("myevent")
43+
def handler1(arg):
44+
print("handler1 called with", arg)
45+
46+
47+
# callback usage
48+
def handler2(arg):
49+
print("handler2 called with", arg)
50+
51+
52+
ee.on("myotherevent", handler2)
53+
54+
55+
# emit
56+
ee.emit("myevent", "foo")
57+
# -> "handler1 called with foo"
58+
59+
ee.emit("myotherevent", "bar")
60+
# -> "handler2 called with bar"
61+
```
62+
63+
64+
### TTL (times to listen)
65+
66+
```python
67+
from pymitter import EventEmitter
68+
69+
70+
ee = EventEmitter()
71+
72+
73+
@ee.once("myevent")
74+
def handler1():
75+
print("handler1 called")
76+
77+
78+
@ee.on("myevent", ttl=10)
79+
def handler2():
80+
print("handler2 called")
81+
82+
83+
ee.emit("myevent")
84+
# -> "handler1 called"
85+
# -> "handler2 called"
86+
87+
ee.emit("myevent")
88+
# -> "handler2 called"
89+
```
90+
91+
92+
### Wildcards
93+
94+
```python
95+
from pymitter import EventEmitter
96+
97+
98+
ee = EventEmitter(wildcard=True)
99+
100+
101+
@ee.on("myevent.foo")
102+
def handler1():
103+
print("handler1 called")
104+
105+
106+
@ee.on("myevent.bar")
107+
def handler2():
108+
print("handler2 called")
109+
110+
111+
@ee.on("myevent.*")
112+
def hander3():
113+
print("handler3 called")
114+
115+
116+
ee.emit("myevent.foo")
117+
# -> "handler1 called"
118+
# -> "handler3 called"
119+
120+
ee.emit("myevent.bar")
121+
# -> "handler2 called"
122+
# -> "handler3 called"
123+
124+
ee.emit("myevent.*")
125+
# -> "handler1 called"
126+
# -> "handler2 called"
127+
# -> "handler3 called"
128+
```
129+
130+
## API
131+
132+
133+
### ``EventEmitter(wildcard=False, delimiter=".", new_listener=False, max_listeners=-1)``
134+
135+
EventEmitter constructor. **Note**: always use *kwargs* for configuration. When *wildcard* is
136+
*True*, wildcards are used as shown in [this example](#wildcards). *delimiter* is used to seperate
137+
namespaces within events. If *new_listener* is *True*, the *"new_listener"* event is emitted every
138+
time a new listener is registered. Functions listening to this event are passed
139+
``(func, event=None)``. *max_listeners* defines the maximum number of listeners per event. Negative
140+
values mean infinity.
141+
142+
- #### ``on(event, func=None, ttl=-1)``
143+
Registers a function to an event. When *func* is *None*, decorator usage is assumed. *ttl*
144+
defines the times to listen. Negative values mean infinity. Returns the function.
145+
146+
- #### ``once(event, func=None)``
147+
Registers a function to an event with ``ttl = 1``. When *func* is *None*, decorator usage is
148+
assumed. Returns the function.
149+
150+
- #### ``on_any(func=None)``
151+
Registers a function that is called every time an event is emitted. When *func* is *None*,
152+
decorator usage is assumed. Returns the function.
153+
154+
- #### ``off(event, func=None)``
155+
Removes a function that is registered to an event. When *func* is *None*, decorator usage is
156+
assumed. Returns the function.
157+
158+
- #### ``off_any(func=None)``
159+
Removes a function that was registered via ``on_any()``. When *func* is *None*, decorator usage
160+
is assumed. Returns the function.
161+
162+
- #### ``off_all()``
163+
Removes all functions of all events.
164+
165+
- #### ``listeners(event)``
166+
Returns all functions that are registered to an event. Wildcards are not applied.
167+
168+
- #### ``listeners_any()``
169+
Returns all functions that were registered using ``on_any()``.
170+
171+
- #### ``listeners_all()``
172+
Returns all registered functions.
173+
174+
- #### ``emit(event, *args, **kwargs)``
175+
Emits an event. All functions of events that match *event* are invoked with *args* and *kwargs*
176+
in the exact order of their registeration. Wildcards might be applied.
177+
178+
179+
## Development
180+
181+
- Source hosted at [GitHub](https://github.com/riga/pymitter)
182+
- Python module hostet at [PyPI](https://pypi.python.org/pypi/pymitter)
183+
- Report issues, questions, feature requests on [GitHub Issues](https://github.com/riga/pymitter/issues)

Diff for: ‎python-ecosys/pymitter/examples.py

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# coding: utf-8
2+
3+
# python imports
4+
import os
5+
import sys
6+
from pymitter import EventEmitter
7+
8+
9+
# create an EventEmitter instance
10+
ee = EventEmitter(wildcard=True, new_listener=True, max_listeners=-1)
11+
12+
13+
@ee.on("new_listener")
14+
def on_new(func, event=None):
15+
print("added listener", event, func)
16+
17+
18+
@ee.on("foo")
19+
def handler_foo1(arg):
20+
print("foo handler 1 called with", arg)
21+
22+
23+
@ee.on("foo")
24+
def handler_foo2(arg):
25+
print("foo handler 2 called with", arg)
26+
27+
28+
@ee.on("foo.*", ttl=1)
29+
def handler_fooall(arg):
30+
print("foo.* handler called with", arg)
31+
32+
33+
@ee.on("foo.bar")
34+
def handler_foobar(arg):
35+
print("foo.bar handler called with", arg)
36+
37+
38+
@ee.on_any()
39+
def handler_any(*args, **kwargs):
40+
print("called every time")
41+
42+
43+
print("emit foo")
44+
ee.emit("foo", "test")
45+
print(10 * "-")
46+
47+
print("emit foo.bar")
48+
ee.emit("foo.bar", "test")
49+
print(10 * "-")
50+
51+
print("emit foo.*")
52+
ee.emit("foo.*", "test")
53+
print(10 * "-")

Diff for: ‎python-ecosys/pymitter/manifest.py

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
metadata(
2+
description="Event subscription and publishing tools.",
3+
version="0.3.2",
4+
pypi="pymitter",
5+
)
6+
7+
module("pymitter.py")

Diff for: ‎python-ecosys/pymitter/pymitter.py

+284
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,284 @@
1+
# coding: utf-8
2+
3+
"""
4+
Python port of the extended Node.js EventEmitter 2 approach providing namespaces, wildcards and TTL.
5+
"""
6+
7+
__author__ = "Marcel Rieger"
8+
__author_email__ = "github.riga@icloud.com"
9+
__copyright__ = "Copyright 2014-2022, Marcel Rieger"
10+
__credits__ = ["Marcel Rieger"]
11+
__contact__ = "https://github.com/riga/pymitter"
12+
__license__ = "BSD-3-Clause"
13+
__status__ = "Development"
14+
__version__ = "0.3.2"
15+
__all__ = ["EventEmitter", "Listener"]
16+
17+
18+
import time
19+
20+
21+
class EventEmitter(object):
22+
"""
23+
The EventEmitter class, ported from Node.js EventEmitter 2.
24+
25+
When *wildcard* is *True*, wildcards in event names are taken into account. When *new_listener*
26+
is *True*, a ``"new_listener"`` event is emitted every time a new listener is registered with
27+
arguments ``(func, event=None)``. *max_listeners* configures the maximum number of event
28+
listeners. A negative numbers means that this number is unlimited. Event names have namespace
29+
support with each namspace being separated by a *delimiter* which defaults to ``"."``.
30+
"""
31+
32+
CB_KEY = "__callbacks"
33+
WC_CHAR = "*"
34+
35+
def __init__(self, wildcard=False, new_listener=False, max_listeners=-1, delimiter="."):
36+
super(EventEmitter, self).__init__()
37+
38+
self.wildcard = wildcard
39+
self.delimiter = delimiter
40+
self.new_listener = new_listener
41+
self.max_listeners = max_listeners
42+
43+
self._tree = self._new_branch()
44+
45+
@classmethod
46+
def _new_branch(cls):
47+
"""
48+
Returns a new branch. Essentially, a branch is just a dictionary with a special item
49+
*CB_KEY* that holds registered functions. All other items are used to build a tree
50+
structure.
51+
"""
52+
return {cls.CB_KEY: []}
53+
54+
def _find_branch(self, event):
55+
"""
56+
Returns a branch of the tree structure that matches *event*. Wildcards are not applied.
57+
"""
58+
parts = event.split(self.delimiter)
59+
60+
if self.CB_KEY in parts:
61+
return None
62+
63+
branch = self._tree
64+
for p in parts:
65+
if p not in branch:
66+
return None
67+
branch = branch[p]
68+
69+
return branch
70+
71+
@classmethod
72+
def _remove_listener(cls, branch, func):
73+
"""
74+
Removes a listener given by its function *func* from a *branch*.
75+
"""
76+
listeners = branch[cls.CB_KEY]
77+
78+
indexes = [i for i, l in enumerate(listeners) if l.func == func]
79+
80+
for i in indexes[::-1]:
81+
listeners.pop(i)
82+
83+
def on(self, event, func=None, ttl=-1):
84+
"""
85+
Registers a function to an event. *ttl* defines the times to listen. Negative values mean
86+
infinity. When *func* is *None*, decorator usage is assumed. Returns the function.
87+
"""
88+
89+
def on(func):
90+
if not callable(func):
91+
return func
92+
93+
parts = event.split(self.delimiter)
94+
if self.CB_KEY in parts:
95+
return func
96+
97+
branch = self._tree
98+
for p in parts:
99+
branch = branch.setdefault(p, self._new_branch())
100+
101+
listeners = branch[self.CB_KEY]
102+
if 0 <= self.max_listeners <= len(listeners):
103+
return func
104+
105+
listener = Listener(func, event, ttl)
106+
listeners.append(listener)
107+
108+
if self.new_listener:
109+
self.emit("new_listener", func, event)
110+
111+
return func
112+
113+
return on(func) if func else on
114+
115+
def once(self, event, func=None):
116+
"""
117+
Registers a function to an event that is called once. When *func* is *None*, decorator usage
118+
is assumed. Returns the function.
119+
"""
120+
return self.on(event, func=func, ttl=1)
121+
122+
def on_any(self, func=None, ttl=-1):
123+
"""
124+
Registers a function that is called every time an event is emitted. *ttl* defines the times
125+
to listen. Negative values mean infinity. When *func* is *None*, decorator usage is assumed.
126+
Returns the function.
127+
"""
128+
129+
def on_any(func):
130+
if not callable(func):
131+
return func
132+
133+
listeners = self._tree[self.CB_KEY]
134+
if 0 <= self.max_listeners <= len(listeners):
135+
return func
136+
137+
listener = Listener(func, None, ttl)
138+
listeners.append(listener)
139+
140+
if self.new_listener:
141+
self.emit("new_listener", func)
142+
143+
return func
144+
145+
return on_any(func) if func else on_any
146+
147+
def off(self, event, func=None):
148+
"""
149+
Removes a function that is registered to an event. When *func* is *None*, decorator usage is
150+
assumed. Returns the function.
151+
"""
152+
153+
def off(func):
154+
branch = self._find_branch(event)
155+
if branch is None:
156+
return func
157+
158+
self._remove_listener(branch, func)
159+
160+
return func
161+
162+
return off(func) if func else off
163+
164+
def off_any(self, func=None):
165+
"""
166+
Removes a function that was registered via :py:meth:`on_any`. When *func* is *None*,
167+
decorator usage is assumed. Returns the function.
168+
"""
169+
170+
def off_any(func):
171+
self._remove_listener(self._tree, func)
172+
173+
return func
174+
175+
return off_any(func) if func else off_any
176+
177+
def off_all(self):
178+
"""
179+
Removes all registered functions.
180+
"""
181+
self._tree = self._new_branch()
182+
183+
def listeners(self, event):
184+
"""
185+
Returns all functions that are registered to an event. Wildcards are not applied.
186+
"""
187+
branch = self._find_branch(event)
188+
if branch is None:
189+
return []
190+
191+
return [listener.func for listener in branch[self.CB_KEY]]
192+
193+
def listeners_any(self):
194+
"""
195+
Returns all functions that were registered using :py:meth:`on_any`.
196+
"""
197+
return [listener.func for listener in self._tree[self.CB_KEY]]
198+
199+
def listeners_all(self):
200+
"""
201+
Returns all registered functions.
202+
"""
203+
listeners = list(self._tree[self.CB_KEY])
204+
205+
branches = list(self._tree.values())
206+
for b in branches:
207+
if not isinstance(b, dict):
208+
continue
209+
210+
branches.extend(b.values())
211+
212+
listeners.extend(b[self.CB_KEY])
213+
214+
return [listener.func for listener in listeners]
215+
216+
def emit(self, event, *args, **kwargs):
217+
"""
218+
Emits an *event*. All functions of events that match *event* are invoked with *args* and
219+
*kwargs* in the exact order of their registration. Wildcards might be applied.
220+
"""
221+
parts = event.split(self.delimiter)
222+
223+
if self.CB_KEY in parts:
224+
return
225+
226+
listeners = list(self._tree[self.CB_KEY])
227+
branches = [self._tree]
228+
229+
for p in parts:
230+
_branches = []
231+
for branch in branches:
232+
for k, b in branch.items():
233+
if k == self.CB_KEY:
234+
continue
235+
if k == p:
236+
_branches.append(b)
237+
elif self.wildcard and self.WC_CHAR in (p, k):
238+
_branches.append(b)
239+
branches = _branches
240+
241+
for b in branches:
242+
listeners.extend(b[self.CB_KEY])
243+
244+
# sort listeners by registration time
245+
listeners = sorted(listeners, key=lambda listener: listener.time)
246+
247+
# call listeners in the order of their registration time
248+
for listener in sorted(listeners, key=lambda listener: listener.time):
249+
listener(*args, **kwargs)
250+
251+
# remove listeners whose ttl value is 0
252+
for listener in listeners:
253+
if listener.ttl == 0:
254+
self.off(listener.event, func=listener.func)
255+
256+
257+
class Listener(object):
258+
"""
259+
A simple event listener class that wraps a function *func* for a specific *event* and that keeps
260+
track of the times to listen left.
261+
"""
262+
263+
def __init__(self, func, event, ttl):
264+
super(Listener, self).__init__()
265+
266+
self.func = func
267+
self.event = event
268+
self.ttl = ttl
269+
270+
# store the registration time
271+
self.time = time.time()
272+
273+
def __call__(self, *args, **kwargs):
274+
"""
275+
Invokes the wrapped function when ttl is non-zero, decreases the ttl value when positive and
276+
returns whether it reached zero or not.
277+
"""
278+
if self.ttl != 0:
279+
self.func(*args, **kwargs)
280+
281+
if self.ttl > 0:
282+
self.ttl -= 1
283+
284+
return self.ttl == 0

Diff for: ‎python-ecosys/pymitter/requirements.txt

Whitespace-only changes.

Diff for: ‎python-ecosys/pymitter/requirements_test.txt

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
flake8<4;python_version<="2.7"
2+
flake8>=4.0.1;python_version>="3.0"
3+
flake8-commas>=2
4+
flake8-quotes>=3,<3.3;python_version<="2.7"
5+
flake8-quotes>=3;python_version>="3.0"

Diff for: ‎python-ecosys/pymitter/setup.py

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# coding: utf-8
2+
3+
4+
import os
5+
from setuptools import setup
6+
7+
import pymitter
8+
9+
10+
this_dir = os.path.dirname(os.path.abspath(__file__))
11+
12+
keywords = [
13+
"event",
14+
"emitter",
15+
"eventemitter",
16+
"wildcard",
17+
"node",
18+
"nodejs",
19+
]
20+
21+
classifiers = [
22+
"Programming Language :: Python",
23+
"Programming Language :: Python :: 2",
24+
"Programming Language :: Python :: 2.7",
25+
"Programming Language :: Python :: 3",
26+
"Programming Language :: Python :: 3.4",
27+
"Programming Language :: Python :: 3.5",
28+
"Programming Language :: Python :: 3.6",
29+
"Programming Language :: Python :: 3.7",
30+
"Programming Language :: Python :: 3.8",
31+
"Programming Language :: Python :: 3.9",
32+
"Development Status :: 5 - Production/Stable",
33+
"Operating System :: OS Independent",
34+
"License :: OSI Approved :: BSD License",
35+
"Intended Audience :: Developers",
36+
]
37+
38+
# read the readme file
39+
with open(os.path.join(this_dir, "README.md"), "r") as f:
40+
long_description = f.read()
41+
42+
# load installation requirements
43+
with open(os.path.join(this_dir, "requirements.txt"), "r") as f:
44+
install_requires = [line.strip() for line in f.readlines() if line.strip()]
45+
46+
setup(
47+
name=pymitter.__name__,
48+
version=pymitter.__version__,
49+
author=pymitter.__author__,
50+
author_email=pymitter.__author_email__,
51+
description=pymitter.__doc__.strip().split("\n")[0].strip(),
52+
license=pymitter.__license__,
53+
url=pymitter.__contact__,
54+
keywords=keywords,
55+
classifiers=classifiers,
56+
long_description=long_description,
57+
long_description_content_type="text/markdown",
58+
install_requires=install_requires,
59+
python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4",
60+
zip_safe=False,
61+
py_modules=[pymitter.__name__],
62+
)

Diff for: ‎python-ecosys/pymitter/tests.py

+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# coding: utf-8
2+
3+
4+
import unittest
5+
6+
from pymitter import EventEmitter
7+
8+
9+
class AllTestCase(unittest.TestCase):
10+
def __init__(self, *args, **kwargs):
11+
super(AllTestCase, self).__init__(*args, **kwargs)
12+
13+
self.ee1 = EventEmitter()
14+
self.ee2 = EventEmitter(wildcard=True)
15+
self.ee3 = EventEmitter(wildcard=True, delimiter=":")
16+
self.ee4 = EventEmitter(new_listener=True)
17+
self.ee5 = EventEmitter(max_listeners=1)
18+
19+
def test_1_callback_usage(self):
20+
stack = []
21+
22+
def handler(arg):
23+
stack.append("1_callback_usage_" + arg)
24+
25+
self.ee1.on("1_callback_usage", handler)
26+
27+
self.ee1.emit("1_callback_usage", "foo")
28+
self.assertTrue(stack[-1] == "1_callback_usage_foo")
29+
30+
def test_1_decorator_usage(self):
31+
stack = []
32+
33+
@self.ee1.on("1_decorator_usage")
34+
def handler(arg):
35+
stack.append("1_decorator_usage_" + arg)
36+
37+
self.ee1.emit("1_decorator_usage", "bar")
38+
self.assertTrue(stack[-1] == "1_decorator_usage_bar")
39+
40+
def test_1_ttl_on(self):
41+
stack = []
42+
43+
@self.ee1.on("1_ttl_on", ttl=1)
44+
def handler(arg):
45+
stack.append("1_ttl_on_" + arg)
46+
47+
self.ee1.emit("1_ttl_on", "foo")
48+
self.assertTrue(stack[-1] == "1_ttl_on_foo")
49+
50+
self.ee1.emit("1_ttl_on", "bar")
51+
self.assertTrue(stack[-1] == "1_ttl_on_foo")
52+
53+
def test_1_ttl_once(self):
54+
stack = []
55+
56+
@self.ee1.once("1_ttl_once")
57+
def handler(arg):
58+
stack.append("1_ttl_once_" + arg)
59+
60+
self.ee1.emit("1_ttl_once", "foo")
61+
self.assertTrue(stack[-1] == "1_ttl_once_foo")
62+
63+
self.ee1.emit("1_ttl_once", "bar")
64+
self.assertTrue(stack[-1] == "1_ttl_once_foo")
65+
66+
def test_2_on_all(self):
67+
stack = []
68+
69+
@self.ee2.on("2_on_all.*")
70+
def handler():
71+
stack.append("2_on_all")
72+
73+
self.ee2.emit("2_on_all.foo")
74+
self.assertTrue(stack[-1] == "2_on_all")
75+
76+
def test_2_emit_all(self):
77+
stack = []
78+
79+
@self.ee2.on("2_emit_all.foo")
80+
def handler():
81+
stack.append("2_emit_all.foo")
82+
83+
self.ee2.emit("2_emit_all.*")
84+
self.assertTrue(stack[-1] == "2_emit_all.foo")
85+
86+
def test_3_delimiter(self):
87+
stack = []
88+
89+
@self.ee3.on("3_delimiter:*")
90+
def handler():
91+
stack.append("3_delimiter")
92+
93+
self.ee3.emit("3_delimiter:foo")
94+
self.assertTrue(stack[-1] == "3_delimiter")
95+
96+
def test_4_new(self):
97+
stack = []
98+
99+
@self.ee4.on("new_listener")
100+
def handler(func, event=None):
101+
stack.append((func, event))
102+
103+
def newhandler():
104+
pass
105+
106+
self.ee4.on("4_new", newhandler)
107+
108+
self.assertTrue(stack[-1] == (newhandler, "4_new"))
109+
110+
def test_5_max(self):
111+
stack = []
112+
113+
@self.ee5.on("5_max")
114+
def handler1():
115+
stack.append("5_max_1")
116+
117+
@self.ee5.on("5_max")
118+
def handler2():
119+
stack.append("5_max_2")
120+
121+
self.ee5.emit("5_max")
122+
self.assertTrue(stack[-1] == "5_max_1")
123+
124+
125+
if __name__ == "__main__":
126+
unittest.main()

0 commit comments

Comments
 (0)
Please sign in to comment.