New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add rudimentary support for Python 3.10 #715
Conversation
This comment has been minimized.
This comment has been minimized.
tests/wsgi_test.py
Outdated
@@ -579,7 +579,8 @@ def wsgi_app(environ, start_response): | |||
sock = eventlet.wrap_ssl( | |||
eventlet.listen(('localhost', 0)), | |||
certfile=certificate_file, keyfile=private_key_file, | |||
server_side=True) | |||
server_side=True, | |||
ssl_version=ssl.PROTOCOL_TLSv1_2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please show which tests fail without this TLS cap.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's this test -- the assert success
at the end fails, and the server prints a traceback like
Traceback (most recent call last):
File "/home/tburke/code/eventlet/tests/wsgi_test.py", line 566, in server
serv.process_request([addr, client_socket, wsgi.STATE_IDLE])
File "/home/tburke/code/eventlet/eventlet/wsgi.py", line 815, in process_request
proto.__init__(conn_state, self)
File "/home/tburke/code/eventlet/eventlet/wsgi.py", line 348, in __init__
self.finish()
File "/home/tburke/code/eventlet/eventlet/wsgi.py", line 729, in finish
BaseHTTPServer.BaseHTTPRequestHandler.finish(self)
File "/usr/lib64/python3.10/socketserver.py", line 811, in finish
self.wfile.close()
File "/usr/lib64/python3.10/socket.py", line 723, in write
return self._sock.send(b)
File "/home/tburke/code/eventlet/eventlet/green/ssl.py", line 193, in send
return self._call_trampolining(
File "/home/tburke/code/eventlet/eventlet/green/ssl.py", line 161, in _call_trampolining
return func(*a, **kw)
File "/usr/lib64/python3.10/ssl.py", line 1203, in send
return self._sslobj.write(data)
ssl.SSLEOFError: EOF occurred in violation of protocol (_ssl.c:2365)
Curiously, the test passes on py39, even when using TLS 1.3. On both versions of Python, I confirmed that TLSv1.3 was in fact negotiated by adding a print(client.version())
after sending the X
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we miss close_notify
in green/ssl. https://datatracker.ietf.org/doc/html/rfc8446#section-6.1
Good news! |
@tipabu for DB tests, you'd have both mysql and postgresql running and this export EVENTLET_DB_TEST_AUTH='{"psycopg2": {"host": "127.0.0.1", "port": 5432, "user": "postgres", "password": "secret"}, "MySQLdb": {"host": "127.0.0.1", "port": 3306, "passwd": "secret", "user": "root"}}' |
Just out of curiosity. From the three distributions available at https://pypi.org/project/nose/#files only |
FYI this also happens on 3.10b3.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good news: I can get away without most of the changes in greenio.
Bad news: somewhere between 3.10.0b1 and 3.10.0rc1, test_patcher_existing_locks_locked
started failing with RuntimeError: cannot release un-acquired lock
around
lock.release() |
I'm still scratching my head over that one. It looks like gc.get_referrers(old)
is mostly returning lists and dicts, though? I wonder if it's somehow related to the trouble I was seeing with __builtins__
showing up as a dict in socket_test.test_error_is_timeout...
@tipabu think we can merge parts of this work that are clearly working and backward compatible, like timeout? |
Sorry for the late reply -- I'm perfectly happy to have this merge in parts; whatever you think is ready. |
@tipabu is this fixed by |
@tipabu moved TLS cap commit into separate branch in hope we can fix it with close_notify. |
Yeah, all of the locking I'd tried in |
On py310, socket.timeout is TimeoutError, which our is_timeout() helper func already knows is a timeout. Note that this doesn't get us to py310 support (not by a long shot), but it's a step along the way. Closes eventlet#687
_pyio.open is now a staticmethod, so we've got to go down to _pyio.open.__wrapped__ to get to the python function object.
...rather than requiring an is_timeout attribute on errors. TimeoutErrors (which are covered by is_timeout) can't necessarily have attributes added to them.
Python 3.10 started including build info on the version line, so the expectation in tests had to change. Also, start printing the banner as we read it to aid in future debugging.
I'm still not sure how this happens, but somehow it does in socket_test.test_error_is_timeout. As a result, is_timeout wouldn't get a reference to TimeoutError, so the socket error would not be correctly identified as a timeout.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@tipabu thank you very much, great job. |
Hi @temoto , Can you mention specific date & version (or revision) of your next release where this fix will be included? |
@rahuledb v0.33.0 update: released |
I'm still getting this with eventlet==0.33.0 and python 3.10.0 - using with gunicorn
|
@roedoejet Please can you check what version of dnspython you have installed? I guess eventlet needs to require dnspython>=2. |
OK, I updated dnspython to 2.1.0, but now get this error:
Which seems related to #702 but I am using gunicorn 20.1.0 |
@roedoejet Benoit has accepted fix in gunicorn/master but didn't release. pip (requirements) works with git links to specific commit. |
There's still work to be done:
dnspython<2.0.0
has a reference tocollections.MutableMapping
which was removed in favor ofcollections.abc.MutableMapping
. Our dependency will need to be updated. See also: eventlet is incompatible with dnspython 2.0.0rc1 #619.nose
has a reference tocollections.Callable
which was similarly removed forcollections.abc.Callable
. Our test infrastructure will need to be updated to support testing py310 in CI. See also: WIP: Remove dependency on nose #638.Manually fixing those references in my local Python 3.10 env, though, I see
EVENTLET_HUB
selects
poll
epolls
Looks like the skips were largely DB- and ZMQ-related tests -- not sure what the extra skip was about when not explicitly specifying a hub.
Feedback is welcome; much of this seems... less than ideal:
greenio._open
requires additional locking, and callers in a mixed greenthread/pthread-enabled process may unexpectedly useGreenFileIO
when calling_pyio.open
.PROTOCOL_TLSv1_2
constant used was deprecated in py36 and may later be removed.dict
/module
floppiness of__builtins__
inis_timeout
is quite strange and also warrants further investigation.