Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gevent
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
gevent
Commits
d9e2479b
Commit
d9e2479b
authored
Jul 07, 2023
by
Jason Madden
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
More removal of obsolete code.
parent
07035b7e
Changes
31
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
31 changed files
with
437 additions
and
813 deletions
+437
-813
setup.py
setup.py
+2
-0
src/gevent/_compat.py
src/gevent/_compat.py
+35
-155
src/gevent/_fileobjectcommon.py
src/gevent/_fileobjectcommon.py
+6
-13
src/gevent/_patcher.py
src/gevent/_patcher.py
+6
-9
src/gevent/_socketcommon.py
src/gevent/_socketcommon.py
+7
-1
src/gevent/_ssl3.py
src/gevent/_ssl3.py
+12
-30
src/gevent/_threading.py
src/gevent/_threading.py
+4
-17
src/gevent/backdoor.py
src/gevent/backdoor.py
+6
-9
src/gevent/builtins.py
src/gevent/builtins.py
+6
-19
src/gevent/contextvars.py
src/gevent/contextvars.py
+2
-2
src/gevent/events.py
src/gevent/events.py
+1
-1
src/gevent/local.py
src/gevent/local.py
+1
-15
src/gevent/lock.py
src/gevent/lock.py
+1
-3
src/gevent/monkey.py
src/gevent/monkey.py
+107
-151
src/gevent/os.py
src/gevent/os.py
+0
-5
src/gevent/pywsgi.py
src/gevent/pywsgi.py
+16
-31
src/gevent/resolver/__init__.py
src/gevent/resolver/__init__.py
+1
-2
src/gevent/server.py
src/gevent/server.py
+19
-42
src/gevent/socket.py
src/gevent/socket.py
+4
-5
src/gevent/ssl.py
src/gevent/ssl.py
+3
-22
src/gevent/subprocess.py
src/gevent/subprocess.py
+137
-186
src/gevent/testing/__init__.py
src/gevent/testing/__init__.py
+0
-1
src/gevent/testing/skipping.py
src/gevent/testing/skipping.py
+0
-1
src/gevent/tests/test__fileobject.py
src/gevent/tests/test__fileobject.py
+6
-16
src/gevent/tests/test__issue1864.py
src/gevent/tests/test__issue1864.py
+1
-3
src/gevent/tests/test__monkey_module_run.py
src/gevent/tests/test__monkey_module_run.py
+1
-3
src/gevent/tests/test__monkey_selectors.py
src/gevent/tests/test__monkey_selectors.py
+0
-3
src/gevent/tests/test__monkey_ssl_warning.py
src/gevent/tests/test__monkey_ssl_warning.py
+1
-0
src/gevent/tests/test__subprocess.py
src/gevent/tests/test__subprocess.py
+0
-1
src/gevent/thread.py
src/gevent/thread.py
+20
-32
src/gevent/threading.py
src/gevent/threading.py
+32
-35
No files found.
setup.py
View file @
d9e2479b
...
...
@@ -427,6 +427,8 @@ def run_setup(ext_modules):
# leak checks. previously we had a hand-rolled version.
'objgraph'
,
# We still have some places we like to test with pkg_resources
'setuptools'
,
],
},
# It's always safe to pass the CFFI keyword, even if
...
...
src/gevent/_compat.py
View file @
d9e2479b
...
...
@@ -12,12 +12,6 @@ import sys
import
os
PY2
=
sys
.
version_info
[
0
]
==
2
PY3
=
sys
.
version_info
[
0
]
>=
3
PY35
=
sys
.
version_info
[:
2
]
>=
(
3
,
5
)
PY36
=
sys
.
version_info
[:
2
]
>=
(
3
,
6
)
PY37
=
sys
.
version_info
[:
2
]
>=
(
3
,
7
)
PY38
=
sys
.
version_info
[:
2
]
>=
(
3
,
8
)
PY39
=
sys
.
version_info
[:
2
]
>=
(
3
,
9
)
PY311
=
sys
.
version_info
[:
2
]
>=
(
3
,
11
)
PYPY
=
hasattr
(
sys
,
'pypy_version_info'
)
...
...
@@ -30,20 +24,12 @@ PURE_PYTHON = PYPY or os.getenv('PURE_PYTHON')
## Types
if
PY3
:
string_types
=
(
str
,)
integer_types
=
(
int
,)
text_type
=
str
native_path_types
=
(
str
,
bytes
)
thread_mod_name
=
'_thread'
else
:
import
__builtin__
# pylint:disable=import-error
string_types
=
(
__builtin__
.
basestring
,)
text_type
=
__builtin__
.
unicode
integer_types
=
(
int
,
__builtin__
.
long
)
native_path_types
=
string_types
thread_mod_name
=
'thread'
string_types
=
(
str
,)
integer_types
=
(
int
,)
text_type
=
str
native_path_types
=
(
str
,
bytes
)
thread_mod_name
=
'_thread'
hostname_types
=
tuple
(
set
(
string_types
+
(
bytearray
,
bytes
)))
...
...
@@ -51,27 +37,20 @@ def NativeStrIO():
import
io
return
io
.
BytesIO
()
if
str
is
bytes
else
io
.
StringIO
()
try
:
from
abc
import
ABC
except
ImportError
:
import
abc
ABC
=
abc
.
ABCMeta
(
'ABC'
,
(
object
,),
{
'__slots__'
:
()})
del
abc
from
abc
import
ABC
# pylint:disable=unused-import
## Exceptions
if
PY3
:
def
reraise
(
t
,
value
,
tb
=
None
):
# pylint:disable=unused-argument
if
value
.
__traceback__
is
not
tb
and
tb
is
not
None
:
raise
value
.
with_traceback
(
tb
)
raise
value
def
exc_clear
():
pass
else
:
from
gevent._util_py2
import
reraise
# pylint:disable=import-error,no-name-in-module
reraise
=
reraise
# export
exc_clear
=
sys
.
exc_clear
def
reraise
(
t
,
value
,
tb
=
None
):
# pylint:disable=unused-argument
if
value
.
__traceback__
is
not
tb
and
tb
is
not
None
:
raise
value
.
with_traceback
(
tb
)
raise
value
def
exc_clear
():
pass
## import locks
try
:
...
...
@@ -86,127 +65,28 @@ imp_acquire_lock = imp.acquire_lock
imp_release_lock
=
imp
.
release_lock
## Functions
if
PY3
:
iteritems
=
dict
.
items
itervalues
=
dict
.
values
xrange
=
range
izip
=
zip
else
:
iteritems
=
dict
.
iteritems
# python 3: pylint:disable=no-member
itervalues
=
dict
.
itervalues
# python 3: pylint:disable=no-member
xrange
=
__builtin__
.
xrange
from
itertools
import
izip
# python 3: pylint:disable=no-member,no-name-in-module
izip
=
izip
iteritems
=
dict
.
items
itervalues
=
dict
.
values
xrange
=
range
izip
=
zip
## The __fspath__ protocol
try
:
from
os
import
PathLike
# pylint:disable=unused-import
except
ImportError
:
class
PathLike
(
ABC
):
@
classmethod
def
__subclasshook__
(
cls
,
subclass
):
return
hasattr
(
subclass
,
'__fspath__'
)
# fspath from 3.6 os.py, but modified to raise the same exceptions as the
# real native implementation.
# Define for testing
def
_fspath
(
path
):
"""
Return the path representation of a path-like object.
If str or bytes is passed in, it is returned unchanged. Otherwise the
os.PathLike interface is used to get the path representation. If the
path representation is not str or bytes, TypeError is raised. If the
provided path is not str, bytes, or os.PathLike, TypeError is raised.
"""
if
isinstance
(
path
,
native_path_types
):
return
path
# Work from the object's type to match method resolution of other magic
# methods.
path_type
=
type
(
path
)
try
:
path_type_fspath
=
path_type
.
__fspath__
except
AttributeError
:
raise
TypeError
(
"expected str, bytes or os.PathLike object, "
"not "
+
path_type
.
__name__
)
path_repr
=
path_type_fspath
(
path
)
if
isinstance
(
path_repr
,
native_path_types
):
return
path_repr
raise
TypeError
(
"expected {}.__fspath__() to return str or bytes, "
"not {}"
.
format
(
path_type
.
__name__
,
type
(
path_repr
).
__name__
))
try
:
from
os
import
fspath
# pylint: disable=unused-import,no-name-in-module
except
ImportError
:
# if not available, use the Python version as transparently as
# possible
fspath
=
_fspath
fspath
.
__name__
=
'fspath'
try
:
from
os
import
fsencode
# pylint: disable=unused-import,no-name-in-module
except
ImportError
:
encoding
=
sys
.
getfilesystemencoding
()
or
(
'utf-8'
if
not
WIN
else
'mbcs'
)
errors
=
'strict'
if
WIN
and
encoding
==
'mbcs'
else
'surrogateescape'
# Added in 3.2, so this is for Python 2.7. Note that it doesn't have
# sys.getfilesystemencodeerrors(), which was added in 3.6
def
fsencode
(
filename
):
"""Encode filename (an os.PathLike, bytes, or str) to the filesystem
encoding with 'surrogateescape' error handler, return bytes unchanged.
On Windows, use 'strict' error handler if the file system encoding is
'mbcs' (which is the default encoding).
"""
filename
=
fspath
(
filename
)
# Does type-checking of `filename`.
if
isinstance
(
filename
,
bytes
):
return
filename
try
:
return
filename
.
encode
(
encoding
,
errors
)
except
LookupError
:
# Can't encode it, and the error handler doesn't
# exist. Probably on Python 2 with an astral character.
# Not sure how to handle this.
raise
UnicodeEncodeError
(
"Can't encode path to filesystem encoding"
)
try
:
from
os
import
fsdecode
# pylint:disable=unused-import
except
ImportError
:
def
fsdecode
(
filename
):
"""Decode filename (an os.PathLike, bytes, or str) from the filesystem
encoding with 'surrogateescape' error handler, return str unchanged. On
Windows, use 'strict' error handler if the file system encoding is
'mbcs' (which is the default encoding).
"""
filename
=
fspath
(
filename
)
# Does type-checking of `filename`.
if
PY3
and
isinstance
(
filename
,
bytes
):
return
filename
.
decode
(
encoding
,
errors
)
return
filename
## The __fspath__ protocol
from
os
import
PathLike
# pylint:disable=unused-import
from
os
import
fspath
_fspath
=
fspath
from
os
import
fsencode
# pylint:disable=unused-import
from
os
import
fsdecode
# pylint:disable=unused-import
## Clocks
try
:
# Python 3.3+ (PEP 418)
from
time
import
perf_counter
from
time
import
get_clock_info
from
time
import
monotonic
perf_counter
=
perf_counter
monotonic
=
monotonic
get_clock_info
=
get_clock_info
except
ImportError
:
import
time
if
sys
.
platform
==
"win32"
:
perf_counter
=
time
.
clock
# pylint:disable=no-member
else
:
perf_counter
=
time
.
time
monotonic
=
perf_counter
def
get_clock_info
(
_
):
return
'Unknown'
# Python 3.3+ (PEP 418)
from
time
import
perf_counter
from
time
import
get_clock_info
from
time
import
monotonic
perf_counter
=
perf_counter
monotonic
=
monotonic
get_clock_info
=
get_clock_info
## Monitoring
def
get_this_psutil_process
():
...
...
src/gevent/_fileobjectcommon.py
View file @
d9e2479b
...
...
@@ -14,7 +14,6 @@ import sys
import
os
from
gevent.hub
import
_get_hub_noargs
as
get_hub
from
gevent._compat
import
PY2
from
gevent._compat
import
integer_types
from
gevent._compat
import
reraise
from
gevent._compat
import
fspath
...
...
@@ -393,18 +392,12 @@ class OpenDescriptor(object): # pylint:disable=too-many-instance-attributes
if
not
self
.
binary
:
# Either native or text at this point.
if
PY2
and
self
.
native
:
# Neither text mode nor binary mode specified.
if
self
.
universal
:
# universal was requested, e.g., 'rU'
result
=
UniversalNewlineBytesWrapper
(
result
,
line_buffering
)
else
:
# Python 2 and text mode, or Python 3 and either text or native (both are the same)
if
not
isinstance
(
raw
,
io
.
TextIOBase
):
# Avoid double-wrapping a TextIOBase in another TextIOWrapper.
# That tends not to work. See https://github.com/gevent/gevent/issues/1542
result
=
io
.
TextIOWrapper
(
result
,
self
.
encoding
,
self
.
errors
,
self
.
newline
,
line_buffering
)
# Python 2 and text mode, or Python 3 and either text or native (both are the same)
if
not
isinstance
(
raw
,
io
.
TextIOBase
):
# Avoid double-wrapping a TextIOBase in another TextIOWrapper.
# That tends not to work. See https://github.com/gevent/gevent/issues/1542
result
=
io
.
TextIOWrapper
(
result
,
self
.
encoding
,
self
.
errors
,
self
.
newline
,
line_buffering
)
if
result
is
not
raw
or
self
.
_raw_object_is_new
(
raw
):
# Set the mode, if possible, but only if we created a new
...
...
src/gevent/_patcher.py
View file @
d9e2479b
...
...
@@ -12,7 +12,7 @@ from __future__ import absolute_import, print_function
import
importlib
import
sys
from
gevent._compat
import
PY3
from
gevent._compat
import
iteritems
from
gevent._compat
import
imp_acquire_lock
from
gevent._compat
import
imp_release_lock
...
...
@@ -25,23 +25,20 @@ MAPPING = {
'gevent.local'
:
'_threading_local'
,
'gevent.socket'
:
'socket'
,
'gevent.select'
:
'select'
,
'gevent.selectors'
:
'selectors'
if
PY3
else
'selectors2'
,
'gevent.selectors'
:
'selectors'
,
'gevent.ssl'
:
'ssl'
,
'gevent.thread'
:
'_thread'
if
PY3
else
'thread'
,
'gevent.thread'
:
'_thread'
,
'gevent.subprocess'
:
'subprocess'
,
'gevent.os'
:
'os'
,
'gevent.threading'
:
'threading'
,
'gevent.builtins'
:
'builtins'
if
PY3
else
'__builtin__'
,
'gevent.builtins'
:
'builtins'
,
'gevent.signal'
:
'signal'
,
'gevent.time'
:
'time'
,
'gevent.queue'
:
'queue'
if
PY3
else
'Queue'
,
'gevent.queue'
:
'queue'
,
'gevent.contextvars'
:
'contextvars'
,
}
OPTIONAL_STDLIB_MODULES
=
frozenset
()
if
PY3
else
frozenset
([
'selectors2'
,
])
OPTIONAL_STDLIB_MODULES
=
frozenset
()
_PATCH_PREFIX
=
'__g_patched_module_'
def
_collect_stdlib_gevent_modules
():
...
...
src/gevent/_socketcommon.py
View file @
d9e2479b
...
...
@@ -270,10 +270,16 @@ def getfqdn(name=''):
First the hostname returned by gethostbyaddr() is checked, then
possibly existing aliases. In case no FQDN is available, hostname
from gethostname() is returned.
.. versionchanged:: NEXT
The IPv6 generic address '::' now returns the result of
``gethostname``, like the IPv4 address '0.0.0.0'.
"""
# pylint: disable=undefined-variable
name
=
name
.
strip
()
if
not
name
or
name
==
'0.0.0.0'
:
# IPv6 added in a late Python 3.10/3.11 patch release.
# https://github.com/python/cpython/issues/100374
if
not
name
or
name
in
(
'0.0.0.0'
,
'::'
):
name
=
gethostname
()
try
:
hostname
,
aliases
,
_
=
gethostbyaddr
(
name
)
...
...
src/gevent/_ssl3.py
View file @
d9e2479b
...
...
@@ -13,13 +13,13 @@ import ssl as __ssl__
_ssl
=
__ssl__
.
_ssl
import
errno
import
sys
from
gevent.socket
import
socket
,
timeout_default
from
gevent.socket
import
error
as
socket_error
from
gevent.socket
import
timeout
as
_socket_timeout
from
gevent._util
import
copy_globals
from
gevent._compat
import
PY36
from
weakref
import
ref
as
_wref
...
...
@@ -49,8 +49,8 @@ from ssl import SSL_ERROR_EOF
from
ssl
import
SSL_ERROR_WANT_READ
from
ssl
import
SSL_ERROR_WANT_WRITE
from
ssl
import
PROTOCOL_SSLv23
from
ssl
import
SSLObject
from
ssl
import
match_hostname
#
from ssl import SSLObject
from
ssl
import
CHANNEL_BINDING_TYPES
from
ssl
import
CERT_REQUIRED
from
ssl
import
DER_cert_to_PEM_cert
...
...
@@ -674,32 +674,14 @@ class SSLSocket(socket):
raise
self
.
_wait
(
self
.
_write_event
,
timeout_exc
=
_SSLErrorHandshakeTimeout
)
if
sys
.
version_info
[:
2
]
<
(
3
,
7
)
and
self
.
_context
.
check_hostname
:
# In Python 3.7, the underlying OpenSSL name matching is used.
# The version implemented in Python doesn't understand IDNA encoding.
if
not
self
.
server_hostname
:
raise
ValueError
(
"check_hostname needs server_hostname "
"argument"
)
match_hostname
(
self
.
getpeercert
(),
self
.
server_hostname
)
# pylint:disable=deprecated-method
if
hasattr
(
SSLObject
,
'_create'
):
# 3.7+, making it difficult to create these objects.
# There's a new type, _ssl.SSLSocket, that takes the
# place of SSLObject for self._sslobj. This one does it all.
def
__create_sslobj
(
self
,
server_side
=
False
,
session
=
None
):
return
self
.
context
.
_wrap_socket
(
self
.
_sock
,
server_side
,
self
.
server_hostname
,
owner
=
self
.
_sock
,
session
=
session
)
elif
PY36
:
# 3.6
def
__create_sslobj
(
self
,
server_side
=
False
,
session
=
None
):
sslobj
=
self
.
_context
.
_wrap_socket
(
self
.
_sock
,
server_side
,
self
.
server_hostname
)
return
SSLObject
(
sslobj
,
owner
=
self
.
_sock
,
session
=
session
)
else
:
# 3.5
def
__create_sslobj
(
self
,
server_side
=
False
,
session
=
None
):
# pylint:disable=unused-argument
sslobj
=
self
.
_context
.
_wrap_socket
(
self
.
_sock
,
server_side
,
self
.
server_hostname
)
return
SSLObject
(
sslobj
,
owner
=
self
.
_sock
)
# 3.7+, making it difficult to create these objects.
# There's a new type, _ssl.SSLSocket, that takes the
# place of SSLObject for self._sslobj. This one does it all.
def
__create_sslobj
(
self
,
server_side
=
False
,
session
=
None
):
return
self
.
context
.
_wrap_socket
(
self
.
_sock
,
server_side
,
self
.
server_hostname
,
owner
=
self
.
_sock
,
session
=
session
)
def
_real_connect
(
self
,
addr
,
connect_ex
):
if
self
.
server_side
:
...
...
src/gevent/_threading.py
View file @
d9e2479b
...
...
@@ -9,8 +9,6 @@ from collections import deque
from
gevent
import
monkey
from
gevent._compat
import
thread_mod_name
from
gevent._compat
import
PY3
__all__
=
[
'Lock'
,
...
...
@@ -33,21 +31,10 @@ start_new_thread, Lock, get_thread_ident, = monkey.get_original(thread_mod_name,
#
#
# In all cases, a timeout value of -1 means "infinite". Sigh.
if
PY3
:
def
acquire_with_timeout
(
lock
,
timeout
=-
1
):
globals
()[
'acquire_with_timeout'
]
=
type
(
lock
).
acquire
return
lock
.
acquire
(
timeout
=
timeout
)
else
:
def
acquire_with_timeout
(
lock
,
timeout
=-
1
,
_time
=
monkey
.
get_original
(
'time'
,
'time'
),
_sleep
=
monkey
.
get_original
(
'time'
,
'sleep'
)):
deadline
=
_time
()
+
timeout
if
timeout
!=
-
1
else
None
while
1
:
if
lock
.
acquire
(
False
):
# Can we acquire non-blocking?
return
True
if
deadline
is
not
None
and
_time
()
>=
deadline
:
return
False
_sleep
(
0.005
)
def
acquire_with_timeout
(
lock
,
timeout
=-
1
):
globals
()[
'acquire_with_timeout'
]
=
type
(
lock
).
acquire
return
lock
.
acquire
(
timeout
=
timeout
)
class
_Condition
(
object
):
# We could use libuv's ``uv_cond_wait`` to implement this whole
...
...
src/gevent/backdoor.py
View file @
d9e2479b
...
...
@@ -18,8 +18,7 @@ from gevent.greenlet import Greenlet
from
gevent.hub
import
getcurrent
from
gevent.server
import
StreamServer
from
gevent.pool
import
Pool
from
gevent._compat
import
PY36
from
gevent._compat
import
exc_clear
__all__
=
[
'BackdoorServer'
,
...
...
@@ -174,15 +173,13 @@ class BackdoorServer(StreamServer):
getcurrent
().
switch_in
()
try
:
console
=
InteractiveConsole
(
self
.
_create_interactive_locals
())
if
PY36
:
# Beginning in 3.6, the console likes to print "now exiting <class>"
# but probably our socket is already closed, so this just causes problems.
console
.
interact
(
banner
=
self
.
banner
,
exitmsg
=
''
)
# pylint:disable=unexpected-keyword-arg
else
:
console
.
interact
(
banner
=
self
.
banner
)
# Beginning in 3.6, the console likes to print "now exiting <class>"
# but probably our socket is already closed, so this just causes problems.
console
.
interact
(
banner
=
self
.
banner
,
exitmsg
=
''
)
# pylint:disable=unexpected-keyword-arg
except
SystemExit
:
# raised by quit(); obviously this cannot propagate.
exc_clear
()
# Python 2
pass
finally
:
raw_file
.
close
()
conn
.
close
()
...
...
src/gevent/builtins.py
View file @
d9e2479b
...
...
@@ -5,25 +5,14 @@ from __future__ import absolute_import
import
weakref
from
gevent.lock
import
RLock
from
gevent._compat
import
PY3
from
gevent._compat
import
imp_acquire_lock
from
gevent._compat
import
imp_release_lock
# Normally we'd have the "expected" case inside the try
# (Python 3, because Python 3 is the way forward). But
# under Python 2, the popular `future` library *also* provides
# a `builtins` module---which lacks the __import__ attribute.
# So we test for the old, deprecated version first
try
:
# Py2
import
__builtin__
as
__gbuiltins__
_allowed_module_name_types
=
(
basestring
,)
# pylint:disable=undefined-variable
__target__
=
'__builtin__'
except
ImportError
:
import
builtins
as
__gbuiltins__
# pylint: disable=import-error
_allowed_module_name_types
=
(
str
,)
__target__
=
'builtins'
import
builtins
as
__gbuiltins__
_allowed_module_name_types
=
(
str
,)
__target__
=
'builtins'
_import
=
__gbuiltins__
.
__import__
...
...
@@ -121,11 +110,9 @@ def _lock_imports():
global
__lock_imports
__lock_imports
=
True
if
PY3
:
__implements__
=
[]
__import__
=
_import
else
:
__implements__
=
[
'__import__'
]
__implements__
=
[]
__import__
=
_import
__all__
=
__implements__
...
...
src/gevent/contextvars.py
View file @
d9e2479b
...
...
@@ -53,12 +53,12 @@ try:
except
ImportError
:
from
collections
import
Mapping
# pylint:disable=deprecated-class
from
gevent._compat
import
PY37
from
gevent._util
import
_NONE
from
gevent.local
import
local
__stdlib_expected__
=
__all__
__implements__
=
__stdlib_expected__
if
PY37
else
None
__implements__
=
__stdlib_expected__
# In the reference implementation, the interpreter level OS thread state
# is modified to contain a pointer to the current context. Obviously we can't
...
...
src/gevent/events.py
View file @
d9e2479b
...
...
@@ -130,7 +130,7 @@ def notify_and_call_entry_points(event):
entry_points
=
set
(
ep
for
ep
in
ep_dict
.
get
(
event
.
ENTRY_POINT_NAME
)
in
ep_dict
.
get
(
event
.
ENTRY_POINT_NAME
,
()
)
)
for
plugin
in
entry_points
:
...
...
src/gevent/local.py
View file @
d9e2479b
...
...
@@ -597,21 +597,7 @@ if local.__module__ == 'gevent.local':
# module has a different name than the pure-Python version and we can check for that.
# It's not as direct, but it works.
# So here we're not compiled
from
gevent._compat
import
PYPY
from
gevent._compat
import
PY2
if
PYPY
and
PY2
:
# The behaviour changed with no warning between PyPy2 7.3.2 and 7.3.3.
local
.
__new__
=
__new__
try
:
local
()
# <= 7.3.2
except
TypeError
:
# >= 7.3.3
local
.
__new__
=
classmethod
(
__new__
)
else
:
local
.
__new__
=
classmethod
(
__new__
)
del
PYPY
del
PY2
local
.
__new__
=
classmethod
(
__new__
)
else
:
# pragma: no cover
# Make sure we revisit in case of changes to the (accelerator) module names.
if
local
.
__module__
!=
'gevent._gevent_clocal'
:
...
...
src/gevent/lock.py
View file @
d9e2479b
...
...
@@ -12,7 +12,7 @@ from __future__ import print_function
from
gevent.hub
import
getcurrent
from
gevent._compat
import
PURE_PYTHON
from
gevent._compat
import
PY2
# This is the one exception to the rule of where to
# import Semaphore, obviously
from
gevent
import
monkey
...
...
@@ -180,8 +180,6 @@ def _fixup_docstrings():
assert
c
.
__doc__
==
b
.
__doc__
for
m
in
'acquire'
,
'release'
,
'wait'
:
c_meth
=
getattr
(
c
,
m
)
if
PY2
:
c_meth
=
c_meth
.
__func__
b_meth
=
getattr
(
b
,
m
)
c_meth
.
__doc__
=
b_meth
.
__doc__
...
...
src/gevent/monkey.py
View file @
d9e2479b
This diff is collapsed.
Click to expand it.
src/gevent/os.py
View file @
d9e2479b
...
...
@@ -48,7 +48,6 @@ import sys
from
gevent.hub
import
_get_hub_noargs
as
get_hub
from
gevent.hub
import
reinit
from
gevent._config
import
config
from
gevent._compat
import
PY3
from
gevent._util
import
copy_globals
import
errno
...
...
@@ -102,8 +101,6 @@ if fcntl:
except
OSError
as
e
:
if
e
.
errno
not
in
ignored_errors
:
raise
if
not
PY3
:
sys
.
exc_clear
()
if
hub
is
None
:
hub
=
get_hub
()
event
=
hub
.
loop
.
io
(
fd
,
1
)
...
...
@@ -133,8 +130,6 @@ if fcntl:
except
OSError
as
e
:
if
e
.
errno
not
in
ignored_errors
:
raise
if
not
PY3
:
sys
.
exc_clear
()
if
hub
is
None
:
hub
=
get_hub
()
event
=
hub
.
loop
.
io
(
fd
,
2
)
...
...
src/gevent/pywsgi.py
View file @
d9e2479b
...
...
@@ -31,13 +31,10 @@ from gevent import socket
import
gevent
from
gevent.server
import
StreamServer
from
gevent.hub
import
GreenletExit
from
gevent._compat
import
PY3
,
reraise
from
gevent._compat
import
reraise
from
functools
import
partial
if
PY3
:
unquote_latin1
=
partial
(
unquote
,
encoding
=
'latin-1'
)
else
:
unquote_latin1
=
unquote
unquote_latin1
=
partial
(
unquote
,
encoding
=
'latin-1'
)
_no_undoc_members
=
True
# Don't put undocumented things into sphinx
...
...
@@ -89,8 +86,7 @@ def format_date_time(timestamp):
# Return a byte string, not a native string
year
,
month
,
day
,
hh
,
mm
,
ss
,
wd
,
_y
,
_z
=
time
.
gmtime
(
timestamp
)
value
=
"%s, %02d %3s %4d %02d:%02d:%02d GMT"
%
(
_WEEKDAYNAME
[
wd
],
day
,
_MONTHNAME
[
month
],
year
,
hh
,
mm
,
ss
)
if
PY3
:
value
=
value
.
encode
(
"latin-1"
)
value
=
value
.
encode
(
"latin-1"
)
return
value
...
...
@@ -392,13 +388,9 @@ class WSGIHandler(object):
# pylint:disable=too-many-instance-attributes
protocol_version
=
'HTTP/1.1'
if
PY3
:
# if we do like Py2, then headers_factory unconditionally
# becomes a bound method, meaning the fp argument becomes WSGIHandler
def
MessageClass
(
self
,
*
args
):
return
headers_factory
(
*
args
)
else
:
MessageClass
=
headers_factory
def
MessageClass
(
self
,
*
args
):
return
headers_factory
(
*
args
)
# Attributes reset at various times for each request; not public
# documented. Class attributes to keep the constructor fast
...
...
@@ -562,10 +554,10 @@ class WSGIHandler(object):
if
self
.
request_version
==
"HTTP/1.1"
:
conntype
=
self
.
headers
.
get
(
"Connection"
,
""
).
lower
()
self
.
close_connection
=
(
conntype
==
'close'
)
self
.
close_connection
=
(
conntype
==
'close'
)
# pylint:disable=superfluous-parens
elif
self
.
request_version
==
'HTTP/1.0'
:
conntype
=
self
.
headers
.
get
(
"Connection"
,
"close"
).
lower
()
self
.
close_connection
=
(
conntype
!=
'keep-alive'
)
self
.
close_connection
=
(
conntype
!=
'keep-alive'
)
# pylint:disable=superfluous-parens
else
:
# XXX: HTTP 0.9. We should drop support
self
.
close_connection
=
True
...
...
@@ -606,8 +598,7 @@ class WSGIHandler(object):
latin-1).
"""
line
=
self
.
rfile
.
readline
(
MAX_REQUEST_LINE
)
if
PY3
:
line
=
line
.
decode
(
'latin-1'
)
line
=
line
.
decode
(
'latin-1'
)
return
line
def
handle_one_request
(
self
):
...
...
@@ -659,7 +650,7 @@ class WSGIHandler(object):
try
:
self
.
requestline
=
self
.
read_requestline
()
# Account for old subclasses that haven't done this
if
PY3
and
isinstance
(
self
.
requestline
,
bytes
):
if
isinstance
(
self
.
requestline
,
bytes
):
self
.
requestline
=
self
.
requestline
.
decode
(
'latin-1'
)
except
socket
.
error
:
# "Connection reset by peer" or other socket errors aren't interesting here
...
...
@@ -720,8 +711,7 @@ class WSGIHandler(object):
if
hasattr
(
self
.
result
,
'__len__'
):
total_len
=
sum
(
len
(
chunk
)
for
chunk
in
self
.
result
)
total_len_str
=
str
(
total_len
)
if
PY3
:
total_len_str
=
total_len_str
.
encode
(
"latin-1"
)
total_len_str
=
total_len_str
.
encode
(
"latin-1"
)
self
.
response_headers
.
append
((
b'Content-Length'
,
total_len_str
))
else
:
self
.
response_use_chunked
=
(
...
...
@@ -856,8 +846,8 @@ class WSGIHandler(object):
# Note: Some Python 2 implementations, like Jython, may allow non-octet (above 255) values
# in their str implementation; this is mentioned in the WSGI spec, but we don't
# run on any platform like that so we can assume that a str value is pure bytes.
response_headers
.
append
((
header
if
not
PY3
else
header
.
encode
(
"latin-1"
),
value
if
not
PY3
else
value
.
encode
(
"latin-1"
)))
response_headers
.
append
((
header
.
encode
(
"latin-1"
),
value
.
encode
(
"latin-1"
)))
except
UnicodeEncodeError
:
# If we get here, we're guaranteed to have a header and value
raise
UnicodeError
(
"Non-latin1 header"
,
repr
(
header
),
repr
(
value
))
...
...
@@ -871,7 +861,7 @@ class WSGIHandler(object):
# code
code
=
int
(
status
.
split
(
' '
,
1
)[
0
])
self
.
status
=
status
if
not
PY3
else
status
.
encode
(
"latin-1"
)
self
.
status
=
status
.
encode
(
"latin-1"
)
self
.
_orig_status
=
status
# Preserve the native string for logging
self
.
response_headers
=
response_headers
self
.
code
=
code
...
...
@@ -898,8 +888,7 @@ class WSGIHandler(object):
if
self
.
code
in
(
304
,
204
):
if
self
.
provided_content_length
is
not
None
and
self
.
provided_content_length
!=
'0'
:
msg
=
'Invalid Content-Length for %s response: %r (must be absent or zero)'
%
(
self
.
code
,
self
.
provided_content_length
)
if
PY3
:
msg
=
msg
.
encode
(
'latin-1'
)
msg
=
msg
.
encode
(
'latin-1'
)
raise
self
.
ApplicationError
(
msg
)
return
self
.
write
...
...
@@ -1012,8 +1001,6 @@ class WSGIHandler(object):
except
socket
.
error
as
ex
:
if
ex
.
args
[
0
]
in
self
.
ignored_socket_errors
:
# See description of self.ignored_socket_errors.
if
not
PY3
:
sys
.
exc_clear
()
self
.
close_connection
=
True
else
:
self
.
handle_error
(
*
sys
.
exc_info
())
...
...
@@ -1032,8 +1019,6 @@ class WSGIHandler(object):
self
.
start_response
(
status
,
headers
[:])
self
.
write
(
body
)
except
socket
.
error
:
if
not
PY3
:
sys
.
exc_clear
()
self
.
close_connection
=
True
def
_log_error
(
self
,
t
,
v
,
tb
):
...
...
@@ -1558,7 +1543,7 @@ class WSGIServer(StreamServer):
name
=
socket
.
getfqdn
(
address
[
0
])
except
socket
.
error
:
name
=
str
(
address
[
0
])
if
PY3
and
not
isinstance
(
name
,
str
):
if
not
isinstance
(
name
,
str
):
name
=
name
.
decode
(
'ascii'
)
self
.
environ
[
'SERVER_NAME'
]
=
name
self
.
environ
.
setdefault
(
'SERVER_PORT'
,
str
(
address
[
1
]))
...
...
src/gevent/resolver/__init__.py
View file @
d9e2479b
...
...
@@ -25,7 +25,6 @@ from gevent._compat import string_types
from
gevent._compat
import
text_type
from
gevent._compat
import
hostname_types
from
gevent._compat
import
integer_types
from
gevent._compat
import
PY3
from
gevent._compat
import
PYPY
from
gevent._compat
import
MAC
...
...
@@ -98,7 +97,7 @@ def _resolve_special(hostname, family):
class
AbstractResolver
(
object
):
HOSTNAME_ENCODING
=
'idna'
if
PY3
else
'ascii'
HOSTNAME_ENCODING
=
'idna'
_LOCAL_HOSTNAMES
=
(
b'localhost'
,
...
...
src/gevent/server.py
View file @
d9e2479b
...
...
@@ -4,8 +4,6 @@ from __future__ import print_function
from
__future__
import
absolute_import
from
__future__
import
division
from
contextlib
import
closing
import
sys
from
_socket
import
error
as
SocketError
...
...
@@ -17,7 +15,7 @@ from _socket import SOCK_DGRAM
from
gevent.baseserver
import
BaseServer
from
gevent.socket
import
EWOULDBLOCK
from
gevent.socket
import
socket
as
GeventSocket
from
gevent._compat
import
PYPY
,
PY3
from
gevent._compat
import
PYPY
__all__
=
[
'StreamServer'
,
'DatagramServer'
]
...
...
@@ -29,13 +27,9 @@ else:
DEFAULT_REUSE_ADDR
=
1
if
PY3
:
# sockets and SSL sockets are context managers on Python 3
def
_closing_socket
(
sock
):
return
sock
else
:
# but they are not guaranteed to be so on Python 2
_closing_socket
=
closing
# sockets and SSL sockets are context managers on Python 3
def
_closing_socket
(
sock
):
return
sock
class
StreamServer
(
BaseServer
):
...
...
@@ -191,38 +185,21 @@ class StreamServer(BaseServer):
backlog
=
cls
.
backlog
return
_tcp_listener
(
address
,
backlog
=
backlog
,
reuse_addr
=
cls
.
reuse_addr
,
family
=
family
)
if
PY3
:
def
do_read
(
self
):
sock
=
self
.
socket
try
:
fd
,
address
=
sock
.
_accept
()
except
BlockingIOError
:
# python 2: pylint: disable=undefined-variable
if
not
sock
.
timeout
:
return
raise
sock
=
GeventSocket
(
sock
.
family
,
sock
.
type
,
sock
.
proto
,
fileno
=
fd
)
# XXX Python issue #7995? "if no default timeout is set
# and the listening socket had a (non-zero) timeout, force
# the new socket in blocking mode to override
# platform-specific socket flags inheritance."
return
sock
,
address
else
:
def
do_read
(
self
):
try
:
client_socket
,
address
=
self
.
socket
.
accept
()
except
SocketError
as
err
:
if
err
.
args
[
0
]
==
EWOULDBLOCK
:
return
raise
sockobj
=
GeventSocket
(
_sock
=
client_socket
)
if
PYPY
:
# Undo the ref-count bump that the constructor
# did. We gave it ownership.
client_socket
.
_drop
()
return
sockobj
,
address
def
do_read
(
self
):
sock
=
self
.
socket
try
:
fd
,
address
=
sock
.
_accept
()
except
BlockingIOError
:
# python 2: pylint: disable=undefined-variable
if
not
sock
.
timeout
:
return
raise
sock
=
GeventSocket
(
sock
.
family
,
sock
.
type
,
sock
.
proto
,
fileno
=
fd
)
# XXX Python issue #7995? "if no default timeout is set
# and the listening socket had a (non-zero) timeout, force
# the new socket in blocking mode to override
# platform-specific socket flags inheritance."
return
sock
,
address
def
do_close
(
self
,
sock
,
*
args
):
# pylint:disable=arguments-differ
...
...
src/gevent/socket.py
View file @
d9e2479b
...
...
@@ -13,16 +13,15 @@ as well as the constants from the :mod:`socket` module are imported into this mo
# Our import magic sadly makes this warning useless
# pylint: disable=undefined-variable
from
gevent._compat
import
PY3
from
gevent._compat
import
PY311
from
gevent._compat
import
exc_clear
from
gevent._util
import
copy_globals
if
PY3
:
from
gevent
import
_socket3
as
_source
# python 2: pylint:disable=no-name-in-module
else
:
from
gevent
import
_socket2
as
_source
from
gevent
import
_socket3
as
_source
# define some things we're expecting to overwrite; each module
# needs to define these
...
...
src/gevent/ssl.py
View file @
d9e2479b
"""
Secure Sockets Layer (SSL/TLS) module.
"""
from
gevent._compat
import
PY2
from
gevent._util
import
copy_globals
# things we expect to override, here for static analysis
...
...
@@ -9,27 +9,8 @@ def wrap_socket(_sock, **_kwargs):
# pylint:disable=unused-argument
raise
NotImplementedError
()
if
PY2
:
if
hasattr
(
__import__
(
'ssl'
),
'SSLContext'
):
# It's not sufficient to check for >= 2.7.9; some distributions
# have backported most of PEP 466. Try to accommodate them. See Issue #702.
# We're just about to import ssl anyway so it's fine to import it here, just
# don't pollute the namespace
from
gevent
import
_sslgte279
as
_source
else
:
# pragma: no cover
from
gevent
import
_ssl2
as
_source
import
warnings
warnings
.
warn
(
"This version of Python has an insecure SSL implementation. "
"gevent is no longer tested with it, and support will be removed "
"in gevent 1.5. Please use Python 2.7.9 or newer."
,
DeprecationWarning
,
stacklevel
=
2
,
)
del
warnings
else
:
# Py3
from
gevent
import
_ssl3
as
_source
# pragma: no cover
from
gevent
import
_ssl3
as
_source
copy_globals
(
_source
,
globals
())
src/gevent/subprocess.py
View file @
d9e2479b
This diff is collapsed.
Click to expand it.
src/gevent/testing/__init__.py
View file @
d9e2479b
...
...
@@ -115,7 +115,6 @@ from .skipping import skipOnPy310
from
.skipping
import
skipOnPy3
from
.skipping
import
skipWithoutResource
from
.skipping
import
skipWithoutExternalNetwork
from
.skipping
import
skipOnPy2
from
.skipping
import
skipOnManylinux
from
.skipping
import
skipOnMacOnCI
...
...
src/gevent/testing/skipping.py
View file @
d9e2479b
...
...
@@ -45,7 +45,6 @@ skipOnPyPy3OnCI = _do_not_skip
skipOnPyPy3
=
_do_not_skip
skipOnPyPyOnWindows
=
_do_not_skip
skipOnPy2
=
unittest
.
skip
if
sysinfo
.
PY2
else
_do_not_skip
skipOnPy3
=
unittest
.
skip
if
sysinfo
.
PY3
else
_do_not_skip
skipOnPy37
=
unittest
.
skip
if
sysinfo
.
PY37
else
_do_not_skip
skipOnPy310
=
unittest
.
skip
if
sysinfo
.
PY310
else
_do_not_skip
...
...
src/gevent/tests/test__fileobject.py
View file @
d9e2479b
...
...
@@ -17,18 +17,10 @@ try:
except
ImportError
:
GreenOpenDescriptor
=
None
from
gevent._compat
import
PY2
from
gevent._compat
import
PY3
from
gevent._compat
import
text_type
import
gevent.testing
as
greentest
from
gevent.testing
import
sysinfo
try
:
ResourceWarning
# pylint:disable=used-before-assignment
except
NameError
:
class
ResourceWarning
(
Warning
):
"Python 2 fallback"
# pylint:disable=unspecified-encoding
...
...
@@ -136,11 +128,9 @@ class TestFileObjectBlock(CleanupMixin,
with
open
(
path
,
'rb'
)
as
f_raw
:
f
=
self
.
_makeOne
(
f_raw
,
'rb'
,
close
=
False
)
if
PY3
or
hasattr
(
f
,
'seekable'
):
# On Python 3, all objects should have seekable.
# On Python 2, only our custom objects do.
self
.
assertTrue
(
f
.
seekable
())
# On Python 3, all objects should have seekable.
# On Python 2, only our custom objects do.
self
.
assertTrue
(
f
.
seekable
())
f
.
seek
(
15
)
self
.
assertEqual
(
15
,
f
.
tell
())
...
...
@@ -169,7 +159,7 @@ class TestFileObjectBlock(CleanupMixin,
else
:
# Note that we don't use ``io.open()`` for the raw file,
# on Python 2. We want 'r' to mean what the usual call to open() means.
opener
=
io
.
open
if
PY3
else
open
opener
=
io
.
open
with
opener
(
path
,
open_mode
,
**
open_kwargs
)
as
raw
:
with
self
.
_makeOne
(
raw
)
as
f
:
gevent_data
=
getattr
(
f
,
meth
)()
...
...
@@ -190,7 +180,7 @@ class TestFileObjectBlock(CleanupMixin,
'r+'
,
buffering
=
5
,
encoding
=
'utf-8'
)
self
.
assertIsInstance
(
gevent_data
,
text_type
)
self
.
assertIsInstance
(
gevent_data
,
str
)
@
skipUnlessWorksWithRegularFiles
def
test_does_not_leak_on_exception
(
self
):
...
...
@@ -341,7 +331,7 @@ class ConcurrentFileObjectMixin(object):
self
.
addCleanup
(
os
.
close
,
w
)
reader
=
self
.
_makeOne
(
r
)
self
.
_close_on_teardown
(
reader
)
self
.
assert
Equal
(
PY2
,
hasattr
(
reader
,
'read1'
))
self
.
assert
False
(
hasattr
(
reader
,
'read1'
))
def
test_bufsize_0
(
self
):
# Issue #840
...
...
src/gevent/tests/test__issue1864.py
View file @
d9e2479b
import
sys
import
unittest
from
gevent.testing
import
skipOnPy2
class
TestSubnormalFloatsAreNotDisabled
(
unittest
.
TestCase
):
@
skipOnPy2
(
'This test always fails on Python 2'
)
def
test_subnormal_is_not_zero
(
self
):
# Enabling the -Ofast compiler flag resulted in subnormal floats getting
# disabled the moment when gevent was imported. This impacted libraries
...
...
@@ -21,7 +19,7 @@ class TestSubnormalFloatsAreNotDisabled(unittest.TestCase):
# `sys.float_info.min` is the minimum representable positive normalized
# float, so dividing it by two gives us a positive subnormal float,
# as long as subnormals floats are not disabled.
self
.
assertGreater
(
sys
.
float_info
.
min
/
2
,
0
)
self
.
assertGreater
(
sys
.
float_info
.
min
/
2
,
0
.0
)
if
__name__
==
"__main__"
:
...
...
src/gevent/tests/test__monkey_module_run.py
View file @
d9e2479b
...
...
@@ -104,21 +104,19 @@ class TestRun(greentest.TestCase):
# Also, occasionally, they get '3' instead of '2' for the number of threads.
# That could have something to do with...? Most commonly that's PyPy, but
# sometimes CPython. Again, haven't reproduced.
@
greentest
.
skipOnPy2
(
"lost sys.stderr sometimes"
)
# Not relevant since Py2 has been dropped.
def
test_threadpool_in_patched_after_patch
(
self
):
# Issue 1484
# If we don't have this correct, then we get exceptions
out
=
self
.
_run
(
os
.
path
.
join
(
'monkey_package'
,
'threadpool_monkey_patches.py'
))
self
.
assertEqual
(
out
,
[
'False'
,
'2'
])
@
greentest
.
skipOnPy2
(
"lost sys.stderr sometimes"
)
def
test_threadpool_in_patched_after_patch_module
(
self
):
# Issue 1484
# If we don't have this correct, then we get exceptions
out
=
self
.
_run
(
'monkey_package.threadpool_monkey_patches'
,
module
=
True
)
self
.
assertEqual
(
out
,
[
'False'
,
'2'
])
@
greentest
.
skipOnPy2
(
"lost sys.stderr sometimes"
)
def
test_threadpool_not_patched_after_patch_module
(
self
):
# Issue 1484
# If we don't have this correct, then we get exceptions
...
...
src/gevent/tests/test__monkey_selectors.py
View file @
d9e2479b
...
...
@@ -17,9 +17,6 @@ from gevent.tests.test__selectors import SelectorTestMixin
class
TestSelectors
(
SelectorTestMixin
,
greentest
.
TestCase
):
@
greentest
.
skipOnPy2
(
'selectors2 backport does not use _select'
)
@
greentest
.
skipOnWindows
(
"SelectSelector._select is a normal function on Windows"
)
...
...
src/gevent/tests/test__monkey_ssl_warning.py
View file @
d9e2479b
...
...
@@ -11,6 +11,7 @@ class Test(unittest.TestCase):
# Issue 1108: Python 2, importing pkg_resources,
# as is done for namespace packages, imports ssl,
# leading to an unwanted SSL warning.
# This is a deprecated API though.
__import__
(
'pkg_resources'
)
from
gevent
import
monkey
...
...
src/gevent/tests/test__subprocess.py
View file @
d9e2479b
...
...
@@ -111,7 +111,6 @@ class TestPopen(greentest.TestCase):
'pineapple
\
n
\
xff
\
xff
\
xf2
\
xf9
\
n
'
)
@
greentest
.
skipOnWindows
(
"Windows IO is weird; this doesn't raise"
)
@
greentest
.
skipOnPy2
(
"Only Python 2 decodes"
)
def
test_communicate_undecodable
(
self
):
# If the subprocess writes non-decodable data, `communicate` raises the
# same UnicodeDecodeError that the stdlib does, instead of
...
...
src/gevent/thread.py
View file @
d9e2479b
...
...
@@ -9,7 +9,6 @@ Implementation of the standard :mod:`thread` module that spawns greenlets.
:class:`gevent.Greenlet` class or :func:`gevent.spawn`.
"""
from
__future__
import
absolute_import
import
sys
__implements__
=
[
'allocate_lock'
,
...
...
@@ -22,31 +21,23 @@ __implements__ = [
]
__imports__
=
[
'error'
]
if
sys
.
version_info
[
0
]
==
2
:
import
thread
as
__thread__
# pylint:disable=import-error
PY2
=
True
PY3
=
False
# Name the `future` backport that might already have been imported;
# Importing `pkg_resources` imports this, for example.
__alternate_targets__
=
(
'_thread'
,)
else
:
import
_thread
as
__thread__
# pylint:disable=import-error
PY2
=
False
PY3
=
True
__target__
=
'_thread'
__imports__
+=
[
'TIMEOUT_MAX'
,
'allocate'
,
'exit_thread'
,
'interrupt_main'
,
'start_new'
]
if
sys
.
version_info
[:
2
]
>=
(
3
,
8
):
# We can't actually produce a value that "may be used
# to identify this particular thread system-wide", right?
# Even if we could, I imagine people will want to pass this to
# non-Python (native) APIs, so we shouldn't mess with it.
__imports__
.
append
(
'get_native_id'
)
import
_thread
as
__thread__
# pylint:disable=import-error
__target__
=
'_thread'
__imports__
+=
[
'TIMEOUT_MAX'
,
'allocate'
,
'exit_thread'
,
'interrupt_main'
,
'start_new'
]
# We can't actually produce a value that "may be used
# to identify this particular thread system-wide", right?
# Even if we could, I imagine people will want to pass this to
# non-Python (native) APIs, so we shouldn't mess with it.
__imports__
.
append
(
'get_native_id'
)
error
=
__thread__
.
error
...
...
@@ -63,7 +54,6 @@ from gevent.local import local as _local
from
gevent.exceptions
import
LoopExit
if
hasattr
(
__thread__
,
'RLock'
):
assert
PY3
or
PYPY
# Added in Python 3.4, backported to PyPy 2.7-7.0
__imports__
.
append
(
"RLock"
)
...
...
@@ -88,13 +78,11 @@ class LockType(BoundedSemaphore):
# and any other API changes we need to make to match behaviour
_OVER_RELEASE_ERROR
=
__thread__
.
error
if
PYPY
and
PY3
:
if
PYPY
:
_OVER_RELEASE_ERROR
=
RuntimeError
if
PY3
:
_TIMEOUT_MAX
=
__thread__
.
TIMEOUT_MAX
# python 2: pylint:disable=no-member
else
:
_TIMEOUT_MAX
=
9223372036.0
_TIMEOUT_MAX
=
__thread__
.
TIMEOUT_MAX
# pylint:disable=no-member
def
acquire
(
self
,
blocking
=
True
,
timeout
=-
1
):
# This is the Python 3 signature.
...
...
src/gevent/threading.py
View file @
d9e2479b
...
...
@@ -50,8 +50,7 @@ from gevent.thread import get_ident as _get_ident
from
gevent.hub
import
sleep
as
_sleep
,
getcurrent
from
gevent.lock
import
RLock
from
gevent._compat
import
PY3
from
gevent._compat
import
PYPY
from
gevent._util
import
LazyOnClass
# Exports, prevent unused import warnings.
...
...
@@ -168,46 +167,45 @@ else:
return
main_threads
[
0
]
if
PY3
:
# XXX: Issue 18808 breaks us on Python 3.4+.
# Thread objects now expect a callback from the interpreter itself
# (threadmodule.c:release_sentinel) when the C-level PyThreadState
# object is being deallocated. Because this never happens
# when a greenlet exits, join() and friends will block forever.
# Fortunately this is easy to fix: just ensure that the allocation of the
# lock, _set_sentinel, creates a *gevent* lock, and release it when
# we're done. The main _shutdown code is in Python and deals with
# this gracefully.
class
Thread
(
__threading__
.
Thread
):
# XXX: Issue 18808 breaks us on Python 3.4+.
# Thread objects now expect a callback from the interpreter itself
# (threadmodule.c:release_sentinel) when the C-level PyThreadState
# object is being deallocated. Because this never happens
# when a greenlet exits, join() and friends will block forever.
# Fortunately this is easy to fix: just ensure that the allocation of the
# lock, _set_sentinel, creates a *gevent* lock, and release it when
# we're done. The main _shutdown code is in Python and deals with
# this gracefully.
def
_set_tstate_lock
(
self
):
super
(
Thread
,
self
).
_set_tstate_lock
()
greenlet
=
getcurrent
()
greenlet
.
rawlink
(
self
.
__greenlet_finished
)
class
Thread
(
__threading__
.
Thread
):
def
__greenlet_finished
(
self
,
_
):
if
self
.
_tstate_lock
:
self
.
_tstate_lock
.
release
()
self
.
_stop
(
)
def
_set_tstate_lock
(
self
):
super
(
Thread
,
self
).
_set_tstate_lock
()
greenlet
=
getcurrent
()
greenlet
.
rawlink
(
self
.
__greenlet_finished
)
__implements__
.
append
(
'Thread'
)
def
__greenlet_finished
(
self
,
_
):
if
self
.
_tstate_lock
:
self
.
_tstate_lock
.
release
()
self
.
_stop
()
class
Timer
(
Thread
,
__threading__
.
Timer
):
# pylint:disable=abstract-method,inherit-non-class
pass
__implements__
.
append
(
'Thread'
)
class
Timer
(
Thread
,
__threading__
.
Timer
):
# pylint:disable=abstract-method,inherit-non-class
pass
__implements__
.
append
(
'Timer'
)
__implements__
.
append
(
'Timer'
)
_set_sentinel
=
allocate_lock
__implements__
.
append
(
'_set_sentinel'
)
# The main thread is patched up with more care
# in _gevent_will_monkey_patch
_set_sentinel
=
allocate_lock
__implements__
.
append
(
'_set_sentinel'
)
# The main thread is patched up with more care
# in _gevent_will_monkey_patch
if
PY3
:
__implements__
.
remove
(
'_get_ident'
)
__implements__
.
append
(
'get_ident'
)
get_ident
=
_get_ident
__implements__
.
remove
(
'_sleep'
)
__implements__
.
remove
(
'_get_ident'
)
__implements__
.
append
(
'get_ident'
)
get_ident
=
_get_ident
__implements__
.
remove
(
'_sleep'
)
if
hasattr
(
__threading__
,
'_CRLock'
):
# Python 3 changed the implementation of threading.RLock
...
...
@@ -219,7 +217,6 @@ if hasattr(__threading__, '_CRLock'):
# if the imported _CRLock is None; this arranges for that to be the case.
# This was also backported to PyPy 2.7-7.0
assert
PY3
or
PYPY
,
"Unsupported Python version"
_CRLock
=
None
__implements__
.
append
(
'_CRLock'
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment