Commit 8df44277 authored by Jason Madden's avatar Jason Madden

Fix #805. Make reload(site) work w/gevent imported

Python 2 issue only.

Allow setting attributes on sys.modules['gevent.signal']; they go to the
gevent/signal.py module for symmetry with getattr and dir.

Reloading results in leaks so don't bother checking for them.
parent aaccf2d3
......@@ -68,7 +68,8 @@ Stdlib Compatibility
- :meth:`gevent.select.poll.poll` returns an event with
``POLLNVAL`` for registered fds that are invalid. Previously it
would tend to report both read and write events.
- Python 2: ``reload(site)`` no longer fails with a ``TypeError`` if
gevent has been imported. Reported in :issue:`805` by Jake Hilton.
Other Changes
-------------
......@@ -83,7 +84,8 @@ Other Changes
timestamp. See :issue:`137`.
- Add :class:`gevent.threadpool.ThreadPoolExecutor` (a
:class:`concurrent.futures.ThreadPoolExecutor` variant that always
uses native threads) on platforms that have ``concurrent.futures``
uses native threads even when the system has been monkey-patched)
on platforms that have ``concurrent.futures``
available (Python 3 and Python 2 with the ``futures`` backport
installed). This is helpful for, e.g., grpc. Reported in
:issue:`786` by Markus Padourek.
......
......@@ -85,9 +85,10 @@ class _signal_metaclass(type):
return getattr(_signal_module, name)
def __setattr__(cls, name, value):
# Because we can't know whether to try to go to the module
# or the class, we don't allow setting an attribute after the fact
raise TypeError("Cannot set attribute")
# For symmetry with getattr and dir, pass all
# attribute setting on to the module. (This makes
# reloading work, see issue #805)
setattr(_signal_module, name, value)
def __instancecheck__(cls, instance):
return isinstance(instance, _signal_class)
......
......@@ -58,13 +58,20 @@ PLATFORM_SPECIFIC_SUFFIXES = ['2', '279', '3']
if sys.platform.startswith('win'):
PLATFORM_SPECIFIC_SUFFIXES.append('posix')
PY2 = None
PY3 = None
PY34 = None
NON_APPLICABLE_SUFFIXES = []
if sys.version_info[0] == 3:
# Python 3
NON_APPLICABLE_SUFFIXES.extend(('2', '279'))
PY2 = False
PY3 = True
if sys.version_info[0] == 2:
if sys.version_info[1] >= 4:
PY34 = True
elif sys.version_info[0] == 2:
# Any python 2
PY3 = False
PY2 = True
......@@ -73,6 +80,7 @@ if sys.version_info[0] == 2:
or (sys.version_info[1] == 7 and sys.version_info[2] < 9)):
# Python 2, < 2.7.9
NON_APPLICABLE_SUFFIXES.append('279')
if sys.platform.startswith('win'):
NON_APPLICABLE_SUFFIXES.append("posix")
# This is intimately tied to FileObjectPosix
......
......@@ -18,7 +18,7 @@ if hasattr(signal, 'SIGALRM'):
error_fatal = False
__timeout__ = 5
def test(self):
def test_alarm(self):
sig = gevent.signal(signal.SIGALRM, raise_Expected)
assert sig.ref is False, repr(sig.ref)
sig.ref = True
......@@ -41,6 +41,31 @@ if hasattr(signal, 'SIGALRM'):
finally:
sig.cancel()
@greentest.ignores_leakcheck
def test_reload(self):
# The site module tries to set attributes
# on all the modules that are loaded (specifically, __file__).
# If gevent.signal is loaded, and is our compatibility shim,
# this used to fail on Python 2: sys.modules['gevent.signal'] has no
# __loader__ attribute, so site.py's main() function tries to do
# gevent.signal.__file__ = os.path.abspath(gevent.signal.__file__), which
# used to not be allowed. (Under Python 3, __loader__ is present so this
# doesn't happen). See
# https://github.com/gevent/gevent/issues/805
import gevent.signal # make sure it's in sys.modules pylint:disable=redefined-outer-name
assert gevent.signal
import site
if greentest.PY34:
from importlib import reload as reload_module
elif greentest.PY3:
from imp import reload as reload_module
else:
# builtin on py2
reload_module = reload # pylint:disable=undefined-variable
reload_module(site)
if __name__ == '__main__':
greentest.main()
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