mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
asyncio, Tulip issue 206: In debug mode, keep the callback in the
representation of Handle and TimerHandle after cancel().
This commit is contained in:
parent
86c9e1877c
commit
1b38bc65dd
2 changed files with 24 additions and 17 deletions
|
@ -73,7 +73,7 @@ class Handle:
|
||||||
"""Object returned by callback registration methods."""
|
"""Object returned by callback registration methods."""
|
||||||
|
|
||||||
__slots__ = ('_callback', '_args', '_cancelled', '_loop',
|
__slots__ = ('_callback', '_args', '_cancelled', '_loop',
|
||||||
'_source_traceback', '__weakref__')
|
'_source_traceback', '_repr', '__weakref__')
|
||||||
|
|
||||||
def __init__(self, callback, args, loop):
|
def __init__(self, callback, args, loop):
|
||||||
assert not isinstance(callback, Handle), 'A Handle is not a callback'
|
assert not isinstance(callback, Handle), 'A Handle is not a callback'
|
||||||
|
@ -81,12 +81,13 @@ class Handle:
|
||||||
self._callback = callback
|
self._callback = callback
|
||||||
self._args = args
|
self._args = args
|
||||||
self._cancelled = False
|
self._cancelled = False
|
||||||
|
self._repr = None
|
||||||
if self._loop.get_debug():
|
if self._loop.get_debug():
|
||||||
self._source_traceback = traceback.extract_stack(sys._getframe(1))
|
self._source_traceback = traceback.extract_stack(sys._getframe(1))
|
||||||
else:
|
else:
|
||||||
self._source_traceback = None
|
self._source_traceback = None
|
||||||
|
|
||||||
def __repr__(self):
|
def _repr_info(self):
|
||||||
info = [self.__class__.__name__]
|
info = [self.__class__.__name__]
|
||||||
if self._cancelled:
|
if self._cancelled:
|
||||||
info.append('cancelled')
|
info.append('cancelled')
|
||||||
|
@ -95,10 +96,21 @@ class Handle:
|
||||||
if self._source_traceback:
|
if self._source_traceback:
|
||||||
frame = self._source_traceback[-1]
|
frame = self._source_traceback[-1]
|
||||||
info.append('created at %s:%s' % (frame[0], frame[1]))
|
info.append('created at %s:%s' % (frame[0], frame[1]))
|
||||||
|
return info
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
if self._repr is not None:
|
||||||
|
return self._repr
|
||||||
|
info = self._repr_info()
|
||||||
return '<%s>' % ' '.join(info)
|
return '<%s>' % ' '.join(info)
|
||||||
|
|
||||||
def cancel(self):
|
def cancel(self):
|
||||||
self._cancelled = True
|
self._cancelled = True
|
||||||
|
if self._loop.get_debug():
|
||||||
|
# Keep a representation in debug mode to keep callback and
|
||||||
|
# parameters. For example, to log the warning "Executing <Handle
|
||||||
|
# ...> took 2.5 second"
|
||||||
|
self._repr = repr(self)
|
||||||
self._callback = None
|
self._callback = None
|
||||||
self._args = None
|
self._args = None
|
||||||
|
|
||||||
|
@ -131,17 +143,11 @@ class TimerHandle(Handle):
|
||||||
del self._source_traceback[-1]
|
del self._source_traceback[-1]
|
||||||
self._when = when
|
self._when = when
|
||||||
|
|
||||||
def __repr__(self):
|
def _repr_info(self):
|
||||||
info = []
|
info = super()._repr_info()
|
||||||
if self._cancelled:
|
pos = 2 if self._cancelled else 1
|
||||||
info.append('cancelled')
|
info.insert(pos, 'when=%s' % self._when)
|
||||||
info.append('when=%s' % self._when)
|
return info
|
||||||
if self._callback is not None:
|
|
||||||
info.append(_format_callback(self._callback, self._args))
|
|
||||||
if self._source_traceback:
|
|
||||||
frame = self._source_traceback[-1]
|
|
||||||
info.append('created at %s:%s' % (frame[0], frame[1]))
|
|
||||||
return '<%s %s>' % (self.__class__.__name__, ' '.join(info))
|
|
||||||
|
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
return hash(self._when)
|
return hash(self._when)
|
||||||
|
|
|
@ -1891,8 +1891,8 @@ class HandleTests(test_utils.TestCase):
|
||||||
# cancelled handle
|
# cancelled handle
|
||||||
h.cancel()
|
h.cancel()
|
||||||
self.assertEqual(repr(h),
|
self.assertEqual(repr(h),
|
||||||
'<Handle cancelled created at %s:%s>'
|
'<Handle cancelled noop(1, 2) at %s:%s created at %s:%s>'
|
||||||
% (create_filename, create_lineno))
|
% (filename, lineno, create_filename, create_lineno))
|
||||||
|
|
||||||
def test_handle_source_traceback(self):
|
def test_handle_source_traceback(self):
|
||||||
loop = asyncio.get_event_loop_policy().new_event_loop()
|
loop = asyncio.get_event_loop_policy().new_event_loop()
|
||||||
|
@ -1987,8 +1987,9 @@ class TimerTests(unittest.TestCase):
|
||||||
# cancelled handle
|
# cancelled handle
|
||||||
h.cancel()
|
h.cancel()
|
||||||
self.assertEqual(repr(h),
|
self.assertEqual(repr(h),
|
||||||
'<TimerHandle cancelled when=123 created at %s:%s>'
|
'<TimerHandle cancelled when=123 noop() '
|
||||||
% (create_filename, create_lineno))
|
'at %s:%s created at %s:%s>'
|
||||||
|
% (filename, lineno, create_filename, create_lineno))
|
||||||
|
|
||||||
|
|
||||||
def test_timer_comparison(self):
|
def test_timer_comparison(self):
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue