]> git.pld-linux.org Git - packages/python-gevent.git/blame - python-gevent-py3.8.patch
- updated to 1.4.0
[packages/python-gevent.git] / python-gevent-py3.8.patch
CommitLineData
5a03dc88
JB
1Based on https://github.com/gevent/gevent/commit/8224e81425762ad21d3b63ffb9cc0a0c2d789704.patch
2and https://src.fedoraproject.org/rpms/python-gevent/raw/master/f/0001-code-replace.patch
3
4From e6e2959184909c6292e0135b709282cd5f96065b Mon Sep 17 00:00:00 2001
5From: Jason Madden <jamadden@gmail.com>
6Date: Fri, 6 Sep 2019 16:29:58 -0500
7Subject: [PATCH 1/9] Basic support for CPython 3.8.0b4.
8
9Still needs the specific networking test classes added, but all the basics pass for me. Lets see about CI.
10---
11 .travis.yml | 11 +++++++
12 CHANGES.rst | 4 +++
13 examples/webproxy.py | 7 +++-
14 pyproject.toml | 5 +--
15 scripts/install.sh | 3 ++
16 src/gevent/__semaphore.pxd | 2 +-
17 src/gevent/_compat.py | 2 +-
18 src/gevent/_socket2.py | 1 +
19 src/gevent/_socketcommon.py | 12 +++++--
20 src/gevent/monkey.py | 46 +++++++++++++++++++++++++--
21 src/gevent/os.py | 29 ++++++++++++++---
22 src/gevent/subprocess.py | 32 +++++++++++++++++++
23 src/gevent/testing/testrunner.py | 17 +++++++---
24 src/gevent/tests/test__core_fork.py | 7 ++--
25 src/gevent/tests/test__threading_2.py | 26 +++++++++------
26 src/gevent/thread.py | 6 ++++
27 src/gevent/threading.py | 46 ++++++++++-----------------
28 17 files changed, 196 insertions(+), 60 deletions(-)
29
30#diff --git a/.travis.yml b/.travis.yml
31#index bf307df95..05dc24b12 100644
32#--- a/.travis.yml
33#+++ b/.travis.yml
34#@@ -42,6 +42,7 @@ env:
35# - TRAVIS_PYTHON_VERSION=3.5
36# - TRAVIS_PYTHON_VERSION=3.6
37# - TRAVIS_PYTHON_VERSION=3.7
38#+ - TRAVIS_PYTHON_VERSION=3.8
39# - TRAVIS_PYTHON_VERSION=pypy2.7
40# - TRAVIS_PYTHON_VERSION=pypy3.6
41# - TRAVIS_PYTHON_VERSION=2.7 GEVENTSETUP_EMBED=0
42#@@ -144,6 +145,8 @@ jobs:
43# script: ccache -s
44# before_script: true
45# after_success: true
46#+ - <<: *build-gevent
47#+ env: TRAVIS_PYTHON_VERSION=3.8
48# - <<: *build-gevent
49# env: TRAVIS_PYTHON_VERSION=3.5
50# - <<: *build-gevent
51#@@ -278,6 +281,14 @@ jobs:
52# env: TRAVIS_PYTHON_VERSION=3.7
53# name: pure37
54#
55#+ # 3.8
56#+ - <<: *test-libuv-jobs
57#+ env: TRAVIS_PYTHON_VERSION=3.8
58#+ name: libuv36
59#+ - <<: *test-libev-jobs
60#+ env: TRAVIS_PYTHON_VERSION=3.8
61#+ name: libev-cffi36
62#+
63#
64# # 2.7, no-embed. Run the tests that exercise the libraries we
65# # linked to.
66#diff --git a/CHANGES.rst b/CHANGES.rst
67#index 52b5e1c6f..53f4398d2 100644
68#--- a/CHANGES.rst
69#+++ b/CHANGES.rst
70#@@ -12,6 +12,10 @@
71# - Add an ``--module`` option to ``gevent.monkey`` allowing to run a Python
72# module rather than a script. See :pr:`1440`.
73#
74#+- Add support for CPython 3.8.0b4.
75#+
76#+- Improve the way joining the main thread works on Python 3.
77#+
78# 1.5a1 (2019-05-02)
79# ==================
80#
81diff --git a/examples/webproxy.py b/examples/webproxy.py
82index e381d6bd4..de1eaf8d5 100755
83--- a/examples/webproxy.py
84+++ b/examples/webproxy.py
85@@ -15,7 +15,12 @@
86 import sys
87 import re
88 import traceback
89-from cgi import escape
90+
91+try:
92+ from cgi import escape
93+except ImportError:
94+ # Python 3.8 removed this API
95+ from html import escape
96
97 try:
98 import urllib2
99#diff --git a/pyproject.toml b/pyproject.toml
100#index 2b611b9a4..f611ef972 100644
101#--- a/pyproject.toml
102#+++ b/pyproject.toml
103#@@ -12,8 +12,9 @@ requires = [
104# # 0.28 is faster, and (important!) lets us specify the target module
105# # name to be created so that we can have both foo.py and _foo.so
106# # at the same time. 0.29 fixes some issues with Python 3.7,
107#- # and adds the 3str mode for transition to Python 3.
108#- "Cython >= 0.29.7",
109#+ # and adds the 3str mode for transition to Python 3. 0.29.12+ is
110#+ # required for Python 3.8
111#+ "Cython >= 0.29.13",
112# # See version requirements in setup.py
113# "cffi >= 1.12.3 ; platform_python_implementation == 'CPython'",
114# # Python 3.7 requires at least 0.4.14, which is ABI incompatible with earlier
115#diff --git a/scripts/install.sh b/scripts/install.sh
116#index 94bd53058..ef8a6dfbd 100755
117#--- a/scripts/install.sh
118#+++ b/scripts/install.sh
119#@@ -99,6 +99,9 @@ for var in "$@"; do
120# 3.7)
121# install 3.7.2 python3.7 3.7.d
122# ;;
123#+ 3.8)
124#+ install 3.8.0b4 python3.8 3.8.d
125#+ ;;
126# pypy2.7)
127# install pypy2.7-7.1.0 pypy2.7 pypy2.7.d
128# ;;
129diff --git a/src/gevent/__semaphore.pxd b/src/gevent/__semaphore.pxd
130index dc9f11c68..e46778ed7 100644
131--- a/src/gevent/__semaphore.pxd
132+++ b/src/gevent/__semaphore.pxd
133@@ -13,7 +13,7 @@ cdef class Semaphore(AbstractLinkable):
134 # threadpool uses it
135 cpdef _start_notify(self)
136 cpdef int wait(self, object timeout=*) except -1000
137- cpdef bint acquire(self, int blocking=*, object timeout=*) except -1000
138+ cpdef bint acquire(self, bint blocking=*, object timeout=*) except -1000
139 cpdef __enter__(self)
140 cpdef __exit__(self, object t, object v, object tb)
141
142diff --git a/src/gevent/_compat.py b/src/gevent/_compat.py
143index 56391459e..e8f5ed4ba 100644
144--- a/src/gevent/_compat.py
145+++ b/src/gevent/_compat.py
146@@ -21,7 +21,7 @@
147 PYPY = hasattr(sys, 'pypy_version_info')
148 WIN = sys.platform.startswith("win")
149 LINUX = sys.platform.startswith('linux')
150-OSX = sys.platform == 'darwin'
151+OSX = MAC = sys.platform == 'darwin'
152
153
154 PURE_PYTHON = PYPY or os.getenv('PURE_PYTHON')
155diff --git a/src/gevent/_socket2.py b/src/gevent/_socket2.py
156index 15f470893..7c2f35f3e 100644
157--- a/src/gevent/_socket2.py
158+++ b/src/gevent/_socket2.py
159@@ -6,6 +6,7 @@
160
161 # Our import magic sadly makes this warning useless
162 # pylint: disable=undefined-variable
163+import sys
164
165 from gevent import _socketcommon
166 from gevent._util import copy_globals
167#diff --git a/src/gevent/_socketcommon.py b/src/gevent/_socketcommon.py
168#index cd12ac1a9..87b9a4f8a 100644
169#--- a/src/gevent/_socketcommon.py
170#+++ b/src/gevent/_socketcommon.py
171#@@ -69,13 +69,19 @@
172# __imports__.extend(__py3_imports__)
173#
174# import time
175#-import sys
176#+
177# from gevent._hub_local import get_hub_noargs as get_hub
178# from gevent._compat import string_types, integer_types, PY3
179#+from gevent._compat import PY38
180#+from gevent._compat import WIN as is_windows
181#+from gevent._compat import OSX as is_macos
182# from gevent._util import copy_globals
183#
184#-is_windows = sys.platform == 'win32'
185#-is_macos = sys.platform == 'darwin'
186#+if PY38:
187#+ __imports__.extend([
188#+ 'create_server',
189#+ 'has_dualstack_ipv6',
190#+ ])
191#
192# # pylint:disable=no-name-in-module,unused-import
193# if is_windows:
194diff --git a/src/gevent/monkey.py b/src/gevent/monkey.py
195index 5dbfe3f78..f862f879c 100644
196--- a/src/gevent/monkey.py
197+++ b/src/gevent/monkey.py
198@@ -668,6 +668,22 @@ def join(timeout=None):
199 raise RuntimeError("Cannot join current thread")
200 if thread_greenlet is not None and thread_greenlet.dead:
201 return
202+ # You may ask: Why not call thread_greenlet.join()?
203+ # Well, in the one case we actually have a greenlet, it's the
204+ # low-level greenlet.greenlet object for the main thread, which
205+ # doesn't have a join method.
206+ #
207+ # You may ask: Why not become the main greenlet's *parent*
208+ # so you can get notified when it finishes? Because you can't
209+ # create a greenlet cycle (the current greenlet is a descendent
210+ # of the parent), and nor can you set a greenlet's parent to None,
211+ # so there can only ever be one greenlet with a parent of None: the main
212+ # greenlet, the one we need to watch.
213+ #
214+ # You may ask: why not swizzle out the problematic lock on the main thread
215+ # into a gevent friendly lock? Well, the interpreter actually depends on that
216+ # for the main thread in threading._shutdown; see below.
217+
218 if not thread.is_alive():
219 return
220
221@@ -700,8 +716,34 @@ def join(timeout=None):
222 if orig_current_thread == threading_mod.main_thread():
223 main_thread = threading_mod.main_thread()
224 _greenlet = main_thread._greenlet = greenlet.getcurrent()
225-
226- main_thread.join = make_join_func(main_thread, _greenlet)
227+ main_thread.__real_tstate_lock = main_thread._tstate_lock
228+
229+ # The interpreter will call threading._shutdown
230+ # when the main thread exits and is about to
231+ # go away. It is called *in* the main thread. This
232+ # is a perfect place to notify other greenlets that
233+ # the main thread is done. We do this by overriding the
234+ # lock of the main thread during operation, and only restoring
235+ # it to the native blocking version at shutdown time
236+ # (the interpreter also has a reference to this lock in a
237+ # C data structure).
238+ main_thread._tstate_lock = threading_mod.Lock()
239+ main_thread._tstate_lock.acquire()
240+ orig_shutdown = threading_mod._shutdown
241+ def _shutdown():
242+ # Release anyone trying to join() me,
243+ # and let us switch to them.
244+ if main_thread._tstate_lock:
245+ main_thread._tstate_lock.release()
246+ from gevent import sleep
247+ sleep()
248+ # The only truly blocking native shutdown lock to
249+ # acquire should be our own (hopefully)
250+ main_thread._tstate_lock = main_thread.__real_tstate_lock
251+ main_thread.__real_tstate_lock = None
252+ orig_shutdown()
253+
254+ threading_mod._shutdown = _shutdown
255
256 # Patch up the ident of the main thread to match. This
257 # matters if threading was imported before monkey-patching
258diff --git a/src/gevent/os.py b/src/gevent/os.py
259index 3980f320c..4dd66abd8 100644
260--- a/src/gevent/os.py
261+++ b/src/gevent/os.py
262@@ -385,6 +385,12 @@ def waitpid(pid, options):
263 # we're not watching it
264 return _waitpid(pid, options)
265
266+ def _watch_child(pid, callback=None, loop=None, ref=False):
267+ loop = loop or get_hub().loop
268+ watcher = loop.child(pid, ref=ref)
269+ _watched_children[pid] = watcher
270+ watcher.start(_on_child, watcher, callback)
271+
272 def fork_and_watch(callback=None, loop=None, ref=False, fork=fork_gevent):
273 """
274 Fork a child process and start a child watcher for it in the parent process.
275@@ -413,10 +419,7 @@ def fork_and_watch(callback=None, loop=None, ref=False, fork=fork_gevent):
276 pid = fork()
277 if pid:
278 # parent
279- loop = loop or get_hub().loop
280- watcher = loop.child(pid, ref=ref)
281- _watched_children[pid] = watcher
282- watcher.start(_on_child, watcher, callback)
283+ _watch_child(pid, callback, loop, ref)
284 return pid
285
286 __extensions__.append('fork_and_watch')
287@@ -474,6 +477,23 @@ def forkpty(*args, **kwargs):
288 # take any args to match fork_and_watch
289 return forkpty_and_watch(*args, **kwargs)
290 __implements__.append("waitpid")
291+
292+ if hasattr(os, 'posix_spawn'):
293+ _raw_posix_spawn = os.posix_spawn
294+ _raw_posix_spawnp = os.posix_spawnp
295+
296+ def posix_spawn(*args, **kwargs):
297+ pid = _raw_posix_spawn(*args, **kwargs)
298+ _watch_child(pid)
299+ return pid
300+
301+ def posix_spawnp(*args, **kwargs):
302+ pid = _raw_posix_spawnp(*args, **kwargs)
303+ _watch_child(pid)
304+ return pid
305+
306+ __implements__.append("posix_spawn")
307+ __implements__.append("posix_spawnp")
308 else:
309 def fork():
310 """
311@@ -503,6 +523,7 @@ def forkpty():
312 else:
313 __implements__.remove('fork')
314
315+
316 __imports__ = copy_globals(os, globals(),
317 names_to_ignore=__implements__ + __extensions__,
318 dunder_names_to_keep=())
319#diff --git a/src/gevent/subprocess.py b/src/gevent/subprocess.py
320#index a9894f1ab..9b4d13cd2 100644
321#--- a/src/gevent/subprocess.py
322#+++ b/src/gevent/subprocess.py
323#@@ -47,6 +47,7 @@
324# from gevent._compat import PY35
325# from gevent._compat import PY36
326# from gevent._compat import PY37
327#+from gevent._compat import PY38
328# from gevent._compat import reraise
329# from gevent._compat import fspath
330# from gevent._compat import fsencode
331#@@ -69,6 +70,25 @@
332# __implements__.append("_posixsubprocess")
333# _posixsubprocess = None
334#
335#+if PY38:
336#+ # Using os.posix_spawn() to start subprocesses
337#+ # bypasses our child watchers on certain operating systems,
338#+ # and with certain library versions. Possibly the right
339#+ # fix is to monkey-patch os.posix_spawn like we do os.fork?
340#+ # These have no effect, they're just here to match the stdlib.
341#+ # TODO: When available, given a monkey patch on them, I think
342#+ # we ought to be able to use them if the stdlib has identified them
343#+ # as suitable.
344#+ __implements__.extend([
345#+ '_use_posix_spawn',
346#+ '_USE_POSIX_SPAWN'
347#+ ])
348#+
349#+ def _use_posix_spawn():
350#+ return False
351#+
352#+ _USE_POSIX_SPAWN = False
353#+
354# # Some symbols we define that we expect to export;
355# # useful for static analysis
356# PIPE = "PIPE should be imported"
357#@@ -1720,3 +1740,15 @@ def run(*popenargs, **kwargs):
358# raise _with_stdout_stderr(CalledProcessError(retcode, process.args, stdout), stderr)
359#
360# return CompletedProcess(process.args, retcode, stdout, stderr)
361#+
362#+def _gevent_did_monkey_patch(*_args):
363#+ # Beginning on 3.8 on Mac, the 'spawn' method became the default
364#+ # start method. That doesn't fire fork watchers and we can't
365#+ # easily patch to make it do so: multiprocessing uses the private
366#+ # c accelerated _subprocess module to implement this. Instead we revert
367#+ # back to using fork.
368#+ from gevent._compat import MAC
369#+ if MAC:
370#+ import multiprocessing
371#+ if hasattr(multiprocessing, 'set_start_method'):
372#+ multiprocessing.set_start_method('fork', force=True)
373diff --git a/src/gevent/testing/testrunner.py b/src/gevent/testing/testrunner.py
374index 3c1c711f8..7a3f8c6bb 100644
375--- a/src/gevent/testing/testrunner.py
376+++ b/src/gevent/testing/testrunner.py
377@@ -480,17 +480,26 @@ def _setup_environ(debug=False):
378 if 'GEVENT_DEBUG' not in os.environ and debug:
379 os.environ['GEVENT_DEBUG'] = 'debug'
380
381- if 'PYTHONTRACEMALLOC' not in os.environ:
382+ if 'PYTHONTRACEMALLOC' not in os.environ and debug:
383+ # This slows the tests down quite a bit. Reserve
384+ # for debugging.
385 os.environ['PYTHONTRACEMALLOC'] = '10'
386
387 if 'PYTHONDEVMODE' not in os.environ:
388- # Python 3.7
389+ # Python 3.7 and above.
390 os.environ['PYTHONDEVMODE'] = '1'
391
392- if 'PYTHONMALLOC' not in os.environ:
393- # Python 3.6
394+ if 'PYTHONMALLOC' not in os.environ and debug:
395+ # Python 3.6 and above.
396+ # This slows the tests down some, but
397+ # can detect memory corruption. Unfortunately
398+ # it can also be flaky, especially in pre-release
399+ # versions of Python (e.g., lots of crashes on Python 3.8b4).
400 os.environ['PYTHONMALLOC'] = 'debug'
401
402+ if sys.version_info.releaselevel != 'final' and not debug:
403+ os.environ['PYTHONMALLOC'] = 'default'
404+ os.environ['PYTHONDEVMODE'] = ''
405
406
407 def main():
408diff --git a/src/gevent/tests/test__core_fork.py b/src/gevent/tests/test__core_fork.py
409index fee42f547..5717cf7d9 100644
410--- a/src/gevent/tests/test__core_fork.py
411+++ b/src/gevent/tests/test__core_fork.py
412@@ -1,11 +1,13 @@
413 from __future__ import print_function
414 import gevent.monkey
415 gevent.monkey.patch_all()
416-import gevent
417-import os
418
419+import os
420 import multiprocessing
421
422+import gevent
423+from gevent._compat import MAC
424+
425 hub = gevent.get_hub()
426 pid = os.getpid()
427 newpid = None
428@@ -46,6 +48,7 @@ def test():
429 if __name__ == '__main__':
430 # Must call for Windows to fork properly; the fork can't be in the top-level
431 multiprocessing.freeze_support()
432+
433 # fork watchers weren't firing in multi-threading processes.
434 # This test is designed to prove that they are.
435 # However, it fails on Windows: The fork watcher never runs!
436diff --git a/src/gevent/tests/test__threading_2.py b/src/gevent/tests/test__threading_2.py
437index b425c88a3..cb7f8b91e 100644
438--- a/src/gevent/tests/test__threading_2.py
439+++ b/src/gevent/tests/test__threading_2.py
440@@ -33,6 +33,7 @@
441 from test.support import verbose
442 except ImportError:
443 from test.test_support import verbose
444+
445 import random
446 import re
447 import sys
448@@ -46,7 +47,7 @@
449 import weakref
450
451 from gevent.tests import lock_tests
452-
453+verbose = False
454 # A trivial mutable counter.
455
456 def skipDueToHang(cls):
457@@ -132,7 +133,7 @@ def test_various_ops(self):
458 print('waiting for all tasks to complete')
459 for t in threads:
460 t.join(NUMTASKS)
461- self.assertFalse(t.is_alive())
462+ self.assertFalse(t.is_alive(), t.__dict__)
463 if hasattr(t, 'ident'):
464 self.assertNotEqual(t.ident, 0)
465 self.assertFalse(t.ident is None)
466@@ -351,28 +352,33 @@ def test_join_nondaemon_on_shutdown(self):
467 # Issue 1722344
468 # Raising SystemExit skipped threading._shutdown
469 import subprocess
470- p = subprocess.Popen([sys.executable, "-W", "ignore", "-c", """if 1:
471+ script = """if 1:
472 %s
473 import threading
474 from time import sleep
475
476 def child():
477- sleep(1)
478+ sleep(0.3)
479 # As a non-daemon thread we SHOULD wake up and nothing
480 # should be torn down yet
481- print("Woke up, sleep function is: %%r" %% sleep)
482+ print("Woke up, sleep function is: %%s.%%s" %% (sleep.__module__, sleep.__name__))
483
484 threading.Thread(target=child).start()
485 raise SystemExit
486- """ % setup_4],
487+ """ % setup_4
488+ p = subprocess.Popen([sys.executable, "-W", "ignore", "-c", script],
489 stdout=subprocess.PIPE,
490 stderr=subprocess.PIPE)
491 stdout, stderr = p.communicate()
492 stdout = stdout.strip()
493 stdout = stdout.decode('utf-8')
494 stderr = stderr.decode('utf-8')
495- assert re.match('^Woke up, sleep function is: <.*?sleep.*?>$', stdout), repr(stdout)
496- stderr = re.sub(r"^\[\d+ refs\]", "", stderr, re.MULTILINE).strip()
497+
498+
499+ self.assertEqual(
500+ 'Woke up, sleep function is: gevent.hub.sleep',
501+ stdout)
502+
503 # On Python 2, importing pkg_resources tends to result in some 'ImportWarning'
504 # being printed to stderr about packages missing __init__.py; the -W ignore is...
505 # ignored.
506@@ -410,7 +416,7 @@ def __init__(self, should_raise):
507 self.should_raise = should_raise
508 self.thread = threading.Thread(target=self._run,
509 args=(self,),
510- kwargs={'yet_another': self})
511+ kwargs={'_yet_another': self})
512 self.thread.start()
513
514 def _run(self, _other_ref, _yet_another):
515@@ -463,7 +469,7 @@ def test_1_join_on_shutdown(self):
516 t = threading.Thread(target=joiningfunc,
517 args=(threading.current_thread(),))
518 t.start()
519- time.sleep(0.1)
520+ time.sleep(0.2)
521 print('end of main')
522 """
523 self._run_and_join(script)
524#diff --git a/src/gevent/thread.py b/src/gevent/thread.py
525#index a1fe41813..14428df3f 100644
526#--- a/src/gevent/thread.py
527#+++ b/src/gevent/thread.py
528#@@ -41,6 +41,12 @@
529# 'interrupt_main',
530# 'start_new'
531# ]
532#+ if sys.version_info[:2] >= (3, 8):
533#+ # We can't actually produce a value that "may be used
534#+ # to identify this particular thread system-wide", right?
535#+ # Even if we could, I imagine people will want to pass this to
536#+ # non-Python (native) APIs, so we shouldn't mess with it.
537#+ __imports__.append('get_native_id')
538#
539#
540# error = __thread__.error
541diff --git a/src/gevent/threading.py b/src/gevent/threading.py
542index c845fd221..64d989584 100644
543--- a/src/gevent/threading.py
544+++ b/src/gevent/threading.py
545@@ -160,41 +160,25 @@ def main_native_thread():
546 if PY3:
547 # XXX: Issue 18808 breaks us on Python 3.4+.
548 # Thread objects now expect a callback from the interpreter itself
549- # (threadmodule.c:release_sentinel). Because this never happens
550+ # (threadmodule.c:release_sentinel) when the C-level PyThreadState
551+ # object is being deallocated. Because this never happens
552 # when a greenlet exits, join() and friends will block forever.
553- # The solution below involves capturing the greenlet when it is
554- # started and deferring the known broken methods to it.
555+ # Fortunately this is easy to fix: just ensure that the allocation of the
556+ # lock, _set_sentinel, creates a *gevent* lock, and release it when
557+ # we're done. The main _shutdown code is in Python and deals with
558+ # this gracefully.
559
560 class Thread(__threading__.Thread):
561- _greenlet = None
562-
563- def is_alive(self):
564- return bool(self._greenlet)
565-
566- isAlive = is_alive
567
568 def _set_tstate_lock(self):
569- self._greenlet = getcurrent()
570-
571- def run(self):
572- try:
573- super(Thread, self).run()
574- finally:
575- # avoid ref cycles, but keep in __dict__ so we can
576- # distinguish the started/never-started case
577- self._greenlet = None
578- self._stop() # mark as finished
579-
580- def join(self, timeout=None):
581- if '_greenlet' not in self.__dict__:
582- raise RuntimeError("Cannot join an inactive thread")
583- if self._greenlet is None:
584- return
585- self._greenlet.join(timeout=timeout)
586-
587- def _wait_for_tstate_lock(self, *args, **kwargs):
588- # pylint:disable=arguments-differ
589- raise NotImplementedError()
590+ super(Thread, self)._set_tstate_lock()
591+ greenlet = getcurrent()
592+ greenlet.rawlink(self.__greenlet_finished)
593+
594+ def __greenlet_finished(self, _):
595+ if self._tstate_lock:
596+ self._tstate_lock.release()
597+ self._stop()
598
599 __implements__.append('Thread')
600
601@@ -203,6 +187,8 @@ class Timer(Thread, __threading__.Timer): # pylint:disable=abstract-method,inher
602
603 __implements__.append('Timer')
604
605+ _set_sentinel = allocate_lock
606+ __implements__.append('_set_sentinel')
607 # The main thread is patched up with more care
608 # in _gevent_will_monkey_patch
609
610
611From 632d3c9990f7db27f76245895bb4c2717818c5d5 Mon Sep 17 00:00:00 2001
612From: Jason Madden <jamadden@gmail.com>
613Date: Fri, 6 Sep 2019 18:26:42 -0500
614Subject: [PATCH 2/9] Add the 3.8 test cases.
615
616---
617 src/gevent/_ssl3.py | 14 +
618 src/gevent/monkey.py | 37 +-
619 src/gevent/testing/patched_tests_setup.py | 36 +-
620 src/gevent/testing/sysinfo.py | 3 +
621 src/greentest/3.8/allsans.pem | 81 +
622 src/greentest/3.8/badcert.pem | 36 +
623 src/greentest/3.8/badkey.pem | 40 +
624 src/greentest/3.8/capath/4e1295a3.0 | 14 +
625 src/greentest/3.8/capath/5ed36f99.0 | 41 +
626 src/greentest/3.8/capath/6e88d7b8.0 | 14 +
627 src/greentest/3.8/capath/99d0fa06.0 | 41 +
628 src/greentest/3.8/capath/b1930218.0 | 26 +
629 src/greentest/3.8/capath/ceff1710.0 | 26 +
630 src/greentest/3.8/ffdh3072.pem | 41 +
631 src/greentest/3.8/idnsans.pem | 169 +
632 src/greentest/3.8/keycert.passwd.pem | 68 +
633 src/greentest/3.8/keycert.pem | 66 +
634 src/greentest/3.8/keycert2.pem | 66 +
635 src/greentest/3.8/keycert3.pem | 164 +
636 src/greentest/3.8/keycert4.pem | 164 +
637 src/greentest/3.8/keycertecc.pem | 106 +
638 src/greentest/3.8/nokia.pem | 31 +
639 src/greentest/3.8/nullbytecert.pem | 90 +
640 src/greentest/3.8/nullcert.pem | 0
641 src/greentest/3.8/pycacert.pem | 99 +
642 src/greentest/3.8/pycakey.pem | 40 +
643 src/greentest/3.8/revocation.crl | 14 +
644 src/greentest/3.8/secp384r1.pem | 7 +
645 .../3.8/selfsigned_pythontestdotnet.pem | 34 +
646 src/greentest/3.8/ssl_cert.pem | 26 +
647 src/greentest/3.8/ssl_key.passwd.pem | 42 +
648 src/greentest/3.8/ssl_key.pem | 40 +
649 src/greentest/3.8/talos-2019-0758.pem | 22 +
650 src/greentest/3.8/test_asyncore.py | 834 +++
651 src/greentest/3.8/test_ftplib.py | 1093 +++
652 src/greentest/3.8/test_httplib.py | 1977 ++++++
653 src/greentest/3.8/test_select.py | 81 +
654 src/greentest/3.8/test_selectors.py | 564 ++
655 src/greentest/3.8/test_smtpd.py | 1013 +++
656 src/greentest/3.8/test_socket.py | 6278 +++++++++++++++++
657 src/greentest/3.8/test_ssl.py | 4652 ++++++++++++
658 src/greentest/3.8/test_subprocess.py | 3330 +++++++++
659 src/greentest/3.8/test_threading.py | 1382 ++++
660 src/greentest/3.8/test_wsgiref.py | 867 +++
661 src/greentest/3.8/version | 1 +
662 45 files changed, 23756 insertions(+), 14 deletions(-)
663 create mode 100644 src/greentest/3.8/allsans.pem
664 create mode 100644 src/greentest/3.8/badcert.pem
665 create mode 100644 src/greentest/3.8/badkey.pem
666 create mode 100644 src/greentest/3.8/capath/4e1295a3.0
667 create mode 100644 src/greentest/3.8/capath/5ed36f99.0
668 create mode 100644 src/greentest/3.8/capath/6e88d7b8.0
669 create mode 100644 src/greentest/3.8/capath/99d0fa06.0
670 create mode 100644 src/greentest/3.8/capath/b1930218.0
671 create mode 100644 src/greentest/3.8/capath/ceff1710.0
672 create mode 100644 src/greentest/3.8/ffdh3072.pem
673 create mode 100644 src/greentest/3.8/idnsans.pem
674 create mode 100644 src/greentest/3.8/keycert.passwd.pem
675 create mode 100644 src/greentest/3.8/keycert.pem
676 create mode 100644 src/greentest/3.8/keycert2.pem
677 create mode 100644 src/greentest/3.8/keycert3.pem
678 create mode 100644 src/greentest/3.8/keycert4.pem
679 create mode 100644 src/greentest/3.8/keycertecc.pem
680 create mode 100644 src/greentest/3.8/nokia.pem
681 create mode 100644 src/greentest/3.8/nullbytecert.pem
682 create mode 100644 src/greentest/3.8/nullcert.pem
683 create mode 100644 src/greentest/3.8/pycacert.pem
684 create mode 100644 src/greentest/3.8/pycakey.pem
685 create mode 100644 src/greentest/3.8/revocation.crl
686 create mode 100644 src/greentest/3.8/secp384r1.pem
687 create mode 100644 src/greentest/3.8/selfsigned_pythontestdotnet.pem
688 create mode 100644 src/greentest/3.8/ssl_cert.pem
689 create mode 100644 src/greentest/3.8/ssl_key.passwd.pem
690 create mode 100644 src/greentest/3.8/ssl_key.pem
691 create mode 100644 src/greentest/3.8/talos-2019-0758.pem
692 create mode 100644 src/greentest/3.8/test_asyncore.py
693 create mode 100644 src/greentest/3.8/test_ftplib.py
694 create mode 100644 src/greentest/3.8/test_httplib.py
695 create mode 100644 src/greentest/3.8/test_select.py
696 create mode 100644 src/greentest/3.8/test_selectors.py
697 create mode 100644 src/greentest/3.8/test_smtpd.py
698 create mode 100644 src/greentest/3.8/test_socket.py
699 create mode 100644 src/greentest/3.8/test_ssl.py
700 create mode 100644 src/greentest/3.8/test_subprocess.py
701 create mode 100644 src/greentest/3.8/test_threading.py
702 create mode 100644 src/greentest/3.8/test_wsgiref.py
703 create mode 100644 src/greentest/3.8/version
704
705=== SKIPPED ===
706From e349789fff94418ff363c3d7ba8d4cf4a5bcd798 Mon Sep 17 00:00:00 2001
707From: Jason Madden <jamadden@gmail.com>
708Date: Fri, 6 Sep 2019 18:27:34 -0500
709Subject: [PATCH 3/9] Fix lint.
710
711---
712 src/gevent/tests/test__core_fork.py | 1 -
713 1 file changed, 1 deletion(-)
714
715diff --git a/src/gevent/tests/test__core_fork.py b/src/gevent/tests/test__core_fork.py
716index 5717cf7d9..20dc2a4d1 100644
717--- a/src/gevent/tests/test__core_fork.py
718+++ b/src/gevent/tests/test__core_fork.py
719@@ -6,7 +6,6 @@
720 import multiprocessing
721
722 import gevent
723-from gevent._compat import MAC
724
725 hub = gevent.get_hub()
726 pid = os.getpid()
727
728From 5c5d2bc660b599256734a9f5c9e58c79ec4f1b1b Mon Sep 17 00:00:00 2001
729From: Jason Madden <jamadden@gmail.com>
730Date: Fri, 6 Sep 2019 18:28:24 -0500
731Subject: [PATCH 4/9] Fix the other place that refs the version in .travis.yml.
732
733---
734 .travis.yml | 4 ++--
735 1 file changed, 2 insertions(+), 2 deletions(-)
736
737#diff --git a/.travis.yml b/.travis.yml
738#index 05dc24b12..c956f6ae7 100644
739#--- a/.travis.yml
740#+++ b/.travis.yml
741#@@ -284,10 +284,10 @@ jobs:
742# # 3.8
743# - <<: *test-libuv-jobs
744# env: TRAVIS_PYTHON_VERSION=3.8
745#- name: libuv36
746#+ name: libuv38
747# - <<: *test-libev-jobs
748# env: TRAVIS_PYTHON_VERSION=3.8
749#- name: libev-cffi36
750#+ name: libev-cffi38
751#
752#
753# # 2.7, no-embed. Run the tests that exercise the libraries we
754#
755From 0a45f740f3afce22c88fd7f9dbe5e30aa7d95336 Mon Sep 17 00:00:00 2001
756From: Jason Madden <jamadden@gmail.com>
757Date: Fri, 6 Sep 2019 18:48:09 -0500
758Subject: [PATCH 5/9] Fix false detection in test__all__.
759
760---
761 .travis.yml | 7 +++++--
762 src/gevent/subprocess.py | 45 ++++++++++++++++++++++++----------------
763 2 files changed, 32 insertions(+), 20 deletions(-)
764
765#diff --git a/.travis.yml b/.travis.yml
766#index c956f6ae7..f676bb6e7 100644
767#--- a/.travis.yml
768#+++ b/.travis.yml
769#@@ -198,9 +198,12 @@ jobs:
770# # We only need to do this on one version, and it should be Python 3, because
771# # pylint has stopped updating for Python 2.
772# - stage: test
773#- # We need pylint, since above we're not installing a requirements file
774#+ # We need pylint, since above we're not installing a
775#+ # requirements file. Code added to _ssl3.SSLContext for Python
776#+ # 3.8 triggers an infinite recursion bug in pylint 2.3.1/astroid 2.2.5
777#+ # unless we disable inference.
778# install: pip install pylint
779#- script: python -m pylint --rcfile=.pylintrc gevent
780#+ script: python -m pylint --limit-inference-results=1 --rcfile=.pylintrc gevent
781# env: TRAVIS_PYTHON_VERSION=3.7
782# name: lint37
783#
784#diff --git a/src/gevent/subprocess.py b/src/gevent/subprocess.py
785#index 9b4d13cd2..ed22d863b 100644
786#--- a/src/gevent/subprocess.py
787#+++ b/src/gevent/subprocess.py
788#@@ -70,24 +70,6 @@
789# __implements__.append("_posixsubprocess")
790# _posixsubprocess = None
791#
792#-if PY38:
793#- # Using os.posix_spawn() to start subprocesses
794#- # bypasses our child watchers on certain operating systems,
795#- # and with certain library versions. Possibly the right
796#- # fix is to monkey-patch os.posix_spawn like we do os.fork?
797#- # These have no effect, they're just here to match the stdlib.
798#- # TODO: When available, given a monkey patch on them, I think
799#- # we ought to be able to use them if the stdlib has identified them
800#- # as suitable.
801#- __implements__.extend([
802#- '_use_posix_spawn',
803#- '_USE_POSIX_SPAWN'
804#- ])
805#-
806#- def _use_posix_spawn():
807#- return False
808#-
809#- _USE_POSIX_SPAWN = False
810#
811# # Some symbols we define that we expect to export;
812# # useful for static analysis
813#@@ -183,6 +165,33 @@ def _use_posix_spawn():
814# 'CREATE_BREAKAWAY_FROM_JOB'
815# ])
816#
817#+if PY38:
818#+ # Using os.posix_spawn() to start subprocesses
819#+ # bypasses our child watchers on certain operating systems,
820#+ # and with certain library versions. Possibly the right
821#+ # fix is to monkey-patch os.posix_spawn like we do os.fork?
822#+ # These have no effect, they're just here to match the stdlib.
823#+ # TODO: When available, given a monkey patch on them, I think
824#+ # we ought to be able to use them if the stdlib has identified them
825#+ # as suitable.
826#+ __implements__.extend([
827#+ '_use_posix_spawn',
828#+ ])
829#+
830#+ def _use_posix_spawn():
831#+ return False
832#+
833#+ _USE_POSIX_SPAWN = False
834#+
835#+ if __subprocess__._USE_POSIX_SPAWN:
836#+ __implements__.extend([
837#+ '_USE_POSIX_SPAWN',
838#+ ])
839#+ else:
840#+ __imports__.extend([
841#+ '_USE_POSIX_SPAWN',
842#+ ])
843#+
844# actually_imported = copy_globals(__subprocess__, globals(),
845# only_names=__imports__,
846# ignore_missing_names=True)
847#
848From 412d59d0889bf0d1221c52d902a98a7648f0a829 Mon Sep 17 00:00:00 2001
849From: Jason Madden <jamadden@gmail.com>
850Date: Sat, 7 Sep 2019 07:04:09 -0500
851Subject: [PATCH 6/9] Hmm, why is test__core giving fits on py38/libuv/travis?
852 Can't reproduce locally.
853
854---
855 appveyor.yml | 1 +
856 src/gevent/libuv/_corecffi_source.c | 16 +++++++++-------
857 2 files changed, 10 insertions(+), 7 deletions(-)
858
859#diff --git a/appveyor.yml b/appveyor.yml
860#index 3e5f84f78..ee660e472 100644
861#--- a/appveyor.yml
862#+++ b/appveyor.yml
863#@@ -11,6 +11,7 @@ environment:
864# # too often we get failures to resolve DNS names or failures
865# # to connect on AppVeyor.
866# GEVENTTEST_USE_RESOURCES: "-network"
867#+ PYTHONTRACEMALLOC: 10
868#
869# matrix:
870#
871diff --git a/src/gevent/libuv/_corecffi_source.c b/src/gevent/libuv/_corecffi_source.c
872index 83fe82ee9..3b4b8d156 100644
873--- a/src/gevent/libuv/_corecffi_source.c
874+++ b/src/gevent/libuv/_corecffi_source.c
875@@ -150,32 +150,34 @@ static void _gevent_fs_poll_callback3(void* handlep, int status, const uv_stat_t
876
877 static void gevent_uv_walk_callback_close(uv_handle_t* handle, void* arg)
878 {
879- if( handle && !uv_is_closing(handle) ) {
880- uv_close(handle, NULL);
881- }
882+ if( handle && !uv_is_closing(handle) ) {
883+ uv_close(handle, NULL);
884+ }
885 }
886
887 static void gevent_close_all_handles(uv_loop_t* loop)
888 {
889+ if (loop) {
890 uv_walk(loop, gevent_uv_walk_callback_close, NULL);
891+ }
892 }
893
894 static void gevent_zero_timer(uv_timer_t* handle)
895 {
896- memset(handle, 0, sizeof(uv_timer_t));
897+ memset(handle, 0, sizeof(uv_timer_t));
898 }
899
900 static void gevent_zero_check(uv_check_t* handle)
901 {
902- memset(handle, 0, sizeof(uv_check_t));
903+ memset(handle, 0, sizeof(uv_check_t));
904 }
905
906 static void gevent_zero_prepare(uv_prepare_t* handle)
907 {
908- memset(handle, 0, sizeof(uv_prepare_t));
909+ memset(handle, 0, sizeof(uv_prepare_t));
910 }
911
912 static void gevent_zero_loop(uv_loop_t* handle)
913 {
914- memset(handle, 0, sizeof(uv_loop_t));
915+ memset(handle, 0, sizeof(uv_loop_t));
916 }
917
918From e52ac513ef66dba47f5312f1870fe2e5b020cb19 Mon Sep 17 00:00:00 2001
919From: Jason Madden <jamadden@gmail.com>
920Date: Sat, 7 Sep 2019 07:44:37 -0500
921Subject: [PATCH 7/9] Disable that failing test on 3.8b4 for now.
922
923---
924 src/gevent/tests/test__core.py | 7 +++++++
925 src/gevent/tests/test__socket.py | 21 ++++++++++-----------
926 2 files changed, 17 insertions(+), 11 deletions(-)
927
928diff --git a/src/gevent/tests/test__core.py b/src/gevent/tests/test__core.py
929index 1816e0f89..c538ee7aa 100644
930--- a/src/gevent/tests/test__core.py
931+++ b/src/gevent/tests/test__core.py
932@@ -2,6 +2,7 @@
933 from __future__ import absolute_import, print_function, division
934
935 import unittest
936+import sys
937 import gevent.testing as greentest
938
939 from gevent import core
940@@ -128,6 +129,12 @@ def destroyOne(self, loop):
941 "See https://ci.appveyor.com/project/denik/gevent/build/1.0.1380/job/lrlvid6mkjtyrhn5#L1103 "
942 "It has also timed out, but only on Appveyor CPython 3.6; local CPython 3.6 does not. "
943 "See https://ci.appveyor.com/project/denik/gevent/build/1.0.1414/job/yn7yi8b53vtqs8lw#L1523")
944+@greentest.skipIf(
945+ greentest.LIBUV and greentest.RUNNING_ON_TRAVIS and sys.version_info == (3, 8, 0, 'beta', 4),
946+ "Crashes on 3.8.0b4 on TravisCI. "
947+ "(https://travis-ci.org/gevent/gevent/jobs/582031266#L215) "
948+ "Unable to reproduce locally so far on macOS."
949+)
950 class TestWatchersDefaultDestroyed(TestWatchers):
951
952 def _makeOne(self):
953#diff --git a/src/gevent/tests/test__socket.py b/src/gevent/tests/test__socket.py
954#index 48f6ee3ed..4a670cdb0 100644
955#--- a/src/gevent/tests/test__socket.py
956#+++ b/src/gevent/tests/test__socket.py
957#@@ -3,15 +3,15 @@
958# from gevent import monkey; monkey.patch_all()
959#
960# import sys
961#-import os
962# import array
963# import socket
964#-import traceback
965# import time
966# import unittest
967#-import gevent.testing as greentest
968# from functools import wraps
969#
970#+from gevent import get_hub
971#+import gevent.testing as greentest
972#+
973# from gevent.testing import six
974# from gevent.testing import LARGE_TIMEOUT
975# from gevent.testing import support
976#@@ -34,8 +34,7 @@ def errors_are_fatal(*args, **kwargs):
977# try:
978# return target(*args, **kwargs)
979# except: # pylint:disable=bare-except
980#- traceback.print_exc()
981#- os._exit(2)
982#+ get_hub().throw(*sys.exc_info())
983#
984# _Thread.__init__(self, target=errors_are_fatal, **kwargs)
985# self.start()
986#@@ -91,18 +90,17 @@ def _test_sendall(self, data, match_data=None, client_method='sendall',
987#
988# def accept_and_read():
989# conn = None
990#+ r = None
991# try:
992# conn, _ = self.listener.accept()
993# r = conn.makefile(mode='rb')
994# read_data.append(r.read())
995# r.flush()
996# r.close()
997#- except: # pylint:disable=bare-except
998#- server_exc_info.append(sys.exc_info())
999# finally:
1000#- if conn:
1001#- conn.close()
1002#- self.listener.close()
1003#+ for f in (conn, r, self.listener):
1004#+ if f is not None:
1005#+ f.close()
1006#
1007# server = Thread(target=accept_and_read)
1008# client = self.create_connection(**client_args)
1009#@@ -114,9 +112,10 @@ def accept_and_read():
1010# client.close()
1011#
1012# server.join()
1013#+ assert not server.is_alive()
1014# if match_data is None:
1015# match_data = self.long_data
1016#- self.assertEqual(read_data[0], match_data)
1017#+ self.assertEqual(read_data, [match_data])
1018#
1019# if server_exc_info:
1020# six.reraise(*server_exc_info[0])
1021#
1022From 271e58658f7cc839dcde74239c66d1d396d675b7 Mon Sep 17 00:00:00 2001
1023From: Jason Madden <jamadden@gmail.com>
1024Date: Sat, 7 Sep 2019 09:02:12 -0500
1025Subject: [PATCH 8/9] Whoops, fix Python 2.
1026
1027---
1028 src/gevent/tests/test__greenness.py | 23 +++++++++++++----------
1029 src/gevent/tests/test__socket.py | 13 ++++++++-----
1030 src/gevent/tests/test__ssl.py | 3 ++-
1031 3 files changed, 23 insertions(+), 16 deletions(-)
1032
1033diff --git a/src/gevent/tests/test__greenness.py b/src/gevent/tests/test__greenness.py
1034index da4fc948e..71392971f 100644
1035--- a/src/gevent/tests/test__greenness.py
1036+++ b/src/gevent/tests/test__greenness.py
1037@@ -29,13 +29,15 @@
1038 import gevent.testing as greentest
1039
1040 try:
1041- import urllib2
1042-except ImportError:
1043 from urllib import request as urllib2
1044-try:
1045- import BaseHTTPServer
1046-except ImportError:
1047 from http import server as BaseHTTPServer
1048+ from http.server import SimpleHTTPRequestHandler
1049+except ImportError:
1050+ # Python 2
1051+ import urllib2
1052+ import BaseHTTPServer
1053+ from SimpleHTTPServer import SimpleHTTPRequestHandler
1054+
1055
1056 import gevent
1057 from gevent.testing import params
1058@@ -47,7 +49,8 @@ class TestGreenness(greentest.TestCase):
1059 def setUp(self):
1060 server_address = params.DEFAULT_BIND_ADDR_TUPLE
1061 BaseHTTPServer.BaseHTTPRequestHandler.protocol_version = "HTTP/1.0"
1062- self.httpd = BaseHTTPServer.HTTPServer(server_address, BaseHTTPServer.BaseHTTPRequestHandler)
1063+ self.httpd = BaseHTTPServer.HTTPServer(server_address,
1064+ SimpleHTTPRequestHandler)
1065 self.httpd.request_count = 0
1066
1067 def tearDown(self):
1068@@ -62,10 +65,10 @@ def test_urllib2(self):
1069 server = gevent.spawn(self.serve)
1070
1071 port = self.httpd.socket.getsockname()[1]
1072- with self.assertRaises(urllib2.HTTPError) as exc:
1073- urllib2.urlopen('http://127.0.0.1:%s' % port)
1074- self.assertEqual(exc.exception.code, 501)
1075- server.get(0.01)
1076+ rsp = urllib2.urlopen('http://127.0.0.1:%s' % port)
1077+ rsp.read()
1078+ rsp.close()
1079+ server.join()
1080 self.assertEqual(self.httpd.request_count, 1)
1081
1082
1083#diff --git a/src/gevent/tests/test__socket.py b/src/gevent/tests/test__socket.py
1084#index 4a670cdb0..195ef1af5 100644
1085#--- a/src/gevent/tests/test__socket.py
1086#+++ b/src/gevent/tests/test__socket.py
1087#@@ -9,7 +9,7 @@
1088# import unittest
1089# from functools import wraps
1090#
1091#-from gevent import get_hub
1092#+from gevent import getcurrent
1093# import gevent.testing as greentest
1094#
1095# from gevent.testing import six
1096#@@ -34,7 +34,7 @@ def errors_are_fatal(*args, **kwargs):
1097# try:
1098# return target(*args, **kwargs)
1099# except: # pylint:disable=bare-except
1100#- get_hub().throw(*sys.exc_info())
1101#+ getcurrent().parent.throw(*sys.exc_info())
1102#
1103# _Thread.__init__(self, target=errors_are_fatal, **kwargs)
1104# self.start()
1105#@@ -95,13 +95,16 @@ def accept_and_read():
1106# conn, _ = self.listener.accept()
1107# r = conn.makefile(mode='rb')
1108# read_data.append(r.read())
1109#- r.flush()
1110#- r.close()
1111# finally:
1112#- for f in (conn, r, self.listener):
1113#+ # Order matters. On Python 2, if we close the
1114#+ # connection before closing the makefile,
1115#+ # test__ssl fails because the underlying socket
1116#+ # has been deleted.
1117#+ for f in (r, conn, self.listener):
1118# if f is not None:
1119# f.close()
1120#
1121#+
1122# server = Thread(target=accept_and_read)
1123# client = self.create_connection(**client_args)
1124#
1125#diff --git a/src/gevent/tests/test__ssl.py b/src/gevent/tests/test__ssl.py
1126#index 97b70bd98..537e70773 100644
1127#--- a/src/gevent/tests/test__ssl.py
1128#+++ b/src/gevent/tests/test__ssl.py
1129#@@ -1,3 +1,4 @@
1130#+from __future__ import print_function, division, absolute_import
1131# from gevent import monkey; monkey.patch_all()
1132# import os
1133#
1134#@@ -5,7 +6,7 @@
1135# import gevent.testing as greentest
1136# # Be careful not to have TestTCP as a bare attribute in this module,
1137# # even aliased, to avoid running duplicate tests
1138#-import test__socket
1139#+from gevent.tests import test__socket
1140# import ssl
1141#
1142#
1143#
1144From 158ccf26ff07af1c0737307f67ed118e7a1d6ac1 Mon Sep 17 00:00:00 2001
1145From: Jason Madden <jamadden@gmail.com>
1146Date: Sat, 7 Sep 2019 09:27:19 -0500
1147Subject: [PATCH 9/9] Implement verify_client_post_handshake; appveyor has TLS
1148 1.3 now so those tests are running there.
1149
1150---
1151 CHANGES.rst | 2 ++
1152 src/gevent/_ssl3.py | 5 +++++
1153 src/gevent/tests/known_failures.py | 9 +++++++++
1154 src/gevent/tests/test__socket.py | 3 ++-
1155 4 files changed, 18 insertions(+), 1 deletion(-)
1156
1157#diff --git a/CHANGES.rst b/CHANGES.rst
1158#index 53f4398d2..a4ab7a7ab 100644
1159#--- a/CHANGES.rst
1160#+++ b/CHANGES.rst
1161#@@ -16,6 +16,8 @@
1162#
1163# - Improve the way joining the main thread works on Python 3.
1164#
1165#+- Implement ``SSLSocket.verify_client_post_handshake()`` when available.
1166#+
1167# 1.5a1 (2019-05-02)
1168# ==================
1169#
1170diff --git a/src/gevent/_ssl3.py b/src/gevent/_ssl3.py
1171index d3de81034..29988cff0 100644
1172--- a/src/gevent/_ssl3.py
1173+++ b/src/gevent/_ssl3.py
1174@@ -678,6 +678,11 @@ def get_channel_binding(self, cb_type="tls-unique"):
1175 return None
1176 return self._sslobj.tls_unique_cb()
1177
1178+ def verify_client_post_handshake(self):
1179+ # Only present in 3.7.1+; an attributeerror is alright
1180+ if self._sslobj:
1181+ return self._sslobj.verify_client_post_handshake()
1182+ raise ValueError("No SSL wrapper around " + str(self))
1183
1184 # Python does not support forward declaration of types
1185 SSLContext.sslsocket_class = SSLSocket
1186diff --git a/src/gevent/tests/known_failures.py b/src/gevent/tests/known_failures.py
1187index eb1db0da1..d5f38ba91 100644
1188--- a/src/gevent/tests/known_failures.py
1189+++ b/src/gevent/tests/known_failures.py
1190@@ -351,6 +351,15 @@
1191 'test__example_webproxy.py',
1192 ]
1193
1194+if APPVEYOR:
1195+ # Strange failures sometimes, but only on Python 3.7, reporting
1196+ # "ConnectionAbortedError: [WinError 10053] An established
1197+ # connection was aborted by the software in your host machine"
1198+ # when we've done no such thing. Try running not in parallel
1199+ RUN_ALONE += [
1200+ 'test__ssl.py',
1201+ 'test__server.py',
1202+ ]
1203
1204
1205 if APPVEYOR or TRAVIS:
1206#diff --git a/src/gevent/tests/test__socket.py b/src/gevent/tests/test__socket.py
1207#index 195ef1af5..4976d5767 100644
1208#--- a/src/gevent/tests/test__socket.py
1209#+++ b/src/gevent/tests/test__socket.py
1210#@@ -29,12 +29,13 @@ class Thread(_Thread):
1211#
1212# def __init__(self, **kwargs):
1213# target = kwargs.pop('target')
1214#+ caller = getcurrent()
1215# @wraps(target)
1216# def errors_are_fatal(*args, **kwargs):
1217# try:
1218# return target(*args, **kwargs)
1219# except: # pylint:disable=bare-except
1220#- getcurrent().parent.throw(*sys.exc_info())
1221#+ caller.throw(*sys.exc_info())
1222#
1223# _Thread.__init__(self, target=errors_are_fatal, **kwargs)
1224# self.start()
1225--- gevent-1.4.0/src/gevent/thread.py.orig 2019-01-04 12:51:44.000000000 +0100
1226+++ gevent-1.4.0/src/gevent/thread.py 2020-01-03 21:14:08.922889769 +0100
1227@@ -31,6 +31,8 @@
1228 'exit_thread',
1229 'interrupt_main',
1230 'start_new']
1231+ if sys.version_info[:2] >= (3, 8):
1232+ __imports__.append('get_native_id')
1233 error = __thread__.error
1234 from gevent._compat import PY3
1235 from gevent._compat import PYPY
1236--- gevent-1.4.0/src/gevent/_tblib.py.orig 2019-01-04 12:51:44.000000000 +0100
1237+++ gevent-1.4.0/src/gevent/_tblib.py 2020-01-03 21:25:28.152543399 +0100
1238@@ -198,6 +198,9 @@
1239 while current:
1240 f_code = current.tb_frame.f_code
1241 code = compile('\n' * (current.tb_lineno - 1) + 'raise __traceback_maker', current.tb_frame.f_code.co_filename, 'exec')
1242- if PY3:
1243+ if hasattr(code, "replace"):
1244+ # Python 3.8 and newer
1245+ code = code.replace(co_argcount=0, co_freevars=(), co_cellvars=())
1246+ elif PY3:
1247 code = CodeType(
1248 0, code.co_kwonlyargcount,
1249--- gevent-1.4.0/src/gevent/_socketcommon.py.orig 2019-01-04 12:51:44.000000000 +0100
1250+++ gevent-1.4.0/src/gevent/_socketcommon.py 2020-01-06 15:00:51.236688228 +0100
1251@@ -74,6 +74,12 @@
1252 from gevent._compat import string_types, integer_types, PY3
1253 from gevent._util import copy_globals
1254
1255+if sys.version_info[:2] >= (3, 8):
1256+ __imports__.extend([
1257+ 'create_server',
1258+ 'has_dualstack_ipv6'
1259+ ])
1260+
1261 is_windows = sys.platform == 'win32'
1262 is_macos = sys.platform == 'darwin'
1263
This page took 0.295996 seconds and 4 git commands to generate.