Commit 4b3fba8a authored by Jason Madden's avatar Jason Madden

Fix #835. patch_select deals better with unexpected import order.

parent 80f014ee
...@@ -69,6 +69,9 @@ Stdlib Compatibility ...@@ -69,6 +69,9 @@ Stdlib Compatibility
libev would tend to return the descriptor as ready. In the worst libev would tend to return the descriptor as ready. In the worst
case, this adds an extra system call, but may also reduce latency if case, this adds an extra system call, but may also reduce latency if
descriptors are ready at the time of entry. descriptors are ready at the time of entry.
- :class:`selectors.SelectSelector` is properly monkey-patched
regardless of the order of imports. Reported in :issue:`835` by
Przemysław Węgrzyn.
- :meth:`gevent.select.poll.unregister` raises an exception if *fd* is not - :meth:`gevent.select.poll.unregister` raises an exception if *fd* is not
registered, like the standard library. registered, like the standard library.
- :meth:`gevent.select.poll.poll` returns an event with - :meth:`gevent.select.poll.poll` returns an event with
......
...@@ -495,12 +495,18 @@ def patch_select(aggressive=True): ...@@ -495,12 +495,18 @@ def patch_select(aggressive=True):
# not a builtin and doesn't get the magic auto-static that they do) # not a builtin and doesn't get the magic auto-static that they do)
# r, w, _ = self._select(self._readers, self._writers, [], timeout) # r, w, _ = self._select(self._readers, self._writers, [], timeout)
# TypeError: select() takes from 3 to 4 positional arguments but 5 were given # TypeError: select() takes from 3 to 4 positional arguments but 5 were given
select = __import__('select') # Note that this obviously only happens if selectors was imported after we had patched
# select; but there is a code path that leads to it being imported first (but now we've
# patched select---so we can't compare them identically)
select = __import__('select') # Should be gevent-patched now
orig_select_select = get_original('select', 'select')
assert select.select is not orig_select_select
selectors = __import__('selectors') selectors = __import__('selectors')
if selectors.SelectSelector._select is select.select: if selectors.SelectSelector._select in (select.select, orig_select_select):
def _select(self, *args, **kwargs): # pylint:disable=unused-argument def _select(self, *args, **kwargs): # pylint:disable=unused-argument
return select.select(*args, **kwargs) return select.select(*args, **kwargs)
selectors.SelectSelector._select = _select selectors.SelectSelector._select = _select
_select._gevent_monkey = True
if aggressive: if aggressive:
# If `selectors` had already been imported before we removed # If `selectors` had already been imported before we removed
......
import sys
import greentest
try:
import selectors # Do this before the patch, just to force it
except ImportError:
pass
from gevent.monkey import patch_all
patch_all()
if sys.platform != 'win32' and sys.version_info[:2] >= (3, 4):
class TestSelectors(greentest.TestCase):
def test_selectors_select_is_patched(self):
# https://github.com/gevent/gevent/issues/835
_select = selectors.SelectSelector._select
self.assertTrue(hasattr(_select, '_gevent_monkey'), dir(_select))
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