-
-
Notifications
You must be signed in to change notification settings - Fork 30.7k
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
RuntimeError after ctrl-C interrupt when asyncio is closing the threadpool #96827
Comments
What does it do in Python 3.11 (e.g. 3.11rc2, now available from python.org)? |
I tried, and it seems to give a similar traceback.
|
Ouch, this is tricky. I think I understand the last part of the traceback. When a loop is closed, it tries to shut down its default executor. This is done by creating a helper thread (in Interestingly, the traceback has the form
Now both traceback 2 and traceback 3 are reporting an error in So what about traceback 1? This is happening in Still with me? It looks like I'll try to come up with a repro that doesn't require one to hit ^C, and take it from there. |
That sounds right, you might be able to create reproducer with |
I have a fix, but not yet a test. I spent 30-60 minutes trying to come up with a test case, but I'm pretty unhappy with it. The key thing is that we need to aim the keyboard interrupt to happen once However, when I try this, it doesn't always trigger the bug with Python 3.11rc2 or Python 3.10.
```py
import asyncio
import _thread
import time
async def main(): def blocking(loop): try:
|
* When chaining futures, skip callback if loop closed. * When shutting down an executor, don't wake a closed loop.
…nGH-96837) * When chaining futures, skip callback if loop closed. * When shutting down an executor, don't wake a closed loop. (cherry picked from commit e9d6376) Co-authored-by: Guido van Rossum <[email protected]>
…nGH-96837) * When chaining futures, skip callback if loop closed. * When shutting down an executor, don't wake a closed loop. (cherry picked from commit e9d6376) Co-authored-by: Guido van Rossum <[email protected]>
* When chaining futures, skip callback if loop closed. * When shutting down an executor, don't wake a closed loop. (cherry picked from commit e9d6376) Co-authored-by: Guido van Rossum <[email protected]>
* When chaining futures, skip callback if loop closed. * When shutting down an executor, don't wake a closed loop. (cherry picked from commit e9d6376) Co-authored-by: Guido van Rossum <[email protected]>
…n#96837) * When chaining futures, skip callback if loop closed. * When shutting down an executor, don't wake a closed loop.
I'm still seeing this issue on Python 3.11.0 on Windows. That is, if I run the test program in the original comment here and hit Ctrl-C after "coro stop" is printed, I get the same exception traceback:
Did the fix make it into the 3.11.0 release? (I found this issue when trying to debug the same error in a program running a subprocess - I assume that |
I guess we'll have to reopen this. It definitely made it into 3.11 (based on the date it was committed). I am out of bandwidth to personally research this -- do you have time to look into it more? Maybe we only fixed it for Selector event loops and not for the Proactor event loop? |
I'm happy to help, but I don't understand enough about asyncio in general, or the proactor/process implementation in particular, to diagnose what the issue might be. |
I checked on Linux. It appears fixed on 3.10, but not on 3.11. I will try to find out what makes the difference. |
I can't believe. I have installed Python 3.11.0 on Fedora 35 from the Fedora RPMs and the patch for this issue is missing! At least on the On Github:
On Fedora, RPM python3.11-libs-3.11.0-1.fc35.x86_64:
|
The people from Fedora/Redhat used the source tarball to build their RPMs. Here's the thing: I do not see the patched asyncio code in the source tarballs (both xz and gz) on the official download page https://www.python.org/downloads/release/python-3110/ !! Could somebody please check and confirm that, because I still can't believe it. But if I'm not wrong, it explains the report from @pfmoore. |
I have checked that code in my installed copy of Python 3.11.0 on Windows, and I see
So it looks like the patch didn't make it into the Windows 3.11.0 release either 🙁 @pablogsal @zooba is there any possibility that the 3.11 Windows release was done from somewhere other than what's currently on the 3.11 branch? Edit: Never mind, the fix is not on the 3.11.0 tag - see https://github.com/python/cpython/blob/v3.11.0/Lib/asyncio/base_events.py#L577 |
I checked the changelog. The assumption that 3.11.0 (released Oct 24) contains the fix for this issue (patch from Sep 30) is false indeed, thanks @pfmoore for pointing that out. |
So this should be fixed in 3.11.1. That's cool, thanks for the investigation! |
Test program based on a SO question; press Ctrl-C after "coro stop" and before "thread stop":
The output is as expected:
but a stack trace is printed to stderr:
The interrupt occurs in
asyncio.run
at line 49 in the fileasyncio/runners.py
The control returns to the main program (
except KeyboardInterrupt
), but the cleanup waitsuntil the spawned thread terminates and at that time the event loop is closed and the
RuntimeError
occurs.
In my opinion, no
RuntimeError
should happen. Given that the entire user's program is guarded bytry-except
which successfully catches theKeyboardInterrupt
, there is very little a programmercan do to avoid this situation maybe except suppressing the output by redirecting the stderr to /dev/null.
Your environment
Python 3.10
The text was updated successfully, but these errors were encountered: