X Tutup
The Wayback Machine - https://web.archive.org/web/20250519072429/https://github.com/python/cpython/issues/93837
Skip to content

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

Closed
usiems opened this issue Jun 15, 2022 · 10 comments
Labels
stdlib Python modules in the Lib dir topic-asyncio type-bug An unexpected behavior, bug, or error

Comments

@usiems
Copy link

usiems commented Jun 15, 2022

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:

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()

The output in the Release version is

<Future pending cb=[test..done_cb(<Future pendi...ion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>

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

  • CPython versions tested on: Python 3.9.12, 3.9.11 (self-compiled)
  • Operating system and architecture: Windows, Intel

Propose patch

I have a patch that fixes the problem for me by including all of the Future's state in the recursion guard:

diff --git i/Lib/asyncio/base_futures.py w/Lib/asyncio/base_futures.py
index 2c01ac9..ee60e93 100644
--- i/Lib/asyncio/base_futures.py
+++ w/Lib/asyncio/base_futures.py
@@ -55,26 +55,24 @@ _repr_running = set()
 def _future_repr_info(future):
     # (Future) -> str
     """helper function for Future.__repr__"""
-    info = [future._state.lower()]
-    if future._state == _FINISHED:
-        if future._exception is not None:
-            info.append(f'exception={future._exception!r}')
-        else:
-            key = id(future), get_ident()
-            if key in _repr_running:
-                result = '...'
-            else:
-                _repr_running.add(key)
-                try:
-                    # use reprlib to limit the length of the output, especially
-                    # for very long strings
-                    result = reprlib.repr(future._result)
-                finally:
-                    _repr_running.discard(key)
-            info.append(f'result={result}')
-    if future._callbacks:
-        info.append(_format_callbacks(future._callbacks))
-    if future._source_traceback:
-        frame = future._source_traceback[-1]
-        info.append(f'created at {frame[0]}:{frame[1]}')
-    return info
+
+    key = id(future), get_ident()
+    if key in _repr_running:
+        return ['... [recursion]']
+    else:
+        _repr_running.add(key)
+        try:
+            info = [future._state.lower()]
+            if future._state == _FINISHED:
+                # use reprlib to limit the length of the output, especially
+                # for very long strings
+                result = reprlib.repr(future._result)
+                info.append(f'result={result}')
+            if future._callbacks:
+                info.append(_format_callbacks(future._callbacks))
+            if future._source_traceback:
+                frame = future._source_traceback[-1]
+                info.append(f'created at {frame[0]}:{frame[1]}')
+            return info
+        finally:
+            _repr_running.discard(key)
@usiems usiems added the type-bug An unexpected behavior, bug, or error label Jun 15, 2022
@hugovk hugovk added the stdlib Python modules in the Lib dir label Jun 15, 2022
@kumaraditya303
Copy link
Contributor

kumaraditya303 commented Jun 15, 2022

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.
I tried it on main branch debug build and there was no error. Also Python 3.9 is security fix only so you should test Python 3.10+.

@kumaraditya303 kumaraditya303 added the pending The issue will be closed if no feedback is provided label Jun 15, 2022
@usiems
Copy link
Author

usiems commented Jun 15, 2022

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

<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future pending cb=[test.<locals>.done_cb(<Future instance at 0x1f405c14cc0>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>)() at C:\Users\usiems\Documents\MeVisLab\future_repr_recursion_bug.py:6]>

The <Future instance at 0x1f405c14cc0> in the middle is where Repr.repr_instance catches the recursion error. The string is normally shortened afterwards.

I also checked with Python 3.10.5, the behavior hasn't changed.

@usiems
Copy link
Author

usiems commented Jun 15, 2022

I was also able to provoke a crash by adding
sys.setrecursionlimit(3000)
to the test

@kumaraditya303
Copy link
Contributor

kumaraditya303 commented Jul 12, 2022

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.

@usiems
Copy link
Author

usiems commented Jul 13, 2022

Hi!
This is a modified full script:

import asyncio
import functools
import sys

sys.setrecursionlimit(3000)

def test():
  fut = asyncio.Future()
  def done_cb(arg):
    pass
  fut.add_done_callback(functools.partial(done_cb, fut))

  print(repr(fut))

try:
  test()
except:
  print("Done")

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.
(Tested with Python 3.10.5 on Windows, installer downloaded from www.python.org).

@kumaraditya303
Copy link
Contributor

Reproduced on Python 3.10.5 (tags/v3.10.5:f377153, Jun 6 2022, 16:14:13) [MSC v.1929 64 bit (AMD64)] on win32
It is a stack overflow:

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 sys.setrecursionlimit to a high value can cause stack overflow depending upon the platform.

Footnotes

  1. https://docs.python.org/3.8/library/sys.html#sys.setrecursionlimit

@ezio-melotti ezio-melotti moved this to Todo in asyncio Jul 17, 2022
@usiems
Copy link
Author

usiems commented Aug 5, 2022

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)

@iritkatriel iritkatriel removed the pending The issue will be closed if no feedback is provided label Sep 19, 2022
StefanD986 added a commit to StefanD986/aiorun that referenced this issue May 7, 2024
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.
cjrh pushed a commit to cjrh/aiorun that referenced this issue May 8, 2024
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.
@asvetlov
Copy link
Contributor

I think it is fixed by #91195 for Python 3.11+

@github-project-automation github-project-automation bot moved this from Todo to Done in asyncio Nov 12, 2024
@freakboy3742
Copy link
Contributor

@asvetlov Was the added OS-ios tag intentional? I can't see an obvious connection to iOS here...

@asvetlov asvetlov removed the OS-ios label Nov 13, 2024
@asvetlov
Copy link
Contributor

@freakboy3742 sorry, OS-ios tag was added by an accident.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stdlib Python modules in the Lib dir topic-asyncio type-bug An unexpected behavior, bug, or error
Projects
Status: Done
Development

No branches or pull requests

7 participants
X Tutup