Hello community,

here is the log from the commit of package python-pyee for openSUSE:Factory 
checked in at 2019-04-26 22:54:29
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pyee (Old)
 and      /work/SRC/openSUSE:Factory/.python-pyee.new.5536 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-pyee"

Fri Apr 26 22:54:29 2019 rev:5 rq:697804 version:6.0.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pyee/python-pyee.changes  2018-12-24 
11:41:51.709427130 +0100
+++ /work/SRC/openSUSE:Factory/.python-pyee.new.5536/python-pyee.changes        
2019-04-26 22:54:30.813312683 +0200
@@ -1,0 +2,13 @@
+Thu Apr 25 07:50:21 UTC 2019 - [email protected]
+
+- version update to 6.0.0
+  * Added a ``BaseEventEmitter`` class which is entirely synchronous and
+    intended for simple use and for subclassing
+  * Added an ``AsyncIOEventEmitter`` class for intended use with asyncio
+  * Added a ``TwistedEventEmitter`` class for intended use with twisted
+  * Added an ``ExecutorEventEmitter`` class which runs events in an executor
+  * Deprecated ``EventEmitter`` (use one of the new classes)
+- modified patches
+  % fix-build-requirements.patch (refreshed)
+
+-------------------------------------------------------------------

Old:
----
  pyee-5.0.0.tar.gz

New:
----
  pyee-6.0.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-pyee.spec ++++++
--- /var/tmp/diff_new_pack.NNMqdu/_old  2019-04-26 22:54:31.573312193 +0200
+++ /var/tmp/diff_new_pack.NNMqdu/_new  2019-04-26 22:54:31.573312193 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-pyee
 #
-# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -19,7 +19,7 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %bcond_without test
 Name:           python-pyee
-Version:        5.0.0
+Version:        6.0.0
 Release:        0
 Summary:        A port of node.js's EventEmitter to python
 License:        MIT
@@ -52,6 +52,7 @@
 %prep
 %setup -q -n pyee-%{version}
 %patch0 -p1
+# https://github.com/jfhbrook/pyee/issues/58
 cp %{SOURCE99} .
 
 %build

++++++ fix-build-requirements.patch ++++++
--- /var/tmp/diff_new_pack.NNMqdu/_old  2019-04-26 22:54:31.601312176 +0200
+++ /var/tmp/diff_new_pack.NNMqdu/_new  2019-04-26 22:54:31.609312171 +0200
@@ -5,24 +5,24 @@
 it was only used for tests. Fix it so we can build for all python flavors
 and run tests only for python3 (where pytest-asyncio is available).
 
-Index: pyee-5.0.0/setup.py
+Index: pyee-6.0.0/setup.py
 ===================================================================
---- pyee-5.0.0.orig/setup.py
-+++ pyee-5.0.0/setup.py
-@@ -14,11 +14,13 @@ setup(
+--- pyee-6.0.0.orig/setup.py   2019-04-13 19:47:29.000000000 +0200
++++ pyee-6.0.0/setup.py        2019-04-25 09:47:13.860816108 +0200
+@@ -14,11 +14,14 @@ setup(
  
      packages=find_packages(),
      setup_requires=[
-+        'vcversioner',
++        'vcversioner'
 +    ],
 +    tests_require=[
 +        'twisted',
++        'futures; python_version < "3.0"',
          'pytest-runner',
          'pytest-asyncio; python_version > "3.4"',
 -        'vcversioner'
--    ],
--    tests_require=['twisted'],
-+        ],
+     ],
+-    tests_require=['twisted', 'futures; python_version < "3.0"'],
      include_package_data=True,
  
      description="A port of node.js's EventEmitter to python.",

++++++ pyee-5.0.0.tar.gz -> pyee-6.0.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyee-5.0.0/CHANGELOG.rst new/pyee-6.0.0/CHANGELOG.rst
--- old/pyee-5.0.0/CHANGELOG.rst        2017-11-18 23:44:14.000000000 +0100
+++ new/pyee-6.0.0/CHANGELOG.rst        2019-04-13 19:47:29.000000000 +0200
@@ -1,3 +1,13 @@
+2019/04/11 Version 6.0.0
+-----------------------
+- Added a ``BaseEventEmitter`` class which is entirely synchronous and
+  intended for simple use and for subclassing
+- Added an ``AsyncIOEventEmitter`` class for intended use with asyncio
+- Added a ``TwistedEventEmitter`` class for intended use with twisted
+- Added an ``ExecutorEventEmitter`` class which runs events in an executor
+- Deprecated ``EventEmitter`` (use one of the new classes)
+
+
 2017/11/18 Version 5.0.0
 ------------------------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyee-5.0.0/DEVELOPMENT.rst 
new/pyee-6.0.0/DEVELOPMENT.rst
--- old/pyee-5.0.0/DEVELOPMENT.rst      2017-11-18 23:19:26.000000000 +0100
+++ new/pyee-6.0.0/DEVELOPMENT.rst      2019-04-13 19:50:11.000000000 +0200
@@ -1,13 +1,17 @@
 Development And Publishing:
 ------------
 
-- Given you're in a virtualenv or conda environment, you can install this
-  project's dependencies with ``make setup``.
-- You can link this project to your global space with
+- Set up either a virtualenv or a conda env
+  - if using a virtualenv, `pip install -r requirements_dev.txt` will install
+    development dependencies
+  - if using conda, `conda env create` in this directory will create the
+    environment and `conda env update` will update.
+- You can link this project to your current environment with
   ``python setup.py develop``.
 - Tests can be ran with ``make test``.
-- Documentation can be generated locally with ``make the_docs``.
-- Version off by ``git tag -a {version} -m 'Version {version}'``. No prefixed
+- Documentation can be generated locally with ``make build_docs`` and served
+  with ``make serve_docs``.
+- Version off by ``git tag -a {version} -m 'Release {version}'``. No prefixed
   v. Make sure you do a commit with the updated CHANGELOG as well.
 - Publish with ``make package`` followed by ``make upload``.
 - RTD should build automatically but can be kicked off manually by logging in.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyee-5.0.0/PKG-INFO new/pyee-6.0.0/PKG-INFO
--- old/pyee-5.0.0/PKG-INFO     2017-11-18 23:44:51.000000000 +0100
+++ new/pyee-6.0.0/PKG-INFO     2019-04-13 19:50:13.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: pyee
-Version: 5.0.0
+Version: 6.0.0
 Summary: A port of node.js's EventEmitter to python.
 Home-page: https://github.com/jfhbrook/pyee
 Author: Joshua Holbrook
@@ -14,8 +14,10 @@
         .. 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.
+        pyee supplies a ``BaseEventEmitter`` object that is similar to the
+        ``EventEmitter`` class from Node.js. It also supplies a number of 
subclasses
+        with added support for async and threaded programming in python, such 
as
+        async/await as seen in python 3.5+.
         
         Docs:
         -----
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyee-5.0.0/README.rst new/pyee-6.0.0/README.rst
--- old/pyee-5.0.0/README.rst   2017-11-18 23:22:07.000000000 +0100
+++ new/pyee-6.0.0/README.rst   2019-04-13 19:47:29.000000000 +0200
@@ -6,8 +6,10 @@
 .. 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.
+pyee supplies a ``BaseEventEmitter`` object that is similar to the
+``EventEmitter`` class from Node.js. It also supplies a number of subclasses
+with added support for async and threaded programming in python, such as
+async/await as seen in python 3.5+.
 
 Docs:
 -----
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyee-5.0.0/pyee/__init__.py 
new/pyee-6.0.0/pyee/__init__.py
--- old/pyee-5.0.0/pyee/__init__.py     2017-11-18 23:19:26.000000000 +0100
+++ new/pyee-6.0.0/pyee/__init__.py     2019-04-13 19:47:29.000000000 +0200
@@ -1,8 +1,11 @@
 # -*- coding: utf-8 -*-
 
 """
-pyee supplies an ``EventEmitter`` object similar to the ``EventEmitter``
-from Node.js. It supports both synchronous callbacks and asyncio coroutines.
+pyee supplies a ``BaseEventEmitter`` class that is similar to the
+``EventEmitter`` class from Node.js. In addition, it supplies the subclasses
+``AsyncIOEventEmitter``, ``TwistedEventEmitter`` and ``ExecutorEventEmitter``
+for supporting async and threaded execution with asyncio, twisted, and
+concurrent.futures Executors respectively, as supported by the environment.
 
 
 Example
@@ -10,9 +13,9 @@
 
 ::
 
-    In [1]: from pyee import EventEmitter
+    In [1]: from pyee import BaseEventEmitter
 
-    In [2]: ee = EventEmitter()
+    In [2]: ee = BaseEventEmitter()
 
     In [3]: @ee.on('event')
        ...: def event_handler():
@@ -26,194 +29,29 @@
 
 """
 
-try:
-    from asyncio import iscoroutine, ensure_future
-except ImportError:
-    iscoroutine = None
-    ensure_future = None
-
-from collections import defaultdict, OrderedDict
+from pyee._base import (
+    BaseEventEmitter,
+    PyeeException
+)
 
-__all__ = ['EventEmitter', 'PyeeException']
+from pyee._compat import CompatEventEmitter as EventEmitter
 
+__all__ = ['BaseEventEmitter', 'EventEmitter', 'PyeeException']
 
-class PyeeException(Exception):
-    """An exception internal to pyee."""
+try:
+    from pyee._asyncio import AsyncIOEventEmitter  # noqa
+    __all__.append('AsyncIOEventEmitter')
+except ImportError:
     pass
 
+try:
+    from pyee._twisted import TwistedEventEmitter  # noqa
+    __all__.append('TwistedEventEmitter')
+except ImportError:
+    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(OrderedDict)
-        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()``).
-
-        In both the decorated and undecorated forms, the event handler is
-        returned. The upshot of this is that you can call decorated handlers
-        directly, as well as use them in remove_listener calls.
-        """
-
-        def _on(f):
-            self._add_event_handler(event, f, f)
-            return f
-
-        if f is None:
-            return _on
-        else:
-            return _on(f)
-
-    def _add_event_handler(self, event, k, v):
-        # Fire 'new_listener' *before* adding the new listener!
-        self.emit('new_listener', event, k)
-
-        # Add the necessary function
-        # Note that k and v are the same for `on` handlers, but
-        # different for `once` handlers, where v is a wrapped version
-        # of k which removes itself before calling k
-        self._events[event][k] = v
-
-    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
-
-        for f in list(self._events[event].values()):
-            result = f(*args, **kwargs)
-
-            # If f was a coroutine function, we need to schedule it and
-            # handle potential errors
-            if iscoroutine and iscoroutine(result):
-                if self._loop:
-                    d = self._schedule(result, loop=self._loop)
-                else:
-                    d = self._schedule(result)
-
-                # scheduler gave us an asyncio Future
-                if hasattr(d, 'add_done_callback'):
-                    @d.add_done_callback
-                    def _callback(f):
-                        exc = f.exception()
-                        if exc:
-                            self.emit('error', exc)
-
-                # scheduler gave us a twisted Deferred
-                elif hasattr(d, 'addErrback'):
-                    @d.addErrback
-                    def _callback(exc):
-                        self.emit('error', exc)
-            handled = True
-
-        if not handled and event == 'error':
-            if 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 _wrapper(f):
-            def g(*args, **kwargs):
-                self.remove_listener(event, f)
-                # f may return a coroutine, so we need to return that
-                # result here so that emit can schedule it
-                return f(*args, **kwargs)
-
-            self._add_event_handler(event, f, g)
-            return f
-
-        if f is None:
-            return _wrapper
-        else:
-            return _wrapper(f)
-
-    def remove_listener(self, event, f):
-        """Removes the function ``f`` from ``event``."""
-        self._events[event].pop(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] = OrderedDict()
-        else:
-            self._events = defaultdict(OrderedDict)
-
-    def listeners(self, event):
-        """Returns a list of all listeners registered to the ``event``.
-        """
-        return list(self._events[event].keys())
+try:
+    from pyee._executor import ExecutorEventEmitter  # noqa
+    __all__.append('ExecutorEventEmitter')
+except ImportError:
+    pass
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyee-5.0.0/pyee/_asyncio.py 
new/pyee-6.0.0/pyee/_asyncio.py
--- old/pyee-5.0.0/pyee/_asyncio.py     1970-01-01 01:00:00.000000000 +0100
+++ new/pyee-6.0.0/pyee/_asyncio.py     2019-04-13 19:47:29.000000000 +0200
@@ -0,0 +1,59 @@
+# -*- coding: utf-8 -*-
+
+from asyncio import ensure_future, Future, iscoroutine
+from pyee._base import BaseEventEmitter
+
+__all__ = ['AsyncIOEventEmitter']
+
+
+class AsyncIOEventEmitter(BaseEventEmitter):
+    """An event emitter class which can run asyncio coroutines in addition to
+    synchronous blocking functions. For example::
+
+        @ee.on('event')
+        async def async_handler(*args, **kwargs):
+            await returns_a_future()
+
+    On emit, the event emitter  will automatically schedule the coroutine using
+    ``asyncio.ensure_future`` and the configured event loop (defaults to
+    ``asyncio.get_event_loop()``).
+
+    Unlike the case with the BaseEventEmitter, all exceptions raised by
+    event handlers are automatically emitted on the ``error`` event. This is
+    important for asyncio coroutines specifically but is also handled for
+    synchronous functions for consistency.
+
+    When ``loop`` is specified, the supplied event loop will be used when
+    scheduling work with ``ensure_future``. Otherwise, the default asyncio
+    event loop is used.
+
+    For asyncio 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.
+    """
+    def __init__(self, loop=None):
+        super(AsyncIOEventEmitter, self).__init__()
+        self._loop = loop
+
+    def _emit_run(self, f, args, kwargs):
+        try:
+            coro = f(*args, **kwargs)
+        except Exception as exc:
+            self.emit('error', exc)
+        else:
+            if iscoroutine(coro):
+                if self._loop:
+                    f = ensure_future(coro, loop=self._loop)
+                else:
+                    f = ensure_future(coro)
+            elif isinstance(coro, Future):
+                f = coro
+            else:
+                f = None
+
+            if f:
+                @f.add_done_callback
+                def _callback(f):
+                    exc = f.exception()
+                    if exc:
+                        self.emit('error', exc)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyee-5.0.0/pyee/_base.py new/pyee-6.0.0/pyee/_base.py
--- old/pyee-5.0.0/pyee/_base.py        1970-01-01 01:00:00.000000000 +0100
+++ new/pyee-6.0.0/pyee/_base.py        2019-04-13 19:47:29.000000000 +0200
@@ -0,0 +1,145 @@
+# -*- coding: utf-8 -*-
+
+from collections import defaultdict, OrderedDict
+
+__all__ = ['BaseEventEmitter', 'PyeeException']
+
+
+class PyeeException(Exception):
+    """An exception internal to pyee."""
+    pass
+
+
+class BaseEventEmitter(object):
+    """The base event emitter class. All other event emitters inherit from
+    this class.
+
+    Most events are registered with an emitter via the ``on`` and ``once``
+    methods, and fired with the ``emit`` method. However, pyee event emitters
+    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 on_error(message):
+              logging.err(message)
+
+          ee.emit('error', Exception('something blew up'))
+
+    All callbacks are handled in a synchronous, blocking manner. As in node.js,
+    raised exceptions are not automatically handled for you---you must catch
+    your own exceptions, and treat them accordingly.
+    """
+    def __init__(self):
+        self._events = defaultdict(OrderedDict)
+
+    def on(self, event, f=None):
+        """Registers the 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)
+
+        In both the decorated and undecorated forms, the event handler is
+        returned. The upshot of this is that you can call decorated handlers
+        directly, as well as use them in remove_listener calls.
+        """
+
+        def _on(f):
+            self._add_event_handler(event, f, f)
+            return f
+
+        if f is None:
+            return _on
+        else:
+            return _on(f)
+
+    def _add_event_handler(self, event, k, v):
+        # Fire 'new_listener' *before* adding the new listener!
+        self.emit('new_listener', event, k)
+
+        # Add the necessary function
+        # Note that k and v are the same for `on` handlers, but
+        # different for `once` handlers, where v is a wrapped version
+        # of k which removes itself before calling k
+        self._events[event][k] = v
+
+    def _emit_run(self, f, args, kwargs):
+        f(*args, **kwargs)
+
+    def _emit_handle_potential_error(self, event, error):
+        if event == 'error':
+            if error:
+                raise error
+            else:
+                raise PyeeException("Uncaught, unspecified 'error' event.")
+
+    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')'``.
+        """
+        handled = False
+
+        for f in list(self._events[event].values()):
+            self._emit_run(f, args, kwargs)
+            handled = True
+
+        if not handled:
+            self._emit_handle_potential_error(event, args[0] if args else None)
+
+        return handled
+
+    def once(self, event, f=None):
+        """The same as ``ee.on``, except that the listener is automatically
+        removed after being called.
+        """
+        def _wrapper(f):
+            def g(*args, **kwargs):
+                self.remove_listener(event, f)
+                # f may return a coroutine, so we need to return that
+                # result here so that emit can schedule it
+                return f(*args, **kwargs)
+
+            self._add_event_handler(event, f, g)
+            return f
+
+        if f is None:
+            return _wrapper
+        else:
+            return _wrapper(f)
+
+    def remove_listener(self, event, f):
+        """Removes the function ``f`` from ``event``."""
+        self._events[event].pop(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] = OrderedDict()
+        else:
+            self._events = defaultdict(OrderedDict)
+
+    def listeners(self, event):
+        """Returns a list of all listeners registered to the ``event``.
+        """
+        return list(self._events[event].keys())
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyee-5.0.0/pyee/_compat.py 
new/pyee-6.0.0/pyee/_compat.py
--- old/pyee-5.0.0/pyee/_compat.py      1970-01-01 01:00:00.000000000 +0100
+++ new/pyee-6.0.0/pyee/_compat.py      2019-04-13 19:47:29.000000000 +0200
@@ -0,0 +1,68 @@
+from pyee._base import BaseEventEmitter
+from warnings import warn
+
+try:
+    from asyncio import iscoroutine, ensure_future
+except ImportError:
+    iscoroutine = None
+    ensure_future = None
+
+
+class CompatEventEmitter(BaseEventEmitter):
+    """An EventEmitter exposed for compatibility with prior versions of
+    pyee. This functionality is deprecated; you should instead use either
+    ``AsyncIOEventEmitter``, ``TwistedEventEmitter``, ``ExecutorEventEmitter``,
+    or ``BaseEventEmitter``.
+
+    This class is similar to the ``AsyncIOEventEmitter`` class, but also allows
+    for overriding the scheduler function (``ensure_future`` by default as in
+    ``ASyncIOEventEmitter``) and does duck typing checks to handle Deferreds.
+    In other words, by setting ``scheduler`` to
+    ``twisted.internet.defer.ensureDeferred`` this will support twisted use
+    cases for coroutines.
+
+    When calling synchronous handlers, raised exceptions are ignored - as with
+    the BaseEventEmitter, you must capture and handle your own exceptions.
+    However, for coroutine functions, exceptions are handled by emitting them
+    on the ``error`` event.  Note that when using with twisted, the ``error``
+    event will emit Failures, not Exceptions.
+
+    This class will also successfully import in python 2, but without coroutine
+    support.
+    """
+
+    def __init__(self, scheduler=ensure_future, loop=None):
+        warn(DeprecationWarning(
+            'pyee.EventEmitter is deprecated and will be removed in a future '
+            'major version; you should instead use either '
+            'pyee.AsyncIOEventEmitter, pyee.TwistedEventEmitter, '
+            'pyee.ExecutorEventEmitter or pyee.BaseEventEmitter.'
+        ))
+
+        super(CompatEventEmitter, self).__init__()
+
+        self._schedule = scheduler
+        self._loop = loop
+
+    def _emit_run(self, f, args, kwargs):
+        coro = f(*args, **kwargs)
+
+        if iscoroutine and iscoroutine(coro):
+            if self._loop:
+                d = self._schedule(coro, loop=self._loop)
+            else:
+                d = self._schedule(coro)
+
+            # scheduler gave us an asyncio Future
+            if hasattr(d, 'add_done_callback'):
+                @d.add_done_callback
+                def _callback(f):
+                    exc = f.exception()
+                    if exc:
+                        self.emit('error', exc)
+
+            # scheduler gave us a twisted Deferred
+            elif hasattr(d, 'addErrback'):
+                @d.addErrback
+                def _callback(exc):
+                    self.emit('error', exc)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyee-5.0.0/pyee/_executor.py 
new/pyee-6.0.0/pyee/_executor.py
--- old/pyee-5.0.0/pyee/_executor.py    1970-01-01 01:00:00.000000000 +0100
+++ new/pyee-6.0.0/pyee/_executor.py    2019-04-13 19:47:29.000000000 +0200
@@ -0,0 +1,71 @@
+# -*- coding: utf-8 -*-
+
+from pyee._base import BaseEventEmitter
+
+try:
+    from concurrent.futures import ThreadPoolExecutor
+except ImportError:
+    from futures import ThreadPoolExecutor
+
+__all__ = ['ExecutorEventEmitter']
+
+
+class ExecutorEventEmitter(BaseEventEmitter):
+    """An event emitter class which runs handlers in a ``concurrent.futures``
+    executor. If using python 2, this will fall back to trying to use the
+    ``futures`` backported library (caveats there apply).
+
+    By default, this class creates a default ``ThreadPoolExecutor``, but
+    a custom executor may also be passed in explicitly to, for instance,
+    use a ``ProcessPoolExecutor`` instead.
+
+    This class runs all emitted events on the configured executor. Errors
+    captured by the resulting Future are automatically emitted on the
+    ``error`` event. This is unlike the BaseEventEmitter, which have no error
+    handling.
+
+    The underlying executor may be shut down by calling the ``shutdown``
+    method. Alternately you can treat the event emitter as a context manager::
+
+        with ExecutorEventEmitter() as ee:
+            # Underlying executor open
+
+            @ee.on('data')
+            def handler(data):
+                print(data)
+
+            ee.emit('event')
+
+        # Underlying executor closed
+
+    Since the function call is scheduled on an executor, emit is always
+    non-blocking.
+
+    No effort is made to ensure thread safety, beyond using an executor.
+    """
+    def __init__(self, executor=None):
+        super(ExecutorEventEmitter, self).__init__()
+        if executor:
+            self._executor = executor
+        else:
+            self._executor = ThreadPoolExecutor()
+
+    def _emit_run(self, f, args, kwargs):
+        future = self._executor.submit(f, *args, **kwargs)
+
+        @future.add_done_callback
+        def _callback(f):
+            exc = f.exception()
+            if exc:
+                self.emit('error', exc)
+
+    def shutdown(self, wait=True):
+        """Call ``shutdown`` on the internal executor."""
+
+        self._executor.shutdown(wait=wait)
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, type, value, traceback):
+        self.shutdown()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyee-5.0.0/pyee/_twisted.py 
new/pyee-6.0.0/pyee/_twisted.py
--- old/pyee-5.0.0/pyee/_twisted.py     1970-01-01 01:00:00.000000000 +0100
+++ new/pyee-6.0.0/pyee/_twisted.py     2019-04-13 19:47:29.000000000 +0200
@@ -0,0 +1,75 @@
+# -*- coding: utf-8 -*-
+
+from pyee._base import BaseEventEmitter
+
+from twisted.internet.defer import Deferred, ensureDeferred
+from twisted.python.failure import Failure
+
+try:
+    from asyncio import iscoroutine
+except ImportError:
+    iscoroutine = None
+
+
+__all__ = ['TwistedEventEmitter']
+
+
+class TwistedEventEmitter(BaseEventEmitter):
+    """An event emitter class which can run twisted coroutines and handle
+    returned Deferreds, in addition to synchronous blocking functions. For
+    example::
+
+        @ee.on('event')
+        @inlineCallbacks
+        def async_handler(*args, **kwargs):
+            yield returns_a_deferred()
+
+    or::
+
+        @ee.on('event')
+        async def async_handler(*args, **kwargs):
+            await returns_a_deferred()
+
+
+    When async handlers fail, Failures are first emitted on the ``failure``
+    event. If there are no ``failure`` handlers, the Failure's associated
+    exception is then emitted on the ``error`` event. If there are no ``error``
+    handlers, the exception is raised. For consistency, when handlers raise
+    errors synchronously, they're captured, wrapped in a Failure and treated
+    as an async failure. This is unlike the behavior of BaseEventEmitter,
+    which have no special error handling.
+
+    For twisted 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.
+
+    Similar behavior occurs for "sync" functions which return Deferreds.
+    """
+    def __init__(self):
+        super(TwistedEventEmitter, self).__init__()
+
+    def _emit_run(self, f, args, kwargs):
+        try:
+            result = f(*args, **kwargs)
+        except Exception:
+            self.emit('failure', Failure())
+        else:
+            if iscoroutine and iscoroutine(result):
+                d = ensureDeferred(result)
+            elif isinstance(result, Deferred):
+                d = result
+            else:
+                d = None
+            if d:
+                @d.addErrback
+                def _errback(failure):
+                    if failure:
+                        self.emit('failure', failure)
+
+    def _emit_handle_potential_error(self, event, error):
+        if event == 'failure':
+            self.emit('error', error.value)
+        else:
+            (
+                super(TwistedEventEmitter, self)
+            )._emit_handle_potential_error(event, error)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyee-5.0.0/pyee.egg-info/PKG-INFO 
new/pyee-6.0.0/pyee.egg-info/PKG-INFO
--- old/pyee-5.0.0/pyee.egg-info/PKG-INFO       2017-11-18 23:44:51.000000000 
+0100
+++ new/pyee-6.0.0/pyee.egg-info/PKG-INFO       2019-04-13 19:50:13.000000000 
+0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: pyee
-Version: 5.0.0
+Version: 6.0.0
 Summary: A port of node.js's EventEmitter to python.
 Home-page: https://github.com/jfhbrook/pyee
 Author: Joshua Holbrook
@@ -14,8 +14,10 @@
         .. 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.
+        pyee supplies a ``BaseEventEmitter`` object that is similar to the
+        ``EventEmitter`` class from Node.js. It also supplies a number of 
subclasses
+        with added support for async and threaded programming in python, such 
as
+        async/await as seen in python 3.5+.
         
         Docs:
         -----
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyee-5.0.0/pyee.egg-info/SOURCES.txt 
new/pyee-6.0.0/pyee.egg-info/SOURCES.txt
--- old/pyee-5.0.0/pyee.egg-info/SOURCES.txt    2017-11-18 23:44:51.000000000 
+0100
+++ new/pyee-6.0.0/pyee.egg-info/SOURCES.txt    2019-04-13 19:50:13.000000000 
+0200
@@ -7,10 +7,17 @@
 setup.py
 version.txt
 pyee/__init__.py
+pyee/_asyncio.py
+pyee/_base.py
+pyee/_compat.py
+pyee/_executor.py
+pyee/_twisted.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
+tests/test_executor.py
+tests/test_sync.py
+tests/test_twisted.py
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyee-5.0.0/setup.cfg new/pyee-6.0.0/setup.cfg
--- old/pyee-5.0.0/setup.cfg    2017-11-18 23:44:51.000000000 +0100
+++ new/pyee-6.0.0/setup.cfg    2019-04-13 19:50:13.000000000 +0200
@@ -4,5 +4,4 @@
 [egg_info]
 tag_build = 
 tag_date = 0
-tag_svn_revision = 0
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyee-5.0.0/setup.py new/pyee-6.0.0/setup.py
--- old/pyee-5.0.0/setup.py     2017-11-18 01:14:03.000000000 +0100
+++ new/pyee-6.0.0/setup.py     2019-04-13 19:47:29.000000000 +0200
@@ -18,7 +18,7 @@
         'pytest-asyncio; python_version > "3.4"',
         'vcversioner'
     ],
-    tests_require=['twisted'],
+    tests_require=['twisted', 'futures; python_version < "3.0"'],
     include_package_data=True,
 
     description="A port of node.js's EventEmitter to python.",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyee-5.0.0/tests/test_async.py 
new/pyee-6.0.0/tests/test_async.py
--- old/pyee-5.0.0/tests/test_async.py  2017-11-18 01:03:16.000000000 +0100
+++ new/pyee-6.0.0/tests/test_async.py  2019-04-13 19:47:29.000000000 +0200
@@ -1,26 +1,30 @@
 # -*- coding: utf-8 -*-
 
 import pytest
-import pytest_asyncio.plugin
+import pytest_asyncio.plugin  # noqa
 
-from asyncio import Future, gather, new_event_loop, wait_for
+from asyncio import Future, wait_for
 from mock import Mock
 from twisted.internet.defer import ensureDeferred, succeed
 
-from pyee import EventEmitter
+from pyee import EventEmitter, AsyncIOEventEmitter, TwistedEventEmitter
 
 
 class PyeeTestError(Exception):
     pass
 
 
[email protected]('cls', [
+    AsyncIOEventEmitter,
+    EventEmitter
+])
 @pytest.mark.asyncio
-async def test_asyncio_emit(event_loop):
-    """Test that event_emitters can handle wrapping coroutines as used with
-    asyncio.
+async def test_asyncio_emit(cls, event_loop):
+    """Test that asyncio-supporting event emitters can handle wrapping
+    coroutines
     """
 
-    ee = EventEmitter(loop=event_loop)
+    ee = cls(loop=event_loop)
 
     should_call = Future(loop=event_loop)
 
@@ -32,15 +36,20 @@
 
     result = await wait_for(should_call, 0.1)
 
-    assert result == True
+    assert result is True
 
 
[email protected]('cls', [
+    AsyncIOEventEmitter,
+    EventEmitter
+])
 @pytest.mark.asyncio
-async def test_asyncio_once_emit(event_loop):
-    """Test that event_emitters also wrap coroutines when using once
+async def test_asyncio_once_emit(cls, event_loop):
+    """Test that asyncio-supporting event emitters also wrap coroutines when
+    using once
     """
 
-    ee = EventEmitter(loop=event_loop)
+    ee = cls(loop=event_loop)
 
     should_call = Future(loop=event_loop)
 
@@ -52,15 +61,19 @@
 
     result = await wait_for(should_call, 0.1)
 
-    assert result == True
+    assert result is True
 
 
[email protected]('cls', [
+    AsyncIOEventEmitter,
+    EventEmitter
+])
 @pytest.mark.asyncio
-async def test_asyncio_error(event_loop):
-    """Test that event_emitters can handle errors when wrapping coroutines as
-    used with asyncio.
+async def test_asyncio_error(cls, event_loop):
+    """Test that asyncio-supporting event emitters can handle errors when
+    wrapping coroutines
     """
-    ee = EventEmitter(loop=event_loop)
+    ee = cls(loop=event_loop)
 
     should_call = Future(loop=event_loop)
 
@@ -70,7 +83,6 @@
 
     @ee.on('error')
     def handle_error(exc):
-        assert isinstance(exc, PyeeTestError)
         should_call.set_result(exc)
 
     ee.emit('event')
@@ -80,11 +92,38 @@
     assert isinstance(result, PyeeTestError)
 
 
-def test_twisted_emit():
-    """Test that event_emitters can handle wrapping coroutines when using
-    twisted and ensureDeferred.
[email protected]
+async def test_sync_error(event_loop):
+    """Test that regular functions have the same error handling as coroutines
+    """
+    ee = AsyncIOEventEmitter(loop=event_loop)
+
+    should_call = Future(loop=event_loop)
+
+    @ee.on('event')
+    def sync_handler():
+        raise PyeeTestError()
+
+    @ee.on('error')
+    def handle_error(exc):
+        should_call.set_result(exc)
+
+    ee.emit('event')
+
+    result = await wait_for(should_call, 0.1)
+
+    assert isinstance(result, PyeeTestError)
+
+
[email protected]('cls,kwargs', [
+    (TwistedEventEmitter, dict()),
+    (EventEmitter, dict(scheduler=ensureDeferred))
+])
+def test_twisted_emit(cls, kwargs):
+    """Test that twisted-supporting event emitters can handle wrapping
+    coroutines
     """
-    ee = EventEmitter(scheduler=ensureDeferred)
+    ee = cls(**kwargs)
 
     should_call = Mock()
 
@@ -98,11 +137,15 @@
     should_call.assert_called_once()
 
 
-def test_twisted_once():
-    """Test that event_emitters also wrap coroutines for once when using
-    twisted and ensureDeferred.
[email protected]('cls,kwargs', [
+    (TwistedEventEmitter, dict()),
+    (EventEmitter, dict(scheduler=ensureDeferred))
+])
+def test_twisted_once(cls, kwargs):
+    """Test that twisted-supporting event emitters also wrap coroutines for
+    once
     """
-    ee = EventEmitter(scheduler=ensureDeferred)
+    ee = cls(**kwargs)
 
     should_call = Mock()
 
@@ -117,10 +160,9 @@
 
 
 def test_twisted_error():
-    """Test that event_emitters can handle wrapping coroutines when using
-    twisted and ensureDeferred.
+    """Test that TwistedEventEmitters handle Failures when wrapping coroutines.
     """
-    ee = EventEmitter(scheduler=ensureDeferred)
+    ee = TwistedEventEmitter()
 
     should_call = Mock()
 
@@ -128,7 +170,7 @@
     async def event_handler():
         raise PyeeTestError()
 
-    @ee.on('error')
+    @ee.on('failure')
     def handle_error(e):
         should_call(e)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyee-5.0.0/tests/test_executor.py 
new/pyee-6.0.0/tests/test_executor.py
--- old/pyee-5.0.0/tests/test_executor.py       1970-01-01 01:00:00.000000000 
+0100
+++ new/pyee-6.0.0/tests/test_executor.py       2019-04-13 19:47:29.000000000 
+0200
@@ -0,0 +1,63 @@
+# -*- coding: utf-8 -*-
+
+from mock import Mock
+from time import sleep
+
+from pyee import ExecutorEventEmitter
+
+
+class PyeeTestError(Exception):
+    pass
+
+
+def test_executor_emit():
+    """Test that ExecutorEventEmitters can emit events.
+    """
+    with ExecutorEventEmitter() as ee:
+        should_call = Mock()
+
+        @ee.on('event')
+        def event_handler():
+            should_call(True)
+
+        ee.emit('event')
+        sleep(0.1)
+
+        should_call.assert_called_once()
+
+
+def test_executor_once():
+    """Test that ExecutorEventEmitters also emit events for once.
+    """
+    with ExecutorEventEmitter() as ee:
+        should_call = Mock()
+
+        @ee.once('event')
+        def event_handler():
+            should_call(True)
+
+        ee.emit('event')
+        sleep(0.1)
+
+        should_call.assert_called_once()
+
+
+def test_executor_error():
+    """Test that ExecutorEventEmitters handle errors.
+    """
+    with ExecutorEventEmitter() as ee:
+        should_call = Mock()
+
+        @ee.on('event')
+        def event_handler():
+            raise PyeeTestError()
+
+        @ee.on('error')
+        def handle_error(e):
+            should_call(e)
+
+        ee.emit('event')
+
+        sleep(0.1)
+
+        should_call.assert_called_once()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyee-5.0.0/tests/test_sync.py 
new/pyee-6.0.0/tests/test_sync.py
--- old/pyee-5.0.0/tests/test_sync.py   2017-11-18 23:19:26.000000000 +0100
+++ new/pyee-6.0.0/tests/test_sync.py   2019-04-13 19:47:29.000000000 +0200
@@ -1,4 +1,5 @@
 # -*- coding: utf-8 -*-
+import pytest
 
 from inspect import getmro
 from collections import OrderedDict
@@ -6,16 +7,22 @@
 from mock import Mock
 from pytest import raises
 
-from pyee import EventEmitter
+from pyee import BaseEventEmitter, EventEmitter
+
 
 class PyeeTestException(Exception):
     pass
 
-def test_emit_sync():
+
[email protected]('cls', [
+    BaseEventEmitter,
+    EventEmitter
+])
+def test_emit_sync(cls):
     """Basic synchronous emission works"""
 
     call_me = Mock()
-    ee = EventEmitter()
+    ee = cls()
 
     @ee.on('event')
     def event_handler(data, **kwargs):
@@ -28,15 +35,19 @@
     call_me.assert_called_once()
 
 
-def test_emit_error():
[email protected]('cls', [
+    BaseEventEmitter,
+    EventEmitter
+])
+def test_emit_error(cls):
     """Errors raise with no event handler, otherwise emit on handler"""
 
     call_me = Mock()
-    ee = EventEmitter()
+    ee = cls()
 
     test_exception = PyeeTestException('lololol')
 
-    with raises(PyeeTestException) as exc_info:
+    with raises(PyeeTestException):
         ee.emit('error', test_exception)
 
     @ee.on('error')
@@ -44,7 +55,7 @@
         call_me()
 
     # No longer raises and error instead return True indicating handled
-    assert ee.emit('error', test_exception)
+    assert ee.emit('error', test_exception) is True
     call_me.assert_called_once()
 
 
@@ -54,7 +65,7 @@
     """
 
     call_me = Mock()
-    ee = EventEmitter()
+    ee = BaseEventEmitter()
 
     # make sure emitting without a callback returns False
     assert not ee.emit('data')
@@ -70,7 +81,7 @@
     """The 'new_listener' event fires whenever a new listerner is added."""
 
     call_me = Mock()
-    ee = EventEmitter()
+    ee = BaseEventEmitter()
 
     ee.on('new_listener', call_me)
 
@@ -85,7 +96,7 @@
 def test_listener_removal():
     """Removing listeners removes the correct listener from an event."""
 
-    ee = EventEmitter()
+    ee = BaseEventEmitter()
 
     # Some functions to pass to the EE
     def first():
@@ -122,7 +133,10 @@
     ])
 
     ee.remove_listener('event', first)
-    assert ee._events['event'] == OrderedDict([(third, third), (fourth, 
fourth)])
+    assert ee._events['event'] == OrderedDict([
+        (third, third),
+        (fourth, fourth)
+    ])
 
     ee.remove_all_listeners('event')
     assert ee._events['event'] == OrderedDict()
@@ -134,7 +148,7 @@
     """
 
     call_me = Mock()
-    ee = EventEmitter()
+    ee = BaseEventEmitter()
 
     def should_remove():
         ee.remove_listener('remove', call_me)
@@ -149,7 +163,7 @@
     call_me.reset_mock()
 
     # Also test with the listeners added in the opposite order
-    ee = EventEmitter()
+    ee = BaseEventEmitter()
     ee.on('remove', call_me)
     ee.on('remove', should_remove)
 
@@ -166,14 +180,14 @@
     # gets removed afterwards
 
     call_me = Mock()
-    ee = EventEmitter()
+    ee = BaseEventEmitter()
 
     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)
+    ee.once('event', once_handler)
 
     ee.emit('event', 'emitter is emitted!')
 
@@ -186,7 +200,7 @@
     """Removal of once functions works
     """
 
-    ee = EventEmitter()
+    ee = BaseEventEmitter()
 
     def once_handler(data):
         pass
@@ -204,7 +218,7 @@
     """`listeners()` returns a copied list of listeners."""
 
     call_me = Mock()
-    ee = EventEmitter()
+    ee = BaseEventEmitter()
 
     @ee.on('event')
     def event_handler():
@@ -232,7 +246,7 @@
 
     call_me = Mock()
     call_me_also = Mock()
-    ee = EventEmitter()
+    ee = BaseEventEmitter()
 
     @ee.on('always')
     def always_event_handler():
@@ -262,18 +276,19 @@
 
 def test_inheritance():
     """Test that inheritance is preserved from object"""
-    assert object in getmro(EventEmitter)
+    assert object in getmro(BaseEventEmitter)
 
-    class example(EventEmitter):
+    class example(BaseEventEmitter):
         def __init__(self):
             super(example, self).__init__()
 
-    assert EventEmitter in getmro(example)
+    assert BaseEventEmitter in getmro(example)
     assert object in getmro(example)
 
+
 def test_multiple_inheritance():
     """Test that inheritance is preserved along a lengthy MRO"""
-    class example(EventEmitter):
+    class example(BaseEventEmitter):
         def __init__(self):
             super(example, self).__init__()
 
@@ -289,4 +304,4 @@
         def __init__(self):
             super(_example2, self).__init__()
 
-    a = _example2()
+    a = _example2()  # noqa
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyee-5.0.0/tests/test_twisted.py 
new/pyee-6.0.0/tests/test_twisted.py
--- old/pyee-5.0.0/tests/test_twisted.py        1970-01-01 01:00:00.000000000 
+0100
+++ new/pyee-6.0.0/tests/test_twisted.py        2019-04-13 19:47:29.000000000 
+0200
@@ -0,0 +1,80 @@
+# -*- coding: utf-8 -*-
+
+from mock import Mock
+from twisted.internet.defer import inlineCallbacks
+from twisted.python.failure import Failure
+
+from pyee import TwistedEventEmitter
+
+
+class PyeeTestError(Exception):
+    pass
+
+
+def test_propagates_failure():
+    """Test that TwistedEventEmitters can propagate failures
+    from twisted Deferreds
+    """
+    ee = TwistedEventEmitter()
+
+    should_call = Mock()
+
+    @ee.on('event')
+    @inlineCallbacks
+    def event_handler():
+        yield Failure(PyeeTestError())
+
+    @ee.on('failure')
+    def handle_failure(f):
+        assert isinstance(f, Failure)
+        should_call(f)
+
+    ee.emit('event')
+
+    should_call.assert_called_once()
+
+
+def test_propagates_sync_failure():
+    """Test that TwistedEventEmitters can propagate failures
+    from twisted Deferreds
+    """
+    ee = TwistedEventEmitter()
+
+    should_call = Mock()
+
+    @ee.on('event')
+    def event_handler():
+        raise PyeeTestError()
+
+    @ee.on('failure')
+    def handle_failure(f):
+        assert isinstance(f, Failure)
+        should_call(f)
+
+    ee.emit('event')
+
+    should_call.assert_called_once()
+
+
+def test_propagates_exception():
+    """Test that TwistedEventEmitters propagate failures as exceptions to
+    the error event when no failure handler
+    """
+
+    ee = TwistedEventEmitter()
+
+    should_call = Mock()
+
+    @ee.on('event')
+    @inlineCallbacks
+    def event_handler():
+        yield Failure(PyeeTestError())
+
+    @ee.on('error')
+    def handle_error(exc):
+        assert isinstance(exc, Exception)
+        should_call(exc)
+
+    ee.emit('event')
+
+    should_call.assert_called_once()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyee-5.0.0/version.txt new/pyee-6.0.0/version.txt
--- old/pyee-5.0.0/version.txt  2017-11-18 23:44:51.000000000 +0100
+++ new/pyee-6.0.0/version.txt  2019-04-13 19:50:13.000000000 +0200
@@ -1 +1 @@
-5.0.0-0-ga33a635
\ No newline at end of file
+6.0.0-0-gad0107d
\ No newline at end of file


Reply via email to