Commit 13d860ae authored by Jason Madden's avatar Jason Madden

Initial fixes to enable basic tests to run on Python 3.7a1.

parent 10143732
...@@ -506,6 +506,7 @@ def patch_select(aggressive=True): ...@@ -506,6 +506,7 @@ def patch_select(aggressive=True):
- :class:`selectors.KqueueSelector` - :class:`selectors.KqueueSelector`
- :class:`selectors.DevpollSelector` (Python 3.5+) - :class:`selectors.DevpollSelector` (Python 3.5+)
""" """
patch_module('select') patch_module('select')
if aggressive: if aggressive:
select = __import__('select') select = __import__('select')
...@@ -536,6 +537,14 @@ def patch_select(aggressive=True): ...@@ -536,6 +537,14 @@ def patch_select(aggressive=True):
selectors.SelectSelector._select = _select selectors.SelectSelector._select = _select
_select._gevent_monkey = True _select._gevent_monkey = True
# Python 3.7 refactors the poll-like selectors to use a common
# base class and capture a reference to select.poll, etc, at
# import time. selectors tends to get imported early
# (importing 'platform' does it: platform -> subprocess -> selectors),
# so we need to clean that up.
if hasattr(selectors, 'PollSelector') and hasattr(selectors.PollSelector, '_selector_cls'):
selectors.PollSelector._selector_cls = select.poll
if aggressive: if aggressive:
# If `selectors` had already been imported before we removed # If `selectors` had already been imported before we removed
# select.epoll|kqueue|devpoll, these may have been defined in terms # select.epoll|kqueue|devpoll, these may have been defined in terms
......
...@@ -769,6 +769,8 @@ def default_get_number_open_files(): ...@@ -769,6 +769,8 @@ def default_get_number_open_files():
lsof_get_open_files = default_get_open_files lsof_get_open_files = default_get_open_files
try: try:
# psutil import subprocess which on Python 3 imports selectors.
# This can expose issues with monkey-patching.
import psutil import psutil
except ImportError: except ImportError:
get_open_files = default_get_open_files get_open_files = default_get_open_files
......
...@@ -6,11 +6,15 @@ import contextlib ...@@ -6,11 +6,15 @@ import contextlib
import functools import functools
import sys import sys
import os import os
import platform # At least on 3.6+, importing platform
# imports subprocess, which imports selectors. That
# can expose issues with monkey patching. We don't need it
# though.
# import platform
import re import re
TRAVIS = os.environ.get("TRAVIS") == "true" TRAVIS = os.environ.get("TRAVIS") == "true"
OSX = bool(platform.mac_ver()[0]) OSX = sys.platform == 'darwin'
# By default, test cases are expected to switch and emit warnings if there was none # By default, test cases are expected to switch and emit warnings if there was none
# If a test is found in this list, it's expected not to switch. # If a test is found in this list, it's expected not to switch.
......
...@@ -470,7 +470,6 @@ class ThreadJoinOnShutdown(unittest.TestCase): ...@@ -470,7 +470,6 @@ class ThreadJoinOnShutdown(unittest.TestCase):
""" """
self._run_and_join(script) self._run_and_join(script)
@greentest.skipOnPyPy3("Buffering issue.")
def test_3_join_in_forked_from_thread(self): def test_3_join_in_forked_from_thread(self):
# Like the test above, but fork() was called from a worker thread # Like the test above, but fork() was called from a worker thread
# In the forked process, the main Thread object must be marked as stopped. # In the forked process, the main Thread object must be marked as stopped.
...@@ -500,13 +499,17 @@ class ThreadJoinOnShutdown(unittest.TestCase): ...@@ -500,13 +499,17 @@ class ThreadJoinOnShutdown(unittest.TestCase):
w = threading.Thread(target=worker) w = threading.Thread(target=worker)
w.start() w.start()
import sys
if sys.version_info[:2] >= (3, 7) or (sys.version_info[:2] >= (3, 5) and hasattr(sys, 'pypy_version_info')):
w.join()
""" """
# In PyPy3 5.8.0, if we don't wait on this top-level "thread", 'w', # In PyPy3 5.8.0, if we don't wait on this top-level "thread", 'w',
# we never see "end of thread". It's not clear why, since that's being # we never see "end of thread". It's not clear why, since that's being
# done in a child of this process. Yet in normal CPython 3, waiting on this # done in a child of this process. Yet in normal CPython 3, waiting on this
# causes the whole process to lock up (possibly because of some loop within # causes the whole process to lock up (possibly because of some loop within
# the interpreter waiting on thread locks, like the issue described in threading.py # the interpreter waiting on thread locks, like the issue described in threading.py
# for Python 3.4? in any case, it doesn't hang in Python 2.) # for Python 3.4? in any case, it doesn't hang in Python 2.) This changed in
# 3.7a1 and waiting on it is again necessary and doesn't hang.
self._run_and_join(script) self._run_and_join(script)
......
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