Commit 94d9788f authored by Jason Madden's avatar Jason Madden

Make zope.interface/event and setuptools required dependencies.

Fixes #1619
parent 706833bf
Make ``zope.interface``, ``zope.event`` and (by extension)
``setuptools`` required dependencies. The ``events`` install extra now
does nothing and will be removed in 2021.
......@@ -117,8 +117,7 @@ fall back to doing this if no binary wheel is available. See
Extra Dependencies
==================
gevent has no runtime dependencies outside the standard library,
greenlet, and (on some platforms) `cffi`_. However, there are a number
There are a number
of additional libraries that extend gevent's functionality and will be
used if they are available. All of these may be installed using
`setuptools extras
......@@ -126,9 +125,13 @@ used if they are available. All of these may be installed using
as named below, e.g., ``pip install gevent[events]``.
events
Configurable event support using `zope.event
<https://pypi.org/project/zope.event>`_ is highly recommended for
configurable event support.
In versions of gevent up to and including 20.5.0, this provided configurable
event support using `zope.event
<https://pypi.org/project/zope.event>`_ and was highly
recommended.
In versions after that, this extra is empty and does nothing. It
will be removed in gevent 21.0.
dnspython
Enables the new pure-Python resolver, backed by `dnspython
......
......@@ -211,7 +211,18 @@ CFFI_REQUIRES = [
]
install_requires = greenlet_requires + CFFI_REQUIRES
install_requires = greenlet_requires + CFFI_REQUIRES + [
# For event notification.
'zope.event',
# For event definitions, and our own interfaces; those should
# ultimately be published, but at this writing only the event
# interfaces are.
'zope.interface',
# setuptools is also used (via pkg_resources) for event
# notifications. It's a hard dependency of zope.interface
# anyway.
'setuptools',
]
# We use headers from greenlet, so it needs to be installed before we
# can compile. If it isn't already installed before we start
......@@ -284,8 +295,9 @@ EXTRA_DNSPYTHON = [
'idna',
]
EXTRA_EVENTS = [
'zope.event',
'zope.interface',
# No longer does anything, but the extra must stay around
# to avoid breaking install scripts.
# Remove this in 2021.
]
EXTRA_PSUTIL_DEPS = [
......
......@@ -16,10 +16,11 @@ from __future__ import print_function
import sys
from gevent._util import Interface
from gevent._util import Attribute
from zope.interface import Interface
from zope.interface import Attribute
# pylint:disable=no-method-argument, unused-argument, no-self-argument
# pylint:disable=inherit-non-class
__all__ = [
'ILoop',
......
......@@ -206,25 +206,6 @@ def gmctime():
import time
return time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
try:
from zope.interface import Interface
from zope.interface import implementer
from zope.interface import Attribute
except ImportError:
class Interface(object):
pass
def implementer(_iface):
def dec(c):
return c
return dec
def Attribute(s):
return s
Interface = Interface
implementer = implementer
Attribute = Attribute
###
# Release automation.
......
......@@ -11,13 +11,13 @@ parameter, the event object).
Higher level frameworks may take this foundation and build richer
models on it.
If :mod:`zope.event` is installed, then it will be used to provide the
functionality of `notify` and `subscribers`. See
:mod:`zope.event.classhandler` for a simple class-based approach to
subscribing to a filtered list of events, and see `zope.component
:mod:`zope.event` will be used to provide the functionality of
`notify` and `subscribers`. See :mod:`zope.event.classhandler` for a
simple class-based approach to subscribing to a filtered list of
events, and see `zope.component
<https://zopecomponent.readthedocs.io/en/latest/event.html>`_ for a
much higher-level, flexible system. If you are using one of these systems,
you generally will not want to directly modify `subscribers`.
much higher-level, flexible system. If you are using one of these
systems, you generally will not want to directly modify `subscribers`.
.. versionadded:: 1.3b1
"""
......@@ -61,61 +61,49 @@ __all__ = [
'GeventDidPatchAllEvent',
]
# pylint:disable=no-self-argument
# pylint:disable=no-self-argument,inherit-non-class
import platform
try:
from zope.event import subscribers
from zope.event import notify
except ImportError:
#: Applications may register for notification of events by appending a
#: callable to the ``subscribers`` list.
#:
#: Each subscriber takes a single argument, which is the event object
#: being published.
#:
#: Exceptions raised by subscribers will be propagated *without* running
#: any remaining subscribers.
subscribers = []
def notify(event):
"""
Notify all subscribers of ``event``.
"""
for subscriber in subscribers:
subscriber(event)
from zope.interface import Interface
from zope.interface import Attribute
from zope.interface import implementer
from zope.event import subscribers
from zope.event import notify
from pkg_resources import iter_entry_points
#: Applications may register for notification of events by appending a
#: callable to the ``subscribers`` list.
#:
#: Each subscriber takes a single argument, which is the event object
#: being published.
#:
#: Exceptions raised by subscribers will be propagated *without* running
#: any remaining subscribers.
#:
#: This is an alias for `zope.event.subscribers`; prefer to use
#: that attribute directly.
subscribers = subscribers
notify = notify # export
try:
# pkg_resources is technically optional, we don't
# list a hard dependency on it.
__import__('pkg_resources')
except ImportError:
notify_and_call_entry_points = notify
else:
from pkg_resources import iter_entry_points
import platform
try:
# Cache the platform info. pkg_resources uses
# platform.machine() for environment markers, and
# platform.machine() wants to call os.popen('uname'), which is
# broken on Py2 when the gevent child signal handler is
# installed. (see test__monkey_sigchild_2.py)
platform.uname()
except: # pylint:disable=bare-except
except: # pylint:disable=bare-except
pass
finally:
finally:
del platform
def notify_and_call_entry_points(event):
def notify_and_call_entry_points(event):
notify(event)
for plugin in iter_entry_points(event.ENTRY_POINT_NAME):
subscriber = plugin.load()
subscriber(event)
from gevent._util import Interface
from gevent._util import implementer
from gevent._util import Attribute
class IPeriodicMonitorThread(Interface):
"""
......
......@@ -14,7 +14,8 @@ __all__ = [
'loop',
]
from gevent._util import implementer
from zope.interface import implementer
from gevent._interfaces import ILoop
from gevent.libev import _corecffi # pylint:disable=no-name-in-module,import-error
......
......@@ -10,6 +10,8 @@ from collections import namedtuple
from operator import delitem
import signal
from zope.interface import implementer
from gevent import getcurrent
from gevent.exceptions import LoopExit
......@@ -17,7 +19,6 @@ from gevent._ffi import _dbg # pylint: disable=unused-import
from gevent._ffi.loop import AbstractLoop
from gevent._ffi.loop import assign_standard_callbacks
from gevent._ffi.loop import AbstractCallbacks
from gevent._util import implementer
from gevent._interfaces import ILoop
from gevent.libuv import _corecffi # pylint:disable=no-name-in-module,import-error
......
......@@ -7,6 +7,8 @@ from gevent import monkey; monkey.patch_all()
from threading import local
from threading import Thread
from zope import interface
try:
from collections.abc import Mapping
except ImportError:
......@@ -379,12 +381,7 @@ class TestGeventLocal(greentest.TestCase):
x = LocalWithClassMethod()
self.assertIs(LocalWithClassMethod, x.a_classmethod())
try:
from zope import interface
except ImportError:
interface = None
@greentest.skipIf(interface is None, "Needs zope.interface")
class TestLocalInterface(greentest.TestCase):
__timeout__ = None
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment