Kyle Stanley <aeros...@gmail.com> added the comment:

FWIW, I agree with get_event_loop() being problematic with its error messages, 
and having a bit too much functionality in a single function from an API design 
perspective. It commonly comes up as an issue among asyncio users in 
communities that I'm active in. 

Typically, I advise them to use get_running_loop() where possible, as it can be 
directly substituted within a coroutine func. For __init__ methods, I recommend 
setting their internal loop attribute to None and then setting it to 
get_running_loop() in either a coro start() method or coro factory method. 
Outside of directly managing the event loop, this works for many use cases. 
When it's needed to actually create one, I advise them to use new_event_loop(), 
but mention that it's already handled if they're using asyncio.run().

Andrew Svetlov wrote:
> The asyncio.get_event_loop() function will stay in Python for a while in 
> deprecated status. I don't know the exact period but it should be 3 releases 
> at least I guess, with possibly extending to 5 releases if needed.

With how many libraries that rely on it, I suspect it will likely be a very 
slow transition from deprecation to removal. 4 versions seems like a reasonable 
period to me, but I think that 3 may be too short (assuming we retain the newer 
annual release cycle).

Yury Selivanov wrote:
> I think we still use get_event_loop() in asyncio code, no?

Indeed, we currently use it in several places throughout asyncio. From a brief 
glace using git grep "get_event_loop()":

Lib/asyncio/futures.py:76:            self._loop = events.get_event_loop()
Lib/asyncio/futures.py:390:        loop = events.get_event_loop()
Lib/asyncio/locks.py:81:            self._loop = events.get_event_loop()
Lib/asyncio/locks.py:177:            self._loop = events.get_event_loop()
Lib/asyncio/locks.py:244:            self._loop = events.get_event_loop()
Lib/asyncio/locks.py:375:            self._loop = events.get_event_loop()
Lib/asyncio/queues.py:35:            self._loop = events.get_event_loop()
Lib/asyncio/streams.py:45:        loop = events.get_event_loop()
Lib/asyncio/streams.py:82:        loop = events.get_event_loop()
Lib/asyncio/streams.py:104:            loop = events.get_event_loop()
Lib/asyncio/streams.py:120:            loop = events.get_event_loop()
Lib/asyncio/streams.py:147:            self._loop = events.get_event_loop()
Lib/asyncio/streams.py:403:            self._loop = events.get_event_loop()
Lib/asyncio/subprocess.py:206:        loop = events.get_event_loop()
Lib/asyncio/subprocess.py:227:        loop = events.get_event_loop()
Lib/asyncio/tasks.py:69:        loop = events.get_event_loop()
Lib/asyncio/tasks.py:129:            loop = events.get_event_loop()
Lib/asyncio/tasks.py:590:        loop = events.get_event_loop()
Lib/asyncio/tasks.py:669:            loop = events.get_event_loop()
Lib/asyncio/tasks.py:751:            loop = events.get_event_loop()

For brevity, I omitted the docs, tests, and the function definition for 
get_event_loop().

Based on Serhiy's idea (of making get_event_loop() an alias for 
get_running_loop() without warning inside of a coro func, but warning for using 
it outside of one), many of the above could remain as is to reduce some code 
churn. We just have to make sure the documentation is updated to reflect 
get_event_loop() becoming an alias for get_running_loop(), at the same time as 
the deprecation warning is added for using it outside of a coro func. 
Otherwise, I suspect it could lead to significant confusion from users that 
have warnings enabled.

That being said, I think we should eventually remove asyncio.get_event_loop() 
entirely from the asyncio internals, including the ones that wouldn't raise 
deprecation warnings (if/when it's made an alias to get_running_loop()) for 
improved clarity. Personally, I find that even the name get_event_loop() is 
rather vague; get_running_loop() is much more obvious as to its purpose and 
what it does from a readability perspective.

Yury Selivanov wrote:
> If we do, we should start by raising deprecation warnings in those call 
> sites, e.g. if a Future or Lock is created outside of a coroutine and no 
> explicit event loop is passed.

For asyncio.Lock (plus other synchronization primitives) and asyncio.Queue, 
this would be added in https://github.com/python/cpython/pull/18195. Currently 
waiting on emanu (author of the PR) to finish up some changes, but it's mostly 
complete. Could I work on adding it to asyncio.Future and other classes in the 
meantime?

One point to be clarified though: you mention "created outside of a coroutine 
and no explicit event loop is passed". However, there are already several 
deprecations in place for passing an explicit event loop for most (if not all) 
of the __init__ methods for objects across asyncio's high-level API. In those 
cases, should the deprecation for creating the object outside of a coroutine 
function care about whether or not an explicit event loop is passed?

I can see why it would matter for the lower level parts of the API (such as 
asyncio.Future) where passing the event loop explicitly is still allowed, but 
IMO it shouldn't be a factor for ones where passing the event loop explicitly 
is already deprecated. Especially considering that the loop argument will be 
removed from those entirely in 3.10 (according to the version listed in the 
current deprecation warnings added in 3.8).

----------
nosy: +aeros

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue39529>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to