-
Notifications
You must be signed in to change notification settings - Fork 3
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
Make compatible with Python 3.12 #120
Conversation
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.
Auto-approved 👍. This diff qualified for automatic approval and doesn't need follow up review.
3232421
to
03d0629
Compare
Yeah, hopefully we can rewrite a lot of synchronicity to not need much of
this in the near future
…On Wed, Jan 17, 2024 at 1:45 PM Michael Waskom ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In synchronicity/synchronizer.py
<#120 (comment)>
:
> + if hasattr(obj, "__dict__"):
+ if self._wrapped_attr not in obj.__dict__:
+ if isinstance(obj.__dict__, dict):
+ # This works for instances
+ obj.__dict__.setdefault(self._wrapped_attr, {})
+ else:
+ # This works for classes & functions
+ setattr(obj, self._wrapped_attr, {})
+ interfaces = obj.__dict__[self._wrapped_attr]
+ else:
+ # e.g., TypeVar in Python>=3.12
+ if not hasattr(obj, self._wrapped_attr):
Makes sense; the resulting code is cumbersome but not unbearably so imo.
—
Reply to this email directly, view it on GitHub
<#120 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AASII2WLJS4LPIK3XDTJHC3YO7BVTAVCNFSM6AAAAABB5BR7NGVHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMYTQMRXGIYTOOJTG4>
.
You are receiving this because your review was requested.Message ID:
***@***.***>
|
While passing tests, the following traceback is printed out when Exception in thread Thread-1 (thread_inner):
Traceback (most recent call last):
File "/usr/lib/python3.12/threading.py", line 1073, in _bootstrap_inner
self.run()
File "/usr/lib/python3.12/threading.py", line 1010, in run
self._target(*self._args, **self._kwargs)
File "/home/ubuntu/venvs/py312/lib/python3.12/site-packages/synchronicity/synchronizer.py", line 159, in thread_inner
asyncio.run(loop_inner())
File "/usr/lib/python3.12/asyncio/runners.py", line 193, in run
with Runner(debug=debug, loop_factory=loop_factory) as runner:
File "/usr/lib/python3.12/asyncio/runners.py", line 62, in __exit__
self.close()
File "/usr/lib/python3.12/asyncio/runners.py", line 72, in close
loop.run_until_complete(
File "/usr/lib/python3.12/asyncio/base_events.py", line 684, in run_until_complete
return future.result()
^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/asyncio/base_events.py", line 596, in shutdown_default_executor
thread.start()
File "/usr/lib/python3.12/threading.py", line 992, in start
_start_new_thread(self._bootstrap, ())
RuntimeError: can't create new thread at interpreter shutdown I suspect this is Python 3.12 related because I found an issue on |
Here is the relevant Python change: python/cpython@ce558e6 |
Ahhh, graceful shutdown handling in synchronicity has been a long standing issue in general and has been on my todo. I even started a PR working on related code here: #113 |
I still can't quite figure out how we're tripping the "can't start a new thread at shutdown" exception shown above. How do we feel about just swallowing it, e.g. @@ -156,7 +156,11 @@ class Synchronizer:
is_ready.set()
await self._stopping.wait() # wait until told to stop
- asyncio.run(loop_inner())
+ try:
+ asyncio.run(loop_inner())
+ except RuntimeError as exc:
+ if "can't create new thread at interpreter shutdown" not in str(exc):
+ raise exc
self._thread = threading.Thread(target=thread_inner, daemon=True)
self._thread.start() |
In my experience it has been things like standard library dns lookups in shutdown handlers that trigger this error, since they use |
This PR adds Python 3.11 and 3.12 to the CI build and addresses an issue that popped up when doing so (which blocks
modal-client
from being Python 3.12 compatible).In Python 3.12,
TypeVar
no longer has a__dict__
attribute. I gather that is a result of the work done to implement PEP695, although I haven't surfaced any specific discussion of this apparently abrupt API break onTypeVar
. That caused a few manipulations insynchronicity
to fail.There's also a new behavior in Python 3.12 where a
RuntimeError
is raised when functions registered withatexit
start a new thread. We're seeing that coming out of synchronicity but aren't completely sure why. Since no behavior depends on the old behavior we're just going to swallow the exception for now and revisit later.Also 3.7 is EOL, so I am dropping it from our CI matrix and bumping the
python-requires
inpyproject.toml
. We recently dropped 3.7 support from the modal client too.Fixes #118