-
-
Notifications
You must be signed in to change notification settings - Fork 31.9k
Endless recursion in repr of asyncio.Future if a callback uses the Future itself as argument #93837
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
Comments
|
Can you specify what should be the intended behavior? From the title it seems that you are getting a recursion error which isn't the case. |
|
This is just a thing we stumbled over in MeVisLab 3.5, where we currently use Python 3.9.11. I believe the recursion error is caught internally by reprlib, but it crashes in the Debug mode of MeVisLab, possibly because the stack segment isn't big enough then. Anyway, I believe this should be caught early. I had a look at the code and it doesn't seem this is caught other than by running into the recursion limit, which seems to be risky. You can make the recursion visible by setting self.maxother = 10000 in reprlib.py, then you get
The I also checked with Python 3.10.5, the behavior hasn't changed. |
|
I was also able to provoke a crash by adding |
|
I am unable to reproduce the crash with this: import sys
sys.setrecursionlimit(3000)
import asyncio
import functools
def test():
fut = asyncio.Future()
def done_cb(arg):
pass
fut.add_done_callback(functools.partial(done_cb, fut))
print(repr(fut))
test()It would be better if you can provide a complete script to reproduce it and test it on main branch. |
|
Hi! I noticed that if I run this on Windows from a GIT bash, it isn't apparent that the script crashed, one is just missing some output after the DeprecationWarning (obviously you should at least see "Done"). If you run this from a CMD shell, you get a crash dialog. |
|
Reproduced on D:\python\main\main.py:8: DeprecationWarning: There is no current event loop
fut = asyncio.Future()
Windows fatal exception: stack overflow
Current thread 0x00001280 (most recent call first):
File "C:\Program Files\Python310\lib\reprlib.py", line 52 in repr
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 38 in <genexpr>
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 38 in _format_args_and_kwargs
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 56 in _format_callback
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 47 in _format_callback
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 23 in _format_callback_source
File "C:\Program Files\Python310\lib\asyncio\base_futures.py", line 32 in format_cb
File "C:\Program Files\Python310\lib\asyncio\base_futures.py", line 35 in _format_callbacks
File "C:\Program Files\Python310\lib\asyncio\base_futures.py", line 76 in _future_repr_info
File "C:\Program Files\Python310\lib\reprlib.py", line 139 in repr_instance
File "C:\Program Files\Python310\lib\reprlib.py", line 62 in repr1
File "C:\Program Files\Python310\lib\reprlib.py", line 52 in repr
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 38 in <genexpr>
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 38 in _format_args_and_kwargs
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 56 in _format_callback
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 47 in _format_callback
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 23 in _format_callback_source
File "C:\Program Files\Python310\lib\asyncio\base_futures.py", line 32 in format_cb
File "C:\Program Files\Python310\lib\asyncio\base_futures.py", line 35 in _format_callbacks
File "C:\Program Files\Python310\lib\asyncio\base_futures.py", line 76 in _future_repr_info
File "C:\Program Files\Python310\lib\reprlib.py", line 139 in repr_instance
File "C:\Program Files\Python310\lib\reprlib.py", line 62 in repr1
File "C:\Program Files\Python310\lib\reprlib.py", line 52 in repr
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 38 in <genexpr>
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 38 in _format_args_and_kwargs
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 56 in _format_callback
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 47 in _format_callback
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 23 in _format_callback_source
File "C:\Program Files\Python310\lib\asyncio\base_futures.py", line 32 in format_cb
File "C:\Program Files\Python310\lib\asyncio\base_futures.py", line 35 in _format_callbacks
File "C:\Program Files\Python310\lib\asyncio\base_futures.py", line 76 in _future_repr_info
File "C:\Program Files\Python310\lib\reprlib.py", line 139 in repr_instance
File "C:\Program Files\Python310\lib\reprlib.py", line 62 in repr1
File "C:\Program Files\Python310\lib\reprlib.py", line 52 in repr
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 38 in <genexpr>
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 38 in _format_args_and_kwargs
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 56 in _format_callback
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 47 in _format_callback
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 23 in _format_callback_source
File "C:\Program Files\Python310\lib\asyncio\base_futures.py", line 32 in format_cb
File "C:\Program Files\Python310\lib\asyncio\base_futures.py", line 35 in _format_callbacks
File "C:\Program Files\Python310\lib\asyncio\base_futures.py", line 76 in _future_repr_info
File "C:\Program Files\Python310\lib\reprlib.py", line 139 in repr_instance
File "C:\Program Files\Python310\lib\reprlib.py", line 62 in repr1
File "C:\Program Files\Python310\lib\reprlib.py", line 52 in repr
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 38 in <genexpr>
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 38 in _format_args_and_kwargs
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 56 in _format_callback
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 47 in _format_callback
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 23 in _format_callback_source
File "C:\Program Files\Python310\lib\asyncio\base_futures.py", line 32 in format_cb
File "C:\Program Files\Python310\lib\asyncio\base_futures.py", line 35 in _format_callbacks
File "C:\Program Files\Python310\lib\asyncio\base_futures.py", line 76 in _future_repr_info
File "C:\Program Files\Python310\lib\reprlib.py", line 139 in repr_instance
File "C:\Program Files\Python310\lib\reprlib.py", line 62 in repr1
File "C:\Program Files\Python310\lib\reprlib.py", line 52 in repr
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 38 in <genexpr>
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 38 in _format_args_and_kwargs
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 56 in _format_callback
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 47 in _format_callback
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 23 in _format_callback_source
File "C:\Program Files\Python310\lib\asyncio\base_futures.py", line 32 in format_cb
File "C:\Program Files\Python310\lib\asyncio\base_futures.py", line 35 in _format_callbacks
File "C:\Program Files\Python310\lib\asyncio\base_futures.py", line 76 in _future_repr_info
File "C:\Program Files\Python310\lib\reprlib.py", line 139 in repr_instance
File "C:\Program Files\Python310\lib\reprlib.py", line 62 in repr1
File "C:\Program Files\Python310\lib\reprlib.py", line 52 in repr
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 38 in <genexpr>
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 38 in _format_args_and_kwargs
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 56 in _format_callback
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 47 in _format_callback
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 23 in _format_callback_source
File "C:\Program Files\Python310\lib\asyncio\base_futures.py", line 32 in format_cb
File "C:\Program Files\Python310\lib\asyncio\base_futures.py", line 35 in _format_callbacks
File "C:\Program Files\Python310\lib\asyncio\base_futures.py", line 76 in _future_repr_info
File "C:\Program Files\Python310\lib\reprlib.py", line 139 in repr_instance
File "C:\Program Files\Python310\lib\reprlib.py", line 62 in repr1
File "C:\Program Files\Python310\lib\reprlib.py", line 52 in repr
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 38 in <genexpr>
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 38 in _format_args_and_kwargs
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 56 in _format_callback
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 47 in _format_callback
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 23 in _format_callback_source
File "C:\Program Files\Python310\lib\asyncio\base_futures.py", line 32 in format_cb
File "C:\Program Files\Python310\lib\asyncio\base_futures.py", line 35 in _format_callbacks
File "C:\Program Files\Python310\lib\asyncio\base_futures.py", line 76 in _future_repr_info
File "C:\Program Files\Python310\lib\reprlib.py", line 139 in repr_instance
File "C:\Program Files\Python310\lib\reprlib.py", line 62 in repr1
File "C:\Program Files\Python310\lib\reprlib.py", line 52 in repr
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 38 in <genexpr>
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 38 in _format_args_and_kwargs
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 56 in _format_callback
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 47 in _format_callback
File "C:\Program Files\Python310\lib\asyncio\format_helpers.py", line 23 in _format_callback_source
File "C:\Program Files\Python310\lib\asyncio\base_futures.py", line 32 in format_cb
File "C:\Program Files\Python310\lib\asyncio\base_futures.py", line 35 in _format_callbacks
File "C:\Program Files\Python310\lib\asyncio\base_futures.py", line 76 in _future_repr_info
File "C:\Program Files\Python310\lib\reprlib.py", line 139 in repr_instance
File "C:\Program Files\Python310\lib\reprlib.py", line 62 in repr1
File "C:\Program Files\Python310\lib\reprlib.py", line 52 in repr
...
However it is documented 1 that manually setting Footnotes |
|
I just want to repeat my point, that an (potential) endless recursion in this method should be avoided. The recursion isn't visible because the RecursionError is caught in the code and I proposed to increase the recursion limit to prove that there indeed is a problem, even if it normally isn't visible. At minimum this is a potential performance issue (because a lot of code is executed pointlessly to produce a string which is dropped for the most part) |
Under certain circumstances this line in `aiorun` can trigger the following Python bug python/cpython#93837 The program will crash with a stack overflow error, probably because the call to log the task about the be cancelled will call repr on a task that references itself somehow.
Under certain circumstances this line in `aiorun` can trigger the following Python bug python/cpython#93837 The program will crash with a stack overflow error, probably because the call to log the task about the be cancelled will call repr on a task that references itself somehow.
|
I think it is fixed by #91195 for Python 3.11+ |
|
@asvetlov Was the added |
|
@freakboy3742 sorry, |


Bug report
I encountered an endless recursion when doing a repr of a asyncio.Future where a callback, which references the Future itself through functools.partial, is added. This crashes when doing this in a Debug version of Python, but somehow recovers on the Release version.
Try this to reproduce:
The output in the Release version is
where you can see at least part of the recursion.
An incomplete fix for the recursion problem has already been done for bpo-42183, but this didn't cover the callbacks.
Your environment
Propose patch
I have a patch that fixes the problem for me by including all of the Future's state in the recursion guard:
The text was updated successfully, but these errors were encountered: