Add a compatibility layer for the asyncio changes in Python 3.14.0a4.#558
Add a compatibility layer for the asyncio changes in Python 3.14.0a4.#558freakboy3742 merged 3 commits intomainfrom
Conversation
src/rubicon/objc/eventloop.py
Outdated
| ) | ||
| policy = EventLoopPolicy() | ||
| set_event_loop_policy(policy) | ||
| return new_event_loop() |
There was a problem hiding this comment.
I expect rubicon-objc to be typically used in cases where it's ok to set the event loop policy globally. However, it might be a bit less invasive and more compatible with the Python 3.14 approach if we return the event loop instance without any side effects. For example:
policy = EventLoopPolicy()
return policy.get_event_loop()WDYT?
There was a problem hiding this comment.
So... get_event_loop() has been deprecated as well (and has been for a couple of releases).
The Python PR that triggered this change documents the "suggested" API usage as:
loop = MyCustomEventLoop()
loop.run_until_complete(task)
There was a problem hiding this comment.
So... python/cpython#83710 (and has been for a couple of releases).
How about the following then?
policy = EventLoopPolicy()
return policy.new_event_loop()
This might be stupid question, but why special case Python < 3.14 at all? Could we use the "suggested" API usage and instantiate the CFEventLoop directly on older Python versions as well?
There was a problem hiding this comment.
How about the following then?
policy = EventLoopPolicy() return policy.new_event_loop()
That's functionally identical to asyncio.new_event_loop() - but I guess it doesn't hurt to be explicit about which policy is creating the loop and avoiding a function call.
This might be stupid question, but why special case Python < 3.14 at all? Could we use the "suggested" API usage and instantiate the
CFEventLoopdirectly on older Python versions as well?
In < 3.14, there are still some functions on the policy - child watchers, mechanisms to get the default loop, and so on. For maximum compatibility, I figured it was best to preserve the old API until it is fully deprecated.
| from asyncio import ( | ||
| _AbstractEventLoopPolicy as AbstractEventLoopPolicy, | ||
| _DefaultEventLoopPolicy as DefaultEventLoopPolicy, | ||
| ) |
There was a problem hiding this comment.
I assume those imports will stop working with Python 3.16. Is there anything we can do to prepare for this now in addition to the deprecation warning below?
There was a problem hiding this comment.
Sure - since we know the deprecation will be finalised with 3.16, we can make these imports and the actual EventLoopPolicy definition conditional on version_info < (3, 16). That way, when, in 6 years time, we run the pyupgrade with the 3.16 minimum version, all the dead code will be automatically removed.
There was a problem hiding this comment.
Thanks! No strong opinions here, I'll leave it to you whether you think thats worth doing :)
Python 3.14.0a4 deprecated the use of custom EventLoopPolicy instances, in favor of instantiating custom event loops directly. This PR adapts to that change by:
iscoroutinefunctionthat raises now warnings in Python 3.14.RubiconEventLoop()as a public API. On Python 3.14+, this is the CFEventLoop class; on earlier versions, it is a wrapper method that creates and installs an event loop policy, then creates a new event loop.This approach should be backwards compatible. Any code using the old policy-based approach will continue to work, but will raise a DeprecationWarning advising users to switch to the
RubiconEventLoop()approach. Code using theRubiconEventLoop()approach will work on all supported versions of Python, and won't raise a warning (even though technically it is using the deprecated EventLoopPolicy class.Fixes #557.
PR Checklist: