Kaydet (Commit) 605a64b4 authored tarafından Victor Stinner's avatar Victor Stinner

(Merge 3.4) asyncio, Tulip issue 206: In debug mode, keep the callback in the

representation of Handle and TimerHandle after cancel().
...@@ -73,7 +73,7 @@ class Handle: ...@@ -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: ...@@ -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: ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment