[Python-checkins] bpo-33672: Fix Task.__repr__ crash with Cython's bogus coroutines (GH-7180)
Yury Selivanov
webhook-mailer at python.org
Tue May 29 00:55:30 EDT 2018
https://github.com/python/cpython/commit/e151f83deab9819fb8d9dfc59f9baa4a7273226c
commit: e151f83deab9819fb8d9dfc59f9baa4a7273226c
branch: 3.6
author: Yury Selivanov <yury at magic.io>
committer: GitHub <noreply at github.com>
date: 2018-05-29T00:55:27-04:00
summary:
bpo-33672: Fix Task.__repr__ crash with Cython's bogus coroutines (GH-7180)
[3.6 backport of 989b9e0]
files:
A Misc/NEWS.d/next/Library/2018-05-28-17-45-06.bpo-33672.GM_Xm_.rst
M Lib/asyncio/coroutines.py
M Lib/asyncio/events.py
M Lib/test/test_asyncio/test_events.py
diff --git a/Lib/asyncio/coroutines.py b/Lib/asyncio/coroutines.py
index 520a309f8460..a9022f92a52a 100644
--- a/Lib/asyncio/coroutines.py
+++ b/Lib/asyncio/coroutines.py
@@ -310,18 +310,25 @@ def _format_coroutine(coro):
if coro_name is None:
coro_name = events._format_callback(func, (), {})
- try:
- coro_code = coro.gi_code
- except AttributeError:
+ coro_code = None
+ if hasattr(coro, 'cr_code') and coro.cr_code:
coro_code = coro.cr_code
+ elif hasattr(coro, 'gi_code') and coro.gi_code:
+ coro_code = coro.gi_code
- try:
- coro_frame = coro.gi_frame
- except AttributeError:
+ coro_frame = None
+ if hasattr(coro, 'cr_frame') and coro.cr_frame:
coro_frame = coro.cr_frame
+ elif hasattr(coro, 'gi_frame') and coro.gi_frame:
+ coro_frame = coro.gi_frame
+
+ filename = '<empty co_filename>'
+ if coro_code and coro_code.co_filename:
+ filename = coro_code.co_filename
- filename = coro_code.co_filename
lineno = 0
+ coro_repr = coro_name
+
if (isinstance(coro, CoroWrapper) and
not inspect.isgeneratorfunction(coro.func) and
coro.func is not None):
@@ -338,7 +345,7 @@ def _format_coroutine(coro):
lineno = coro_frame.f_lineno
coro_repr = ('%s running at %s:%s'
% (coro_name, filename, lineno))
- else:
+ elif coro_code:
lineno = coro_code.co_firstlineno
coro_repr = ('%s done, defined at %s:%s'
% (coro_name, filename, lineno))
diff --git a/Lib/asyncio/events.py b/Lib/asyncio/events.py
index 05dc8969f44a..e654efc5526a 100644
--- a/Lib/asyncio/events.py
+++ b/Lib/asyncio/events.py
@@ -58,10 +58,10 @@ def _format_callback(func, args, kwargs, suffix=''):
suffix = _format_args_and_kwargs(args, kwargs) + suffix
return _format_callback(func.func, func.args, func.keywords, suffix)
- if hasattr(func, '__qualname__'):
- func_repr = getattr(func, '__qualname__')
- elif hasattr(func, '__name__'):
- func_repr = getattr(func, '__name__')
+ if hasattr(func, '__qualname__') and func.__qualname__:
+ func_repr = func.__qualname__
+ elif hasattr(func, '__name__') and func.__name__:
+ func_repr = func.__name__
else:
func_repr = repr(func)
diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py
index 1ecc89f2e758..548a4610f772 100644
--- a/Lib/test/test_asyncio/test_events.py
+++ b/Lib/test/test_asyncio/test_events.py
@@ -2467,6 +2467,28 @@ def __await__(self):
# built-in async_gen.asend().
self.assertEqual(coroutines._format_coroutine(coro), 'Coro()')
+ coro = Coro()
+ coro.__qualname__ = 'AAA'
+ coro.cr_code = None
+ self.assertEqual(coroutines._format_coroutine(coro), 'AAA()')
+
+ coro = Coro()
+ coro.__qualname__ = 'AAA'
+ coro.cr_code = None
+ coro.cr_frame = None
+ self.assertEqual(coroutines._format_coroutine(coro), 'AAA()')
+
+ coro = Coro()
+ coro.__qualname__ = None
+ coro.cr_code = None
+ coro.cr_frame = None
+ self.assertEqual(coroutines._format_coroutine(coro), f'{repr(coro)}()')
+
+ coro = Coro()
+ coro.cr_code = None
+ coro.cr_frame = None
+ self.assertEqual(coroutines._format_coroutine(coro), f'{repr(coro)}()')
+
class TimerTests(unittest.TestCase):
diff --git a/Misc/NEWS.d/next/Library/2018-05-28-17-45-06.bpo-33672.GM_Xm_.rst b/Misc/NEWS.d/next/Library/2018-05-28-17-45-06.bpo-33672.GM_Xm_.rst
new file mode 100644
index 000000000000..36373c028639
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2018-05-28-17-45-06.bpo-33672.GM_Xm_.rst
@@ -0,0 +1 @@
+Fix Task.__repr__ crash with Cython's bogus coroutines
More information about the Python-checkins
mailing list