]> granicus.if.org Git - python/commitdiff
asyncio, Tulip issue 206: In debug mode, keep the callback in the
authorVictor Stinner <victor.stinner@gmail.com>
Wed, 17 Sep 2014 21:24:13 +0000 (23:24 +0200)
committerVictor Stinner <victor.stinner@gmail.com>
Wed, 17 Sep 2014 21:24:13 +0000 (23:24 +0200)
representation of Handle and TimerHandle after cancel().

Lib/asyncio/events.py
Lib/test/test_asyncio/test_events.py

index 3c7a36d0763ffeb7f2d22ce93e0b1d6811b0dbdf..b7cc35122d4d70733f5f885475519895388cec66 100644 (file)
@@ -73,7 +73,7 @@ class Handle:
     """Object returned by callback registration methods."""
 
     __slots__ = ('_callback', '_args', '_cancelled', '_loop',
-                 '_source_traceback', '__weakref__')
+                 '_source_traceback', '_repr', '__weakref__')
 
     def __init__(self, callback, args, loop):
         assert not isinstance(callback, Handle), 'A Handle is not a callback'
@@ -81,12 +81,13 @@ class Handle:
         self._callback = callback
         self._args = args
         self._cancelled = False
+        self._repr = None
         if self._loop.get_debug():
             self._source_traceback = traceback.extract_stack(sys._getframe(1))
         else:
             self._source_traceback = None
 
-    def __repr__(self):
+    def _repr_info(self):
         info = [self.__class__.__name__]
         if self._cancelled:
             info.append('cancelled')
@@ -95,10 +96,21 @@ class Handle:
         if self._source_traceback:
             frame = self._source_traceback[-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)
 
     def cancel(self):
         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._args = None
 
@@ -131,17 +143,11 @@ class TimerHandle(Handle):
             del self._source_traceback[-1]
         self._when = when
 
-    def __repr__(self):
-        info = []
-        if self._cancelled:
-            info.append('cancelled')
-        info.append('when=%s' % self._when)
-        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 _repr_info(self):
+        info = super()._repr_info()
+        pos = 2 if self._cancelled else 1
+        info.insert(pos, 'when=%s' % self._when)
+        return info
 
     def __hash__(self):
         return hash(self._when)
index 0cfc028db1faeb817d31d292622bd0069a65afb9..7ac845a8a0fa498fc1e893b5f13491d7f1953dc5 100644 (file)
@@ -1891,8 +1891,8 @@ class HandleTests(test_utils.TestCase):
         # cancelled handle
         h.cancel()
         self.assertEqual(repr(h),
-                        '<Handle cancelled created at %s:%s>'
-                        % (create_filename, create_lineno))
+                        '<Handle cancelled noop(1, 2) at %s:%s created at %s:%s>'
+                        % (filename, lineno, create_filename, create_lineno))
 
     def test_handle_source_traceback(self):
         loop = asyncio.get_event_loop_policy().new_event_loop()
@@ -1987,8 +1987,9 @@ class TimerTests(unittest.TestCase):
         # cancelled handle
         h.cancel()
         self.assertEqual(repr(h),
-                        '<TimerHandle cancelled when=123 created at %s:%s>'
-                        % (create_filename, create_lineno))
+                        '<TimerHandle cancelled when=123 noop() '
+                        'at %s:%s created at %s:%s>'
+                        % (filename, lineno, create_filename, create_lineno))
 
 
     def test_timer_comparison(self):