summaryrefslogtreecommitdiffstats
path: root/Lib/asyncio/base_futures.py
diff options
context:
space:
mode:
authorAndrew Svetlov <andrew.svetlov@gmail.com>2022-03-17 01:03:09 (GMT)
committerGitHub <noreply@github.com>2022-03-17 01:03:09 (GMT)
commit30b5d41fabad04f9f34d603f1ce2249452c18c71 (patch)
tree7eed9b2cc60f96768193498b051583dd733e2a40 /Lib/asyncio/base_futures.py
parenta7c54148322781cb0f332d440a3454d550ef6414 (diff)
downloadcpython-30b5d41fabad04f9f34d603f1ce2249452c18c71.zip
cpython-30b5d41fabad04f9f34d603f1ce2249452c18c71.tar.gz
cpython-30b5d41fabad04f9f34d603f1ce2249452c18c71.tar.bz2
bpo-47039: Normalize repr() of asyncio future and task objects (GH-31950)
Diffstat (limited to 'Lib/asyncio/base_futures.py')
-rw-r--r--Lib/asyncio/base_futures.py30
1 files changed, 9 insertions, 21 deletions
diff --git a/Lib/asyncio/base_futures.py b/Lib/asyncio/base_futures.py
index 2c01ac9..cd811a7 100644
--- a/Lib/asyncio/base_futures.py
+++ b/Lib/asyncio/base_futures.py
@@ -42,16 +42,6 @@ def _format_callbacks(cb):
return f'cb=[{cb}]'
-# bpo-42183: _repr_running is needed for repr protection
-# when a Future or Task result contains itself directly or indirectly.
-# The logic is borrowed from @reprlib.recursive_repr decorator.
-# Unfortunately, the direct decorator usage is impossible because of
-# AttributeError: '_asyncio.Task' object has no attribute '__module__' error.
-#
-# After fixing this thing we can return to the decorator based approach.
-_repr_running = set()
-
-
def _future_repr_info(future):
# (Future) -> str
"""helper function for Future.__repr__"""
@@ -60,17 +50,9 @@ def _future_repr_info(future):
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)
+ # 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))
@@ -78,3 +60,9 @@ def _future_repr_info(future):
frame = future._source_traceback[-1]
info.append(f'created at {frame[0]}:{frame[1]}')
return info
+
+
+@reprlib.recursive_repr()
+def _future_repr(future):
+ info = ' '.join(_future_repr_info(future))
+ return f'<{future.__class__.__name__} {info}>'