]> git.pld-linux.org Git - packages/python-gevent.git/blob - python-gevent-py3.8.patch
- rel 2; rediff patches
[packages/python-gevent.git] / python-gevent-py3.8.patch
1 Based on https://github.com/gevent/gevent/commit/8224e81425762ad21d3b63ffb9cc0a0c2d789704.patch
2 and https://src.fedoraproject.org/rpms/python-gevent/raw/master/f/0001-code-replace.patch
3
4 From e6e2959184909c6292e0135b709282cd5f96065b Mon Sep 17 00:00:00 2001
5 From: Jason Madden <jamadden@gmail.com>
6 Date: Fri, 6 Sep 2019 16:29:58 -0500
7 Subject: [PATCH 1/9] Basic support for CPython 3.8.0b4.
8
9 Still 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
81 diff -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
98 diff -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  
110 diff -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')
122 diff -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
133 diff -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  
149 diff -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
164 diff -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,
179 diff -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  }
224 diff -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
286 diff -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=())
346 diff -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():
380 diff -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:
399 diff -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):
423 diff -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!
449 diff -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  
498 diff -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)
585 diff -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
597 diff -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.114355 seconds and 4 git commands to generate.