[Python-modules-commits] [pyee] 01/03: import pyee_3.0.3.orig.tar.gz

Ethan Ward ethanward-guest at moszumanska.debian.org
Mon Jul 24 19:59:25 UTC 2017


This is an automated email from the git hooks/post-receive script.

ethanward-guest pushed a commit to branch master
in repository pyee.

commit a53727b59001424354a52a0bd190907ab41d4c7f
Author: Ethan Ward <ethan.ward at mycroft.ai>
Date:   Mon Jul 24 14:53:24 2017 -0500

    import pyee_3.0.3.orig.tar.gz
---
 MANIFEST.in                        |   4 +
 PKG-INFO                           |  56 ++++++++
 README.rst                         |  34 +++++
 pyee.egg-info/PKG-INFO             |  56 ++++++++
 pyee.egg-info/SOURCES.txt          |  13 ++
 pyee.egg-info/dependency_links.txt |   1 +
 pyee.egg-info/top_level.txt        |   1 +
 pyee/__init__.py                   | 210 +++++++++++++++++++++++++++++
 setup.cfg                          |   7 +
 setup.py                           |  42 ++++++
 tests/conftest.py                  |   8 ++
 tests/test_async.py                | 115 ++++++++++++++++
 tests/test_sync.py                 | 261 +++++++++++++++++++++++++++++++++++++
 version.txt                        |   1 +
 14 files changed, 809 insertions(+)

diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..6935e1c
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,4 @@
+include README.rst
+include CHANGELOG
+include version.txt
+recursive-include tests *.py
diff --git a/PKG-INFO b/PKG-INFO
new file mode 100644
index 0000000..d1cbc14
--- /dev/null
+++ b/PKG-INFO
@@ -0,0 +1,56 @@
+Metadata-Version: 1.1
+Name: pyee
+Version: 3.0.3
+Summary: A port of node.js's EventEmitter to python.
+Home-page: https://github.com/jfhbrook/pyee
+Author: Joshua Holbrook
+Author-email: josh.holbrook at gmail.com
+License: UNKNOWN
+Description: pyee
+        ====
+        
+        .. image:: https://travis-ci.org/jfhbrook/pyee.png
+           :target: https://travis-ci.org/jfhbrook/pyee
+        .. image:: https://readthedocs.org/projects/pyee/badge/?version=latest
+           :target: https://pyee.readthedocs.io
+        
+        pyee supplies an ``EventEmitter`` object similar to the ``EventEmitter``
+        from Node.js.
+        
+        Docs:
+        -----
+        
+        Authgenerated API docs, including basic installation directions and examples,
+        can be found at https://pyee.readthedocs.io .
+        
+        Development:
+        ------------
+        
+        - For development purposes, you can link this project to your global space with
+          ``python setup.py develop``.
+        - Tests can be ran with ``python setup.py test``.
+        - Documentation can be generated with ``cd ./docs && make html``.
+        
+        Changelog:
+        ----------
+        
+        https://github.com/jfhbrook/pyee/blob/master/CHANGELOG.md
+        
+        License:
+        --------
+        
+        MIT/X11, see LICENSE file.
+        
+Keywords: events,emitter,node.js,node,eventemitter,event_emitter
+Platform: UNKNOWN
+Classifier: Programming Language :: Python
+Classifier: Development Status :: 4 - Beta
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Topic :: Other/Nonlisted Topic
diff --git a/README.rst b/README.rst
new file mode 100644
index 0000000..cab78c3
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,34 @@
+pyee
+====
+
+.. image:: https://travis-ci.org/jfhbrook/pyee.png
+   :target: https://travis-ci.org/jfhbrook/pyee
+.. image:: https://readthedocs.org/projects/pyee/badge/?version=latest
+   :target: https://pyee.readthedocs.io
+
+pyee supplies an ``EventEmitter`` object similar to the ``EventEmitter``
+from Node.js.
+
+Docs:
+-----
+
+Authgenerated API docs, including basic installation directions and examples,
+can be found at https://pyee.readthedocs.io .
+
+Development:
+------------
+
+- For development purposes, you can link this project to your global space with
+  ``python setup.py develop``.
+- Tests can be ran with ``python setup.py test``.
+- Documentation can be generated with ``cd ./docs && make html``.
+
+Changelog:
+----------
+
+https://github.com/jfhbrook/pyee/blob/master/CHANGELOG.md
+
+License:
+--------
+
+MIT/X11, see LICENSE file.
diff --git a/pyee.egg-info/PKG-INFO b/pyee.egg-info/PKG-INFO
new file mode 100644
index 0000000..d1cbc14
--- /dev/null
+++ b/pyee.egg-info/PKG-INFO
@@ -0,0 +1,56 @@
+Metadata-Version: 1.1
+Name: pyee
+Version: 3.0.3
+Summary: A port of node.js's EventEmitter to python.
+Home-page: https://github.com/jfhbrook/pyee
+Author: Joshua Holbrook
+Author-email: josh.holbrook at gmail.com
+License: UNKNOWN
+Description: pyee
+        ====
+        
+        .. image:: https://travis-ci.org/jfhbrook/pyee.png
+           :target: https://travis-ci.org/jfhbrook/pyee
+        .. image:: https://readthedocs.org/projects/pyee/badge/?version=latest
+           :target: https://pyee.readthedocs.io
+        
+        pyee supplies an ``EventEmitter`` object similar to the ``EventEmitter``
+        from Node.js.
+        
+        Docs:
+        -----
+        
+        Authgenerated API docs, including basic installation directions and examples,
+        can be found at https://pyee.readthedocs.io .
+        
+        Development:
+        ------------
+        
+        - For development purposes, you can link this project to your global space with
+          ``python setup.py develop``.
+        - Tests can be ran with ``python setup.py test``.
+        - Documentation can be generated with ``cd ./docs && make html``.
+        
+        Changelog:
+        ----------
+        
+        https://github.com/jfhbrook/pyee/blob/master/CHANGELOG.md
+        
+        License:
+        --------
+        
+        MIT/X11, see LICENSE file.
+        
+Keywords: events,emitter,node.js,node,eventemitter,event_emitter
+Platform: UNKNOWN
+Classifier: Programming Language :: Python
+Classifier: Development Status :: 4 - Beta
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Topic :: Other/Nonlisted Topic
diff --git a/pyee.egg-info/SOURCES.txt b/pyee.egg-info/SOURCES.txt
new file mode 100644
index 0000000..2b76adc
--- /dev/null
+++ b/pyee.egg-info/SOURCES.txt
@@ -0,0 +1,13 @@
+MANIFEST.in
+README.rst
+setup.cfg
+setup.py
+version.txt
+pyee/__init__.py
+pyee.egg-info/PKG-INFO
+pyee.egg-info/SOURCES.txt
+pyee.egg-info/dependency_links.txt
+pyee.egg-info/top_level.txt
+tests/conftest.py
+tests/test_async.py
+tests/test_sync.py
\ No newline at end of file
diff --git a/pyee.egg-info/dependency_links.txt b/pyee.egg-info/dependency_links.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pyee.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
diff --git a/pyee.egg-info/top_level.txt b/pyee.egg-info/top_level.txt
new file mode 100644
index 0000000..4207325
--- /dev/null
+++ b/pyee.egg-info/top_level.txt
@@ -0,0 +1 @@
+pyee
diff --git a/pyee/__init__.py b/pyee/__init__.py
new file mode 100644
index 0000000..d4effab
--- /dev/null
+++ b/pyee/__init__.py
@@ -0,0 +1,210 @@
+# -*- coding: utf-8 -*-
+
+"""
+pyee supplies an ``EventEmitter`` object similar to the ``EventEmitter``
+from Node.js. It supports both synchronous callbacks and asyncio coroutines.
+
+
+Example
+-------
+
+::
+
+    In [1]: from pyee import EventEmitter
+
+    In [2]: ee = EventEmitter()
+
+    In [3]: @ee.on('event')
+       ...: def event_handler():
+       ...:     print('BANG BANG')
+       ...:
+
+    In [4]: ee.emit('event')
+    BANG BANG
+
+    In [5]:
+
+"""
+
+try:
+    from asyncio import iscoroutine, ensure_future
+except ImportError:
+    iscoroutine = None
+    ensure_future = None
+
+from collections import defaultdict
+
+__all__ = ['EventEmitter', 'PyeeException']
+
+
+class PyeeException(Exception):
+    """An exception internal to pyee."""
+    pass
+
+
+class EventEmitter(object):
+    """The EventEmitter class.
+
+    For interoperation with asyncio, one can specify the scheduler and
+    the event loop. The scheduler defaults to ``asyncio.ensure_future``,
+    and the loop defaults to ``None``. When used with the default scheduler,
+    this will schedule the coroutine onto asyncio's default loop.
+
+    This should also be compatible with recent versions of twisted by
+    setting ``scheduler=twisted.internet.defer.ensureDeferred``.
+
+    Most events are registered with EventEmitter via the ``on`` and ``once``
+    methods. However, pyee EventEmitters have two *special* events:
+
+    - ``new_listener``: Fires whenever a new listener is created. Listeners for
+      this event do not fire upon their own creation.
+
+    - ``error``: When emitted raises an Exception by default, behavior can be
+      overriden by attaching callback to the event.
+
+      For example::
+
+          @ee.on('error')
+          def onError(message):
+              logging.err(message)
+
+          ee.emit('error', Exception('something blew up'))
+
+      For synchronous callbacks, exceptions are **not** handled for you---
+      you must catch your own exceptions inside synchronous ``on`` handlers.
+      However, when wrapping **async** functions, errors will be intercepted
+      and emitted under the ``error`` event. **This behavior for async
+      functions is inconsistent with node.js**, which unlike this package has
+      no facilities for handling returned Promises from handlers.
+    """
+    def __init__(self, scheduler=ensure_future, loop=None):
+        self._events = defaultdict(list)
+        self._schedule = scheduler
+        self._loop = loop
+
+    def on(self, event, f=None):
+        """Registers the function (or optionally an asyncio coroutine function)
+        ``f`` to the event name ``event``.
+
+        If ``f`` isn't provided, this method returns a function that
+        takes ``f`` as a callback; in other words, you can use this method
+        as a decorator, like so::
+
+            @ee.on('data')
+            def data_handler(data):
+                print(data)
+
+        As mentioned, this method can also take an asyncio coroutine function::
+
+           @ee.on('data')
+           async def data_handler(data)
+               await do_async_thing(data)
+
+
+        This will automatically schedule the coroutine using the configured
+        scheduling function (defaults to ``asyncio.ensure_future``) and the
+        configured event loop (defaults to ``asyncio.get_event_loop()``).
+        """
+
+        def _on(f):
+            # Fire 'new_listener' *before* adding the new listener!
+            self.emit('new_listener', event, f)
+
+            # Add the necessary function
+            self._events[event].append(f)
+
+            # Return original function so removal works
+            return f
+
+        if f is None:
+            return _on
+        else:
+            return _on(f)
+
+    def emit(self, event, *args, **kwargs):
+        """Emit ``event``, passing ``*args`` and ``**kwargs`` to each attached
+        function. Returns ``True`` if any functions are attached to ``event``;
+        otherwise returns ``False``.
+
+        Example::
+
+            ee.emit('data', '00101001')
+
+        Assuming ``data`` is an attached function, this will call
+        ``data('00101001')'``.
+
+        For coroutine event handlers, calling emit is non-blocking. In other
+        words, you do not have to await any results from emit, and the
+        coroutine is scheduled in a fire-and-forget fashion.
+        """
+        handled = False
+
+        # Copy the events dict first. Avoids a bug if the events dict gets
+        # changed in the middle of the following for loop.
+        events_copy = list(self._events[event])
+
+        # Pass the args to each function in the events dict
+        for f in events_copy:
+            result = f(*args, **kwargs)
+            if iscoroutine and iscoroutine(result):
+                if self._loop:
+                    d = self._schedule(result, loop=self._loop)
+                else:
+                    d = self._schedule(result)
+                if hasattr(d, 'add_done_callback'):
+                    @d.add_done_callback
+                    def _callback(f):
+                        exc = f.exception()
+                        if exc:
+                            self.emit('error', exc)
+                elif hasattr(d, 'addErrback'):
+                    @d.addErrback
+                    def _callback(exc):
+                        self.emit('error', exc)
+            handled = True
+
+        if not handled and event == 'error':
+            if len(args):
+                raise args[0]
+            else:
+                raise PyeeException("Uncaught, unspecified 'error' event.")
+
+        return handled
+
+    def once(self, event, f=None):
+        """The same as ``ee.on``, except that the listener is automatically
+        removed after being called.
+        """
+        def _once(f):
+            def g(*args, **kwargs):
+                f(*args, **kwargs)
+                self.remove_listener(event, g)
+            return g
+
+        def _wrapper(f):
+            self.on(event, _once(f))
+            return f
+
+        if f is None:
+            return _wrapper
+        else:
+            _wrapper(f)
+
+    def remove_listener(self, event, f):
+        """Removes the function ``f`` from ``event``."""
+        self._events[event].remove(f)
+
+    def remove_all_listeners(self, event=None):
+        """Remove all listeners attached to ``event``.
+        If ``event`` is ``None``, remove all listeners on all events.
+        """
+        if event is not None:
+            self._events[event] = []
+        else:
+            self._events = None
+            self._events = defaultdict(list)
+
+    def listeners(self, event):
+        """Returns the list of all listeners registered to the ``event``.
+        """
+        return self._events[event]
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 0000000..e4eba0b
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,7 @@
+[aliases]
+test = pytest
+
+[egg_info]
+tag_build = 
+tag_date = 0
+
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..a2a0827
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+
+from os import path
+from setuptools import find_packages, setup
+
+README_rst = path.join(path.abspath(path.dirname(__file__)), 'README.rst')
+
+with open(README_rst, 'r') as f:
+    long_description = f.read()
+
+setup(
+    name="pyee",
+    vcversioner={},
+
+    packages=find_packages(),
+    setup_requires=['pytest-runner', 'vcversioner'],
+    tests_require=['twisted'],
+    include_package_data=True,
+
+    description="A port of node.js's EventEmitter to python.",
+    long_description=long_description,
+    author="Joshua Holbrook",
+    author_email="josh.holbrook at gmail.com",
+    url="https://github.com/jfhbrook/pyee",
+    keywords=[
+        "events", "emitter", "node.js", "node", "eventemitter",
+        "event_emitter"
+    ],
+    classifiers=[
+        "Programming Language :: Python",
+        "Development Status :: 4 - Beta",
+        "Intended Audience :: Developers",
+        "License :: OSI Approved :: MIT License",
+        "Operating System :: OS Independent",
+        "Programming Language :: Python",
+        "Programming Language :: Python :: 2",
+        "Programming Language :: Python :: 2.7",
+        "Programming Language :: Python :: 3",
+        "Programming Language :: Python :: 3.5",
+        "Topic :: Other/Nonlisted Topic"
+    ]
+)
diff --git a/tests/conftest.py b/tests/conftest.py
new file mode 100644
index 0000000..325beb3
--- /dev/null
+++ b/tests/conftest.py
@@ -0,0 +1,8 @@
+# -*- coding: utf-8 -*-
+
+from sys import version_info as v
+
+collect_ignore = []
+
+if not (v[0] >= 3 and v[1] >= 5):
+    collect_ignore.append('test_async.py')
diff --git a/tests/test_async.py b/tests/test_async.py
new file mode 100644
index 0000000..b4fee1d
--- /dev/null
+++ b/tests/test_async.py
@@ -0,0 +1,115 @@
+# -*- coding: utf-8 -*-
+
+from asyncio import Future, gather, new_event_loop, sleep
+from mock import Mock
+from twisted.internet.defer import ensureDeferred
+
+from pyee import EventEmitter
+
+class PyeeTestError(Exception):
+    pass
+
+def test_asyncio_emit():
+    """Test that event_emitters can handle wrapping coroutines as used with
+    asyncio.
+    """
+    loop = new_event_loop()
+    ee = EventEmitter(loop=loop)
+
+    should_call = Future(loop=loop)
+
+    @ee.on('event')
+    async def event_handler():
+        should_call.set_result(True)
+
+    async def create_timeout(loop=loop):
+        await sleep(0.1, loop=loop)
+        if not should_call.done():
+            raise Exception('should_call timed out!')
+            return should_call.cancel()
+
+    timeout = create_timeout(loop=loop)
+
+    @should_call.add_done_callback
+    def _done(result):
+        assert result
+
+    ee.emit('event')
+
+    loop.run_until_complete(gather(should_call, timeout, loop=loop))
+
+    loop.close()
+
+
+def test_asyncio_error():
+    """Test that event_emitters can handle errors when wrapping coroutines as
+    used with asyncio.
+    """
+    loop = new_event_loop()
+    ee = EventEmitter(loop=loop)
+
+    should_call = Future(loop=loop)
+
+    @ee.on('event')
+    async def event_handler():
+        raise PyeeTestError()
+
+    @ee.on('error')
+    def handle_error(exc):
+        should_call.set_result(exc)
+
+    async def create_timeout(loop=loop):
+        await sleep(0.1, loop=loop)
+        if not should_call.done():
+            raise Exception('should_call timed out!')
+            return should_call.cancel()
+
+    timeout = create_timeout(loop=loop)
+
+    @should_call.add_done_callback
+    def _done(result):
+        assert isinstance(result, PyeeTestError)
+
+    ee.emit('event')
+
+    loop.run_until_complete(gather(should_call, timeout, loop=loop))
+
+    loop.close()
+
+
+def test_twisted_emit():
+    """Test that event_emitters can handle wrapping coroutines when using
+    twisted and ensureDeferred.
+    """
+    ee = EventEmitter(scheduler=ensureDeferred)
+
+    should_call = Mock()
+
+    @ee.on('event')
+    async def event_handler():
+        should_call(True)
+
+    ee.emit('event')
+
+    should_call.assert_called_once()
+
+
+def test_twisted_error():
+    """Test that event_emitters can handle wrapping coroutines when using
+    twisted and ensureDeferred.
+    """
+    ee = EventEmitter(scheduler=ensureDeferred)
+
+    should_call = Mock()
+
+    @ee.on('event')
+    async def event_handler():
+        raise PyeeTestError()
+
+    @ee.on('error')
+    def handle_error(e):
+        should_call(e)
+
+    ee.emit('event')
+
+    should_call.assert_called_once()
diff --git a/tests/test_sync.py b/tests/test_sync.py
new file mode 100644
index 0000000..d685a2f
--- /dev/null
+++ b/tests/test_sync.py
@@ -0,0 +1,261 @@
+# -*- coding: utf-8 -*-
+
+from inspect import getmro
+
+from mock import Mock
+from pytest import raises
+
+from pyee import EventEmitter
+
+class PyeeTestException(Exception):
+    pass
+
+def test_emit_sync():
+    """Basic synchronous emission works"""
+
+    call_me = Mock()
+    ee = EventEmitter()
+
+    @ee.on('event')
+    def event_handler(data, **kwargs):
+        call_me()
+        assert data == 'emitter is emitted!'
+
+    # Making sure data is passed propers
+    ee.emit('event', 'emitter is emitted!', error=False)
+
+    call_me.assert_called_once()
+
+
+def test_emit_error():
+    """Errors raise with no event handler, otherwise emit on handler"""
+
+    call_me = Mock()
+    ee = EventEmitter()
+
+    test_exception = PyeeTestException('lololol')
+
+    with raises(PyeeTestException) as exc_info:
+        ee.emit('error', test_exception)
+
+    @ee.on('error')
+    def on_error(exc):
+        call_me()
+
+    # No longer raises and error instead return True indicating handled
+    assert ee.emit('error', test_exception)
+    call_me.assert_called_once()
+
+
+def test_emit_return():
+    """Emit returns True when handlers are registered on an event, and false
+    otherwise.
+    """
+
+    call_me = Mock()
+    ee = EventEmitter()
+
+    # make sure emitting without a callback returns False
+    assert not ee.emit('data')
+
+    # add a callback
+    ee.on('data')(call_me)
+
+    # should return True now
+    assert ee.emit('data')
+
+
+def test_new_listener_event():
+    """The 'new_listener' event fires whenever a new listerner is added."""
+
+    call_me = Mock()
+    ee = EventEmitter()
+
+    ee.on('new_listener', call_me)
+
+    # Should fire new_listener event
+    @ee.on('event')
+    def event_handler(data):
+        pass
+
+    call_me.assert_called_once()
+
+
+def test_listener_removal():
+    """Removing listeners removes the correct listener from an event."""
+
+    ee = EventEmitter()
+
+    # Some functions to pass to the EE
+    def first():
+        return 1
+
+    ee.on('event', first)
+
+    @ee.on('event')
+    def second():
+        return 2
+
+    @ee.on('event')
+    def third():
+        return 3
+
+    def fourth():
+        return 4
+
+    ee.on('event', fourth)
+
+    assert ee._events['event'] == [first, second, third, fourth]
+
+    ee.remove_listener('event', second)
+
+    assert ee._events['event'] == [first, third, fourth]
+
+    ee.remove_listener('event', first)
+    assert ee._events['event'] == [third, fourth]
+
+    ee.remove_all_listeners('event')
+    assert ee._events['event'] == []
+
+
+def test_listener_removal_on_emit():
+    """Test that a listener removed during an emit is called inside the current
+    emit cycle.
+    """
+
+    call_me = Mock()
+    ee = EventEmitter()
+
+    def should_remove():
+        ee.remove_listener('remove', call_me)
+
+    ee.on('remove', should_remove)
+    ee.on('remove', call_me)
+
+    ee.emit('remove')
+
+    call_me.assert_called_once()
+
+    call_me.reset_mock()
+
+    # Also test with the listeners added in the opposite order
+    ee = EventEmitter()
+    ee.on('remove', call_me)
+    ee.on('remove', should_remove)
+
+    ee.emit('remove')
+
+    call_me.assert_called_once()
+
+
+def test_once():
+    """Test that `once()` method works propers.
+    """
+
+    # very similar to "test_emit" but also makes sure that the event
+    # gets removed afterwards
+
+    call_me = Mock()
+    ee = EventEmitter()
+
+    def once_handler(data):
+        assert data == 'emitter is emitted!'
+        call_me()
+
+    # Tests to make sure that after event is emitted that it's gone.
+    callback_fn = ee.once('event', once_handler)
+
+    # assert ee._events['event'] == [callback_fn]
+
+    ee.emit('event', 'emitter is emitted!')
+
+    call_me.assert_called_once()
+
+    assert ee._events['event'] == []
+
+
+def test_listeners():
+    """`listeners()` gives you access to the listeners array."""
+
+    call_me = Mock()
+    ee = EventEmitter()
+
+    @ee.on('event')
+    def event_handler():
+        pass
+
+    listeners = ee.listeners('event')
+
+    assert listeners[0] == event_handler
+
+    # Overwrite listener
+    listeners[0] = call_me
+
+    ee.emit('event')
+
+    call_me.assert_called_once()
+
+
+def test_properties_preserved():
+    """Test that the properties of decorated functions are preserved."""
+
+    call_me = Mock()
+    call_me_also = Mock()
+    ee = EventEmitter()
+
+    @ee.on('always')
+    def always_event_handler():
+        """An event handler."""
+        call_me()
+
+    @ee.once('once')
+    def once_event_handler():
+        """Another event handler."""
+        call_me_also()
+
+    assert always_event_handler.__doc__ == 'An event handler.'
+    assert once_event_handler.__doc__ == 'Another event handler.'
+
+    always_event_handler()
+    call_me.assert_called_once()
+
+    once_event_handler()
+    call_me_also.assert_called_once()
+
+    call_me_also.reset_mock()
+
+    # Calling the event handler directly doesn't clear the handler
+    ee.emit('once')
+    call_me_also.assert_called_once()
+
+
+def test_inheritance():
+    """Test that inheritance is preserved from object"""
+    assert object in getmro(EventEmitter)
+
+    class example(EventEmitter):
+        def __init__(self):
+            super(example, self).__init__()
+
+    assert EventEmitter in getmro(example)
+    assert object in getmro(example)
+
+def test_multiple_inheritance():
+    """Test that inheritance is preserved along a lengthy MRO"""
+    class example(EventEmitter):
+        def __init__(self):
+            super(example, self).__init__()
+
+    class _example(example):
+        def __init__(self):
+            super(_example, self).__init__()
+
+    class example2(_example):
+        def __init__(self):
+            super(example2, self).__init__()
+
+    class _example2(_example):
+        def __init__(self):
+            super(_example2, self).__init__()
+
+    a = _example2()
diff --git a/version.txt b/version.txt
new file mode 100644
index 0000000..5c8973f
--- /dev/null
+++ b/version.txt
@@ -0,0 +1 @@
+3.0.3-0-gb719423
\ No newline at end of file

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/pyee.git



More information about the Python-modules-commits mailing list