Skip to content

Commit

Permalink
Python 3.10 partial support
Browse files Browse the repository at this point in the history
Everything below is specific to changes in Python 3.10.
#715

- Only wrap socket.timeout on Python < 3.10
  socket.timeout is TimeoutError, which our is_timeout() helper func already knows.
  fixes #687
- Working greenio._open
  _pyio.open is now a staticmethod, so we've got to go down to
  _pyio.open.__wrapped__ to get to the python function object.
- Test using eventlet.is_timeout rather than requiring an is_timeout attribute on errors.
  TimeoutErrors (which are covered by is_timeout) can't necessarily have attributes added to them.
- Fix backdoor tests
  Skip build info line at interpreter startup. Also, start printing the banner as we read it to aid in future debugging.
- Tolerate __builtins__ being a dict (rather than module) in is_timeout
  (@tipabu) still not sure how this happens, but somehow it does in socket_test.test_error_is_timeout.
  • Loading branch information
tipabu committed Oct 8, 2021
1 parent 690464a commit 15d3c24
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 6 deletions.
5 changes: 4 additions & 1 deletion eventlet/greenio/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@
_original_socket = eventlet.patcher.original('socket').socket


socket_timeout = eventlet.timeout.wrap_is_timeout(socket.timeout)
if sys.version_info >= (3, 10):
socket_timeout = socket.timeout # Really, TimeoutError
else:
socket_timeout = eventlet.timeout.wrap_is_timeout(socket.timeout)


def socket_connect(descriptor, address):
Expand Down
5 changes: 4 additions & 1 deletion eventlet/greenio/py3.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,12 @@ def __exit__(self, *args):
FileIO=GreenFileIO,
os=_original_os,
))
if hasattr(_original_pyio, 'text_encoding'):
_open_environment['text_encoding'] = _original_pyio.text_encoding

_pyio_open = getattr(_original_pyio.open, '__wrapped__', _original_pyio.open)
_open = FunctionType(
six.get_function_code(_original_pyio.open),
six.get_function_code(_pyio_open),
_open_environment,
)

Expand Down
9 changes: 7 additions & 2 deletions eventlet/timeout.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,11 @@ def fun(*args, **kwargs):
return fun


if isinstance(__builtins__, dict): # seen when running tests on py310, but HOW??
_timeout_err = __builtins__.get('TimeoutError', Timeout)
else:
_timeout_err = getattr(__builtins__, 'TimeoutError', Timeout)


def is_timeout(obj):
py3err = getattr(__builtins__, 'TimeoutError', Timeout)
return bool(getattr(obj, 'is_timeout', False)) or isinstance(obj, py3err)
return bool(getattr(obj, 'is_timeout', False)) or isinstance(obj, _timeout_err)
2 changes: 1 addition & 1 deletion tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ def run_isolated(path, prefix='tests/isolated/', **kwargs):

def check_is_timeout(obj):
value_text = getattr(obj, 'is_timeout', '(missing)')
assert obj.is_timeout, 'type={0} str={1} .is_timeout={2}'.format(type(obj), str(obj), value_text)
assert eventlet.is_timeout(obj), 'type={0} str={1} .is_timeout={2}'.format(type(obj), str(obj), value_text)


@contextlib.contextmanager
Expand Down
5 changes: 4 additions & 1 deletion tests/backdoor_test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import os.path
import sys

import eventlet

Expand All @@ -22,7 +23,9 @@ def test_server(self):
def _run_test_on_client_and_server(self, client, server_thread):
f = client.makefile('rw')
assert 'Python' in f.readline()
f.readline() # build info
if sys.version_info < (3, 10):
# Starting in py310, build info is included in version line
f.readline() # build info
f.readline() # help info
assert 'InteractiveConsole' in f.readline()
self.assertEqual('>>> ', f.read(4))
Expand Down

0 comments on commit 15d3c24

Please sign in to comment.