Skip to content
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

DeprecationWarning scope expanded in asyncio.events #100160

Open
jaraco opened this issue Dec 10, 2022 · 13 comments
Open

DeprecationWarning scope expanded in asyncio.events #100160

jaraco opened this issue Dec 10, 2022 · 13 comments
Assignees
Labels
3.10 3.11 release-blocker type-bug An unexpected behavior, bug, or error

Comments

@jaraco
Copy link
Member

jaraco commented Dec 10, 2022

As discovered in prompt-toolkit/python-prompt-toolkit#1696, it appears that the DeprecationWarning introduced in Python 3.10 has expanded its scope, now with 3.11.1 and 3.10.9 emitting during get_event_loop_policy() where it did not before:

 ~ $ py -3.11 -W error
Python 3.11.0 (main, Oct 26 2022, 19:06:18) [Clang 14.0.0 (clang-1400.0.29.202)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import asyncio
>>> asyncio.get_event_loop_policy().get_event_loop()
<_UnixSelectorEventLoop running=False closed=False debug=False>
>>> ^D
 ~ $ docker run -it jaraco/multipy-tox py -3.11 -W error
Python 3.11.1 (main, Dec  7 2022, 01:11:34) [GCC 11.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import asyncio
>>> asyncio.get_event_loop_policy().get_event_loop()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.11/asyncio/events.py", line 687, in get_event_loop
    warnings.warn('There is no current event loop',
DeprecationWarning: There is no current event loop

It's not obvious if it was intentional to expand the scope of the DeprecationWarning, but it does come as a surprise as the calling code had previously attempted to address the deprecation.

I think there are two concerns to be addressed:

  • Does this symptom indicate an unintentional but real additional path that was previously unprotected by the DeprecationWarning? And if so, does that imply that the behavior's first true deprecation is in Python 3.12 and thus will delay the removal?
  • What is a user expected to do to properly address the deprecation? I read the what's new for Python 3.10 and it indicates that the call is deprecated, but it provides little guidance on how a user can adapt to the new behavior. Maybe there should be a note to the effect of "programs relying on a non-running event loop must ensure that there is a running event loop before attempting to get the event loop."

Linked PRs

@jaraco jaraco added the type-bug An unexpected behavior, bug, or error label Dec 10, 2022
@gvanrossum
Copy link
Member

gvanrossum commented Dec 10, 2022

@kumaraditya303 @serhiy-storchaka Looks like the 3.12 code somehow made it into 3.11.1 (and 3.10.9). We should roll this back.

the culprit appears to be #93453.

@kumaraditya303
Copy link
Contributor

kumaraditya303 commented Dec 10, 2022

I am confused, yes there is a change in behavior but it is correct. You need to set the event loop before getting it alternatively use the runner APIs.

I looked at the code and it is missing setting the event loop:
https://github.com/prompt-toolkit/python-prompt-toolkit/blob/da05f669d00817655f76b82972272d4d5f4d4225/src/prompt_toolkit/eventloop/utils.py#L106-L118 The last line gets the event loop without setting it. Am I missing something?

@gvanrossum
Copy link
Member

gvanrossum commented Dec 10, 2022

In pre-3.12 semantics, the first ever get_event_loop() call (if in the main thread) creates a new loop and sets it as the current loop. Apparently those semantics were lost?

@gvanrossum
Copy link
Member

gvanrossum commented Dec 10, 2022

We shouldn't have a change in behavior between 3.11.0 and 3.11.1.

@serhiy-storchaka
Copy link
Member

serhiy-storchaka commented Dec 10, 2022

It was an intentional change based on results of discussion in #93453. BaseDefaultEventLoopPolicy.get_event_loop() will raise an exception in 3.12.

A user is expected to only use get_event_loop() if an event loop was previously set by set_event_loop(), and use new_event_loop() for explicit creation of the event loop. But if you do not know whether an even loop was previously set, the only workaround is silencing DeprecationWarning for the line with get_event_loop().

@gvanrossum
Copy link
Member

gvanrossum commented Dec 10, 2022

I'm guessing it's unfortunate that we have a deprecation warning in 3.11.1 that wasn't there in 3.11.0, and ditto for 3.10.9 vs. 3.10.8. That's not normally how we do deprecations (unless it's security related).

I'd like an opinion from an SC member -- let me tag @gpshead, he can decide whether to escalate this to the SC agenda or whatever.

@gpshead
Copy link
Member

gpshead commented Dec 11, 2022

New warnings from existing code paths should not normally happen in patch releases. It is unfortunate that this change already shipped in 3.10.9 and 3.11.1. I recommend undoing it in both branches.

Release manager @pablogsal, Is this worth rolling 3.10.10 and 3.11.2 releases for? At least two projects disrupted by the warning change have linked to this issue so far (python-prompt-toolkit and tqdm). There will presumably always be people using 3.10.9 and 3.11.1 so impacted projects may need to carry workarounds forever regardless. Questions to consider:

  • Is that just in those project's tests where DeprecationWarning is enabled?
  • Or does it impact their transitive users?
  • Who else calls the API in this situation getting implicit event loop creation that we don't yet know about?

From #93453:

But then we will have a weird situation, when some code emits a Deprecation warning in 3.10-3.11, but works without warning before 3.10 and after 3.11. Should we undeprecate this case in the future bugfix releases of 3.10 and/or 3.11? It would be not so easy.

The thing to do in this kind of situation is to either leave the existing warning as is in the stable releases, or remove it entirely. (It is fine if we marked something as deprecated in a release and later change our mind and opt not to deprecate it).

What I think happened here appears to be that an attempt to narrow the warning to reflect a new plan was made. This wound up moving the warning to happen from different API calls. The original released warning was removed (fine), but a new location raising the warning was added to a different call path. As seen in the tests: test_get_event_loop() added a new assertion that a DeprecationWarning was raised. That should be a red flag in stable releases. This kind of hiccup might be expected in a first patch 3.11.1 if it were correcting an accident for a warning just added in 3.11, but is never expected in a later lifecycle patch like 3.10.9.

We still need a Deprecation warning in 3.10-3.11 for the case when a new event loop is implicitly created.

Strictly speaking this was a bug that the warning wasn't raised in those releases. The lack of warning about an upcoming behavior change should be considered a reason to delay making the change. ie: restore the implicit event loop creation in 3.12 and remove it in 3.14. I reopened #93453 with such a comment.

@serhiy-storchaka
Copy link
Member

serhiy-storchaka commented Dec 11, 2022

Plan A:

  1. Remove any deprecation warnings in 3.10 and 3.11.
  2. Restore implicit creation of an event loop in 3.12 and add a deprecation warning.
  3. Keep a warning in 3.13.
  4. Remove implicit creation of an event loop in 3.14.

Plan B:

  1. Remove any deprecation warnings in 3.10.
  2. Keep a deprecation warning in 3.11.
  3. Restore implicit creation of an event loop in 3.12 and add a deprecation warning.
  4. Remove implicit creation of an event loop in 3.13.

Plan C:

  1. Do nothing (except maybe changing the documentation more).

@jaraco
Copy link
Member Author

jaraco commented Dec 11, 2022

  • Or does it impact their transitive users?

For prompt toolkit, it does affect transitive users including those of xonsh, who see the warning emitted when the shell starts.

@gvanrossum
Copy link
Member

gvanrossum commented Dec 11, 2022

I think it has to be plan A.

@blink1073
Copy link

blink1073 commented Dec 19, 2022

FWIW you can add several jupyter packages to affected users. We would also prefer plan A.

@gvanrossum
Copy link
Member

gvanrossum commented Dec 21, 2022

@serhiy-storchaka Is there a PR yet? Should I label this as release blocker for the next 3.10 and 3.11 releases?

@pablogsal
Copy link
Member

pablogsal commented Dec 21, 2022

I think it has to be plan A.

I concur with this

Should I label this as release blocker for the next 3.10 and 3.11 releases?

I went ahead and add it myself 👍

serhiy-storchaka added a commit to serhiy-storchaka/cpython that referenced this issue Dec 21, 2022
Partially revert changes made in pythonGH-93453.

asyncio.DefaultEventLoopPolicy.get_event_loop() now emits a
DeprecationWarning and creates and sets a new event loop instead of
raising a RuntimeError if there is no current event loop set.
serhiy-storchaka added a commit to serhiy-storchaka/cpython that referenced this issue Dec 21, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.10 3.11 release-blocker type-bug An unexpected behavior, bug, or error
Projects
Status: Todo
Development

No branches or pull requests

7 participants