]> git.pld-linux.org Git - packages/python-gevent.git/blame_incremental - python-gevent-py3.8.patch
- rel 2; rediff patches
[packages/python-gevent.git] / python-gevent-py3.8.patch
... / ...
CommitLineData
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 -urNp -x '*.orig' gevent-1.4.0.org/examples/webproxy.py gevent-1.4.0/examples/webproxy.py
82--- gevent-1.4.0.org/examples/webproxy.py 2019-01-04 12:51:44.000000000 +0100
83+++ gevent-1.4.0/examples/webproxy.py 2021-03-05 09:44:15.299051013 +0100
84@@ -15,7 +15,12 @@ from gevent import monkey; monkey.patch_
85 import sys
86 import re
87 import traceback
88-from cgi import escape
89+
90+try:
91+ from cgi import escape
92+except ImportError:
93+ # Python 3.8 removed this API
94+ from html import escape
95
96 try:
97 import urllib2
98diff -urNp -x '*.orig' gevent-1.4.0.org/src/gevent/__semaphore.pxd gevent-1.4.0/src/gevent/__semaphore.pxd
99--- gevent-1.4.0.org/src/gevent/__semaphore.pxd 2019-01-04 12:51:44.000000000 +0100
100+++ gevent-1.4.0/src/gevent/__semaphore.pxd 2021-03-05 09:44:15.299051013 +0100
101@@ -13,7 +13,7 @@ cdef class Semaphore(AbstractLinkable):
102 # threadpool uses it
103 cpdef _start_notify(self)
104 cpdef int wait(self, object timeout=*) except -1000
105- cpdef bint acquire(self, int blocking=*, object timeout=*) except -1000
106+ cpdef bint acquire(self, bint blocking=*, object timeout=*) except -1000
107 cpdef __enter__(self)
108 cpdef __exit__(self, object t, object v, object tb)
109
110diff -urNp -x '*.orig' gevent-1.4.0.org/src/gevent/_compat.py gevent-1.4.0/src/gevent/_compat.py
111--- gevent-1.4.0.org/src/gevent/_compat.py 2019-01-04 12:51:44.000000000 +0100
112+++ gevent-1.4.0/src/gevent/_compat.py 2021-03-05 09:44:15.299051013 +0100
113@@ -14,7 +14,7 @@ PY3 = sys.version_info[0] >= 3
114 PYPY = hasattr(sys, 'pypy_version_info')
115 WIN = sys.platform.startswith("win")
116 LINUX = sys.platform.startswith('linux')
117-OSX = sys.platform == 'darwin'
118+OSX = MAC = sys.platform == 'darwin'
119
120
121 PURE_PYTHON = PYPY or os.getenv('PURE_PYTHON')
122diff -urNp -x '*.orig' gevent-1.4.0.org/src/gevent/_socket2.py gevent-1.4.0/src/gevent/_socket2.py
123--- gevent-1.4.0.org/src/gevent/_socket2.py 2019-01-04 12:51:44.000000000 +0100
124+++ gevent-1.4.0/src/gevent/_socket2.py 2021-03-05 09:44:15.299051013 +0100
125@@ -6,6 +6,7 @@ from __future__ import absolute_import
126
127 # Our import magic sadly makes this warning useless
128 # pylint: disable=undefined-variable
129+import sys
130
131 from gevent import _socketcommon
132 from gevent._util import copy_globals
133diff -urNp -x '*.orig' gevent-1.4.0.org/src/gevent/_socketcommon.py gevent-1.4.0/src/gevent/_socketcommon.py
134--- gevent-1.4.0.org/src/gevent/_socketcommon.py 2019-01-04 12:51:44.000000000 +0100
135+++ gevent-1.4.0/src/gevent/_socketcommon.py 2021-03-05 09:44:15.302384451 +0100
136@@ -74,6 +74,12 @@ from gevent._hub_local import get_hub_no
137 from gevent._compat import string_types, integer_types, PY3
138 from gevent._util import copy_globals
139
140+if sys.version_info[:2] >= (3, 8):
141+ __imports__.extend([
142+ 'create_server',
143+ 'has_dualstack_ipv6'
144+ ])
145+
146 is_windows = sys.platform == 'win32'
147 is_macos = sys.platform == 'darwin'
148
149diff -urNp -x '*.orig' gevent-1.4.0.org/src/gevent/_ssl3.py gevent-1.4.0/src/gevent/_ssl3.py
150--- gevent-1.4.0.org/src/gevent/_ssl3.py 2019-01-04 12:51:44.000000000 +0100
151+++ gevent-1.4.0/src/gevent/_ssl3.py 2021-03-05 09:44:15.299051013 +0100
152@@ -667,6 +667,11 @@ class SSLSocket(socket):
153 return None
154 return self._sslobj.tls_unique_cb()
155
156+ def verify_client_post_handshake(self):
157+ # Only present in 3.7.1+; an attributeerror is alright
158+ if self._sslobj:
159+ return self._sslobj.verify_client_post_handshake()
160+ raise ValueError("No SSL wrapper around " + str(self))
161
162 # Python does not support forward declaration of types
163 SSLContext.sslsocket_class = SSLSocket
164diff -urNp -x '*.orig' gevent-1.4.0.org/src/gevent/_tblib.py gevent-1.4.0/src/gevent/_tblib.py
165--- gevent-1.4.0.org/src/gevent/_tblib.py 2019-01-04 12:51:44.000000000 +0100
166+++ gevent-1.4.0/src/gevent/_tblib.py 2021-03-05 09:44:15.302384451 +0100
167@@ -198,7 +198,10 @@ class Traceback(object):
168 while current:
169 f_code = current.tb_frame.f_code
170 code = compile('\n' * (current.tb_lineno - 1) + 'raise __traceback_maker', current.tb_frame.f_code.co_filename, 'exec')
171- if PY3:
172+ if hasattr(code, "replace"):
173+ # Python 3.8 and newer
174+ code = code.replace(co_argcount=0, co_freevars=(), co_cellvars=())
175+ elif PY3:
176 code = CodeType(
177 0, code.co_kwonlyargcount,
178 code.co_nlocals, code.co_stacksize, code.co_flags,
179diff -urNp -x '*.orig' gevent-1.4.0.org/src/gevent/libuv/_corecffi_source.c gevent-1.4.0/src/gevent/libuv/_corecffi_source.c
180--- gevent-1.4.0.org/src/gevent/libuv/_corecffi_source.c 2019-01-04 12:51:44.000000000 +0100
181+++ gevent-1.4.0/src/gevent/libuv/_corecffi_source.c 2021-03-05 09:44:15.299051013 +0100
182@@ -150,32 +150,34 @@ static void _gevent_fs_poll_callback3(vo
183
184 static void gevent_uv_walk_callback_close(uv_handle_t* handle, void* arg)
185 {
186- if( handle && !uv_is_closing(handle) ) {
187- uv_close(handle, NULL);
188- }
189+ if( handle && !uv_is_closing(handle) ) {
190+ uv_close(handle, NULL);
191+ }
192 }
193
194 static void gevent_close_all_handles(uv_loop_t* loop)
195 {
196+ if (loop) {
197 uv_walk(loop, gevent_uv_walk_callback_close, NULL);
198+ }
199 }
200
201 static void gevent_zero_timer(uv_timer_t* handle)
202 {
203- memset(handle, 0, sizeof(uv_timer_t));
204+ memset(handle, 0, sizeof(uv_timer_t));
205 }
206
207 static void gevent_zero_check(uv_check_t* handle)
208 {
209- memset(handle, 0, sizeof(uv_check_t));
210+ memset(handle, 0, sizeof(uv_check_t));
211 }
212
213 static void gevent_zero_prepare(uv_prepare_t* handle)
214 {
215- memset(handle, 0, sizeof(uv_prepare_t));
216+ memset(handle, 0, sizeof(uv_prepare_t));
217 }
218
219 static void gevent_zero_loop(uv_loop_t* handle)
220 {
221- memset(handle, 0, sizeof(uv_loop_t));
222+ memset(handle, 0, sizeof(uv_loop_t));
223 }
224diff -urNp -x '*.orig' gevent-1.4.0.org/src/gevent/monkey.py gevent-1.4.0/src/gevent/monkey.py
225--- gevent-1.4.0.org/src/gevent/monkey.py 2019-01-04 12:51:44.000000000 +0100
226+++ gevent-1.4.0/src/gevent/monkey.py 2021-03-05 09:44:15.299051013 +0100
227@@ -614,6 +614,22 @@ def patch_thread(threading=True, _thread
228 raise RuntimeError("Cannot join current thread")
229 if thread_greenlet is not None and thread_greenlet.dead:
230 return
231+ # You may ask: Why not call thread_greenlet.join()?
232+ # Well, in the one case we actually have a greenlet, it's the
233+ # low-level greenlet.greenlet object for the main thread, which
234+ # doesn't have a join method.
235+ #
236+ # You may ask: Why not become the main greenlet's *parent*
237+ # so you can get notified when it finishes? Because you can't
238+ # create a greenlet cycle (the current greenlet is a descendent
239+ # of the parent), and nor can you set a greenlet's parent to None,
240+ # so there can only ever be one greenlet with a parent of None: the main
241+ # greenlet, the one we need to watch.
242+ #
243+ # You may ask: why not swizzle out the problematic lock on the main thread
244+ # into a gevent friendly lock? Well, the interpreter actually depends on that
245+ # for the main thread in threading._shutdown; see below.
246+
247 if not thread.is_alive():
248 return
249
250@@ -646,8 +662,34 @@ def patch_thread(threading=True, _thread
251 if orig_current_thread == threading_mod.main_thread():
252 main_thread = threading_mod.main_thread()
253 _greenlet = main_thread._greenlet = greenlet.getcurrent()
254+ main_thread.__real_tstate_lock = main_thread._tstate_lock
255+
256+ # The interpreter will call threading._shutdown
257+ # when the main thread exits and is about to
258+ # go away. It is called *in* the main thread. This
259+ # is a perfect place to notify other greenlets that
260+ # the main thread is done. We do this by overriding the
261+ # lock of the main thread during operation, and only restoring
262+ # it to the native blocking version at shutdown time
263+ # (the interpreter also has a reference to this lock in a
264+ # C data structure).
265+ main_thread._tstate_lock = threading_mod.Lock()
266+ main_thread._tstate_lock.acquire()
267+ orig_shutdown = threading_mod._shutdown
268+ def _shutdown():
269+ # Release anyone trying to join() me,
270+ # and let us switch to them.
271+ if main_thread._tstate_lock:
272+ main_thread._tstate_lock.release()
273+ from gevent import sleep
274+ sleep()
275+ # The only truly blocking native shutdown lock to
276+ # acquire should be our own (hopefully)
277+ main_thread._tstate_lock = main_thread.__real_tstate_lock
278+ main_thread.__real_tstate_lock = None
279+ orig_shutdown()
280
281- main_thread.join = make_join_func(main_thread, _greenlet)
282+ threading_mod._shutdown = _shutdown
283
284 # Patch up the ident of the main thread to match. This
285 # matters if threading was imported before monkey-patching
286diff -urNp -x '*.orig' gevent-1.4.0.org/src/gevent/os.py gevent-1.4.0/src/gevent/os.py
287--- gevent-1.4.0.org/src/gevent/os.py 2019-01-04 12:51:44.000000000 +0100
288+++ gevent-1.4.0/src/gevent/os.py 2021-03-05 09:44:15.299051013 +0100
289@@ -385,6 +385,12 @@ if hasattr(os, 'fork'):
290 # we're not watching it
291 return _waitpid(pid, options)
292
293+ def _watch_child(pid, callback=None, loop=None, ref=False):
294+ loop = loop or get_hub().loop
295+ watcher = loop.child(pid, ref=ref)
296+ _watched_children[pid] = watcher
297+ watcher.start(_on_child, watcher, callback)
298+
299 def fork_and_watch(callback=None, loop=None, ref=False, fork=fork_gevent):
300 """
301 Fork a child process and start a child watcher for it in the parent process.
302@@ -413,10 +419,7 @@ if hasattr(os, 'fork'):
303 pid = fork()
304 if pid:
305 # parent
306- loop = loop or get_hub().loop
307- watcher = loop.child(pid, ref=ref)
308- _watched_children[pid] = watcher
309- watcher.start(_on_child, watcher, callback)
310+ _watch_child(pid, callback, loop, ref)
311 return pid
312
313 __extensions__.append('fork_and_watch')
314@@ -474,6 +477,23 @@ if hasattr(os, 'fork'):
315 # take any args to match fork_and_watch
316 return forkpty_and_watch(*args, **kwargs)
317 __implements__.append("waitpid")
318+
319+ if hasattr(os, 'posix_spawn'):
320+ _raw_posix_spawn = os.posix_spawn
321+ _raw_posix_spawnp = os.posix_spawnp
322+
323+ def posix_spawn(*args, **kwargs):
324+ pid = _raw_posix_spawn(*args, **kwargs)
325+ _watch_child(pid)
326+ return pid
327+
328+ def posix_spawnp(*args, **kwargs):
329+ pid = _raw_posix_spawnp(*args, **kwargs)
330+ _watch_child(pid)
331+ return pid
332+
333+ __implements__.append("posix_spawn")
334+ __implements__.append("posix_spawnp")
335 else:
336 def fork():
337 """
338@@ -503,6 +523,7 @@ if hasattr(os, 'fork'):
339 else:
340 __implements__.remove('fork')
341
342+
343 __imports__ = copy_globals(os, globals(),
344 names_to_ignore=__implements__ + __extensions__,
345 dunder_names_to_keep=())
346diff -urNp -x '*.orig' gevent-1.4.0.org/src/gevent/testing/testrunner.py gevent-1.4.0/src/gevent/testing/testrunner.py
347--- gevent-1.4.0.org/src/gevent/testing/testrunner.py 2019-01-04 12:51:44.000000000 +0100
348+++ gevent-1.4.0/src/gevent/testing/testrunner.py 2021-03-05 09:44:15.299051013 +0100
349@@ -381,17 +381,26 @@ def _setup_environ(debug=False):
350 if 'GEVENT_DEBUG' not in os.environ and debug:
351 os.environ['GEVENT_DEBUG'] = 'debug'
352
353- if 'PYTHONTRACEMALLOC' not in os.environ:
354+ if 'PYTHONTRACEMALLOC' not in os.environ and debug:
355+ # This slows the tests down quite a bit. Reserve
356+ # for debugging.
357 os.environ['PYTHONTRACEMALLOC'] = '10'
358
359 if 'PYTHONDEVMODE' not in os.environ:
360- # Python 3.7
361+ # Python 3.7 and above.
362 os.environ['PYTHONDEVMODE'] = '1'
363
364- if 'PYTHONMALLOC' not in os.environ:
365- # Python 3.6
366+ if 'PYTHONMALLOC' not in os.environ and debug:
367+ # Python 3.6 and above.
368+ # This slows the tests down some, but
369+ # can detect memory corruption. Unfortunately
370+ # it can also be flaky, especially in pre-release
371+ # versions of Python (e.g., lots of crashes on Python 3.8b4).
372 os.environ['PYTHONMALLOC'] = 'debug'
373
374+ if sys.version_info.releaselevel != 'final' and not debug:
375+ os.environ['PYTHONMALLOC'] = 'default'
376+ os.environ['PYTHONDEVMODE'] = ''
377
378
379 def main():
380diff -urNp -x '*.orig' gevent-1.4.0.org/src/gevent/tests/known_failures.py gevent-1.4.0/src/gevent/tests/known_failures.py
381--- gevent-1.4.0.org/src/gevent/tests/known_failures.py 2021-03-05 09:44:15.072377256 +0100
382+++ gevent-1.4.0/src/gevent/tests/known_failures.py 2021-03-05 09:44:15.302384451 +0100
383@@ -610,6 +610,15 @@ RUN_ALONE = [
384 'test__examples.py',
385 ]
386
387+if APPVEYOR:
388+ # Strange failures sometimes, but only on Python 3.7, reporting
389+ # "ConnectionAbortedError: [WinError 10053] An established
390+ # connection was aborted by the software in your host machine"
391+ # when we've done no such thing. Try running not in parallel
392+ RUN_ALONE += [
393+ 'test__ssl.py',
394+ 'test__server.py',
395+ ]
396
397
398 if APPVEYOR or TRAVIS:
399diff -urNp -x '*.orig' gevent-1.4.0.org/src/gevent/tests/test__core.py gevent-1.4.0/src/gevent/tests/test__core.py
400--- gevent-1.4.0.org/src/gevent/tests/test__core.py 2019-01-04 12:51:44.000000000 +0100
401+++ gevent-1.4.0/src/gevent/tests/test__core.py 2021-03-05 09:44:15.299051013 +0100
402@@ -2,6 +2,7 @@
403 from __future__ import absolute_import, print_function, division
404 import sys
405 import unittest
406+import sys
407 import gevent.testing as greentest
408
409 from gevent import core
410@@ -130,6 +131,12 @@ class TestWatchersDefault(TestWatchers):
411 "See https://ci.appveyor.com/project/denik/gevent/build/1.0.1380/job/lrlvid6mkjtyrhn5#L1103 "
412 "It has also timed out, but only on Appveyor CPython 3.6; local CPython 3.6 does not. "
413 "See https://ci.appveyor.com/project/denik/gevent/build/1.0.1414/job/yn7yi8b53vtqs8lw#L1523")
414+@greentest.skipIf(
415+ greentest.LIBUV and greentest.RUNNING_ON_TRAVIS and sys.version_info == (3, 8, 0, 'beta', 4),
416+ "Crashes on 3.8.0b4 on TravisCI. "
417+ "(https://travis-ci.org/gevent/gevent/jobs/582031266#L215) "
418+ "Unable to reproduce locally so far on macOS."
419+)
420 class TestWatchersDefaultDestroyed(TestWatchers):
421
422 def _makeOne(self):
423diff -urNp -x '*.orig' gevent-1.4.0.org/src/gevent/tests/test__core_fork.py gevent-1.4.0/src/gevent/tests/test__core_fork.py
424--- gevent-1.4.0.org/src/gevent/tests/test__core_fork.py 2019-01-04 12:51:44.000000000 +0100
425+++ gevent-1.4.0/src/gevent/tests/test__core_fork.py 2021-03-05 09:44:15.299051013 +0100
426@@ -1,11 +1,12 @@
427 from __future__ import print_function
428 import gevent.monkey
429 gevent.monkey.patch_all()
430-import gevent
431-import os
432
433+import os
434 import multiprocessing
435
436+import gevent
437+
438 hub = gevent.get_hub()
439 pid = os.getpid()
440 newpid = None
441@@ -46,6 +47,7 @@ def test():
442 if __name__ == '__main__':
443 # Must call for Windows to fork properly; the fork can't be in the top-level
444 multiprocessing.freeze_support()
445+
446 # fork watchers weren't firing in multi-threading processes.
447 # This test is designed to prove that they are.
448 # However, it fails on Windows: The fork watcher never runs!
449diff -urNp -x '*.orig' gevent-1.4.0.org/src/gevent/tests/test__greenness.py gevent-1.4.0/src/gevent/tests/test__greenness.py
450--- gevent-1.4.0.org/src/gevent/tests/test__greenness.py 2019-01-04 12:51:44.000000000 +0100
451+++ gevent-1.4.0/src/gevent/tests/test__greenness.py 2021-03-05 09:44:15.299051013 +0100
452@@ -29,13 +29,15 @@ monkey.patch_all()
453 import gevent.testing as greentest
454
455 try:
456- import urllib2
457-except ImportError:
458 from urllib import request as urllib2
459-try:
460- import BaseHTTPServer
461-except ImportError:
462 from http import server as BaseHTTPServer
463+ from http.server import SimpleHTTPRequestHandler
464+except ImportError:
465+ # Python 2
466+ import urllib2
467+ import BaseHTTPServer
468+ from SimpleHTTPServer import SimpleHTTPRequestHandler
469+
470
471 import gevent
472 from gevent.testing import params
473@@ -47,7 +49,8 @@ class TestGreenness(greentest.TestCase):
474 def setUp(self):
475 server_address = params.DEFAULT_BIND_ADDR_TUPLE
476 BaseHTTPServer.BaseHTTPRequestHandler.protocol_version = "HTTP/1.0"
477- self.httpd = BaseHTTPServer.HTTPServer(server_address, BaseHTTPServer.BaseHTTPRequestHandler)
478+ self.httpd = BaseHTTPServer.HTTPServer(server_address,
479+ SimpleHTTPRequestHandler)
480 self.httpd.request_count = 0
481
482 def tearDown(self):
483@@ -62,10 +65,10 @@ class TestGreenness(greentest.TestCase):
484 server = gevent.spawn(self.serve)
485
486 port = self.httpd.socket.getsockname()[1]
487- with self.assertRaises(urllib2.HTTPError) as exc:
488- urllib2.urlopen('http://127.0.0.1:%s' % port)
489- self.assertEqual(exc.exception.code, 501)
490- server.get(0.01)
491+ rsp = urllib2.urlopen('http://127.0.0.1:%s' % port)
492+ rsp.read()
493+ rsp.close()
494+ server.join()
495 self.assertEqual(self.httpd.request_count, 1)
496
497
498diff -urNp -x '*.orig' gevent-1.4.0.org/src/gevent/tests/test__threading_2.py gevent-1.4.0/src/gevent/tests/test__threading_2.py
499--- gevent-1.4.0.org/src/gevent/tests/test__threading_2.py 2019-01-04 12:51:44.000000000 +0100
500+++ gevent-1.4.0/src/gevent/tests/test__threading_2.py 2021-03-05 09:44:15.299051013 +0100
501@@ -33,6 +33,7 @@ try:
502 from test.support import verbose
503 except ImportError:
504 from test.test_support import verbose
505+
506 import random
507 import re
508 import sys
509@@ -46,7 +47,7 @@ import unittest
510 import weakref
511
512 from gevent.tests import lock_tests
513-
514+verbose = False
515 # A trivial mutable counter.
516
517 def skipDueToHang(cls):
518@@ -132,7 +133,7 @@ class ThreadTests(unittest.TestCase):
519 print('waiting for all tasks to complete')
520 for t in threads:
521 t.join(NUMTASKS)
522- self.assertFalse(t.is_alive())
523+ self.assertFalse(t.is_alive(), t.__dict__)
524 if hasattr(t, 'ident'):
525 self.assertNotEqual(t.ident, 0)
526 self.assertFalse(t.ident is None)
527@@ -351,28 +352,33 @@ class ThreadTests(unittest.TestCase):
528 # Issue 1722344
529 # Raising SystemExit skipped threading._shutdown
530 import subprocess
531- p = subprocess.Popen([sys.executable, "-W", "ignore", "-c", """if 1:
532+ script = """if 1:
533 %s
534 import threading
535 from time import sleep
536
537 def child():
538- sleep(1)
539+ sleep(0.3)
540 # As a non-daemon thread we SHOULD wake up and nothing
541 # should be torn down yet
542- print("Woke up, sleep function is: %%r" %% sleep)
543+ print("Woke up, sleep function is: %%s.%%s" %% (sleep.__module__, sleep.__name__))
544
545 threading.Thread(target=child).start()
546 raise SystemExit
547- """ % setup_4],
548+ """ % setup_4
549+ p = subprocess.Popen([sys.executable, "-W", "ignore", "-c", script],
550 stdout=subprocess.PIPE,
551 stderr=subprocess.PIPE)
552 stdout, stderr = p.communicate()
553 stdout = stdout.strip()
554 stdout = stdout.decode('utf-8')
555 stderr = stderr.decode('utf-8')
556- assert re.match('^Woke up, sleep function is: <.*?sleep.*?>$', stdout), repr(stdout)
557- stderr = re.sub(r"^\[\d+ refs\]", "", stderr, re.MULTILINE).strip()
558+
559+
560+ self.assertEqual(
561+ 'Woke up, sleep function is: gevent.hub.sleep',
562+ stdout)
563+
564 # On Python 2, importing pkg_resources tends to result in some 'ImportWarning'
565 # being printed to stderr about packages missing __init__.py; the -W ignore is...
566 # ignored.
567@@ -410,7 +416,7 @@ class ThreadTests(unittest.TestCase):
568 self.should_raise = should_raise
569 self.thread = threading.Thread(target=self._run,
570 args=(self,),
571- kwargs={'yet_another': self})
572+ kwargs={'_yet_another': self})
573 self.thread.start()
574
575 def _run(self, _other_ref, _yet_another):
576@@ -463,7 +469,7 @@ class ThreadJoinOnShutdown(unittest.Test
577 t = threading.Thread(target=joiningfunc,
578 args=(threading.current_thread(),))
579 t.start()
580- time.sleep(0.1)
581+ time.sleep(0.2)
582 print('end of main')
583 """
584 self._run_and_join(script)
585diff -urNp -x '*.orig' gevent-1.4.0.org/src/gevent/thread.py gevent-1.4.0/src/gevent/thread.py
586--- gevent-1.4.0.org/src/gevent/thread.py 2019-01-04 12:51:44.000000000 +0100
587+++ gevent-1.4.0/src/gevent/thread.py 2021-03-05 09:44:15.302384451 +0100
588@@ -31,6 +31,8 @@ else:
589 'exit_thread',
590 'interrupt_main',
591 'start_new']
592+ if sys.version_info[:2] >= (3, 8):
593+ __imports__.append('get_native_id')
594 error = __thread__.error
595 from gevent._compat import PY3
596 from gevent._compat import PYPY
597diff -urNp -x '*.orig' gevent-1.4.0.org/src/gevent/threading.py gevent-1.4.0/src/gevent/threading.py
598--- gevent-1.4.0.org/src/gevent/threading.py 2019-01-04 12:51:44.000000000 +0100
599+++ gevent-1.4.0/src/gevent/threading.py 2021-03-05 09:44:15.299051013 +0100
600@@ -156,41 +156,25 @@ import sys
601 if sys.version_info[:2] >= (3, 4):
602 # XXX: Issue 18808 breaks us on Python 3.4.
603 # Thread objects now expect a callback from the interpreter itself
604- # (threadmodule.c:release_sentinel). Because this never happens
605+ # (threadmodule.c:release_sentinel) when the C-level PyThreadState
606+ # object is being deallocated. Because this never happens
607 # when a greenlet exits, join() and friends will block forever.
608- # The solution below involves capturing the greenlet when it is
609- # started and deferring the known broken methods to it.
610+ # Fortunately this is easy to fix: just ensure that the allocation of the
611+ # lock, _set_sentinel, creates a *gevent* lock, and release it when
612+ # we're done. The main _shutdown code is in Python and deals with
613+ # this gracefully.
614
615 class Thread(__threading__.Thread):
616- _greenlet = None
617-
618- def is_alive(self):
619- return bool(self._greenlet)
620-
621- isAlive = is_alive
622
623 def _set_tstate_lock(self):
624- self._greenlet = getcurrent()
625-
626- def run(self):
627- try:
628- super(Thread, self).run()
629- finally:
630- # avoid ref cycles, but keep in __dict__ so we can
631- # distinguish the started/never-started case
632- self._greenlet = None
633- self._stop() # mark as finished
634-
635- def join(self, timeout=None):
636- if '_greenlet' not in self.__dict__:
637- raise RuntimeError("Cannot join an inactive thread")
638- if self._greenlet is None:
639- return
640- self._greenlet.join(timeout=timeout)
641-
642- def _wait_for_tstate_lock(self, *args, **kwargs):
643- # pylint:disable=arguments-differ
644- raise NotImplementedError()
645+ super(Thread, self)._set_tstate_lock()
646+ greenlet = getcurrent()
647+ greenlet.rawlink(self.__greenlet_finished)
648+
649+ def __greenlet_finished(self, _):
650+ if self._tstate_lock:
651+ self._tstate_lock.release()
652+ self._stop()
653
654 __implements__.append('Thread')
655
656@@ -199,6 +183,8 @@ if sys.version_info[:2] >= (3, 4):
657
658 __implements__.append('Timer')
659
660+ _set_sentinel = allocate_lock
661+ __implements__.append('_set_sentinel')
662 # The main thread is patched up with more care
663 # in _gevent_will_monkey_patch
664
This page took 0.047164 seconds and 4 git commands to generate.