Skip to content

Commit 4f0f756

Browse files
committed
simplify code in Handle._run
1 parent f624bf9 commit 4f0f756

File tree

1 file changed

+48
-31
lines changed

1 file changed

+48
-31
lines changed

Lib/asyncio/events.py

Lines changed: 48 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -34,39 +34,61 @@
3434

3535
from . import format_helpers
3636

37-
_HANDLE_CANCELLED = object()
37+
class _HandleCancelled:
38+
@staticmethod
39+
def callback(*args):
40+
pass
41+
42+
args = ()
43+
44+
_HANDLE_CANCELLED = _HandleCancelled()
45+
46+
47+
class _HandlePartial:
48+
__slots__ = ("callback", "args")
49+
50+
def __init__(self, callback, args):
51+
self.callback = callback
52+
self.args = args
53+
54+
def __eq__(self, other):
55+
if isinstance(other, _HandlePartial):
56+
return (self.callback == other.callback and
57+
self.args == other.args)
58+
return NotImplemented
3859

3960

4061
class Handle:
4162
"""Object returned by callback registration methods."""
4263

43-
__slots__ = ('_callback_args', '_loop',
64+
__slots__ = ('_callback_partial', '_loop',
4465
'_source_traceback', '_repr', '__weakref__',
4566
'_context')
4667

4768
def __init__(self, callback, args, loop, context=None):
4869
if context is None:
4970
context = contextvars.copy_context()
50-
self._context = context
5171
self._loop = loop
52-
self._callback_args = (callback, args)
72+
self._context = context
73+
self._callback_partial = _HandlePartial(callback, args)
5374
self._repr = None
5475
if self._loop.get_debug():
5576
self._source_traceback = format_helpers.extract_stack(
5677
sys._getframe(1))
5778
else:
5879
self._source_traceback = None
5980

60-
def _repr_info(self, cancelling, callback_args):
81+
def _repr_info(self, cancelling, callback_partial):
6182
info = [self.__class__.__name__]
6283
if cancelling:
6384
info.append('cancelled')
64-
if callback_args is _HANDLE_CANCELLED:
85+
if callback_partial is _HANDLE_CANCELLED:
6586
info.append('cancelled')
6687
callback = None
6788
args = None
6889
else:
69-
callback, args = callback_args
90+
callback = callback_partial.callback
91+
args = callback_partial.args
7092

7193
if callback is not None:
7294
info.append(format_helpers._format_callback_source(
@@ -77,61 +99,58 @@ def _repr_info(self, cancelling, callback_args):
7799
info.append(f'created at {frame[0]}:{frame[1]}')
78100
return info
79101

80-
def _repr_atomic(self, cancelling, callback_args):
81-
info = self._repr_info(cancelling, callback_args)
102+
def _repr_atomic(self, cancelling, callback_partial):
103+
info = self._repr_info(cancelling, callback_partial)
82104
return '<{}>'.format(' '.join(info))
83105

84106
def __repr__(self):
85107
if self._repr is not None:
86108
return self._repr
87-
return self._repr_atomic(cancelling=False, callback_args=self._callback_args)
109+
return self._repr_atomic(cancelling=False, callback_partial=self._callback_partial)
88110

89111
def get_context(self):
90112
return self._context
91113

92114
def cancel(self):
93-
callback_args = self._callback_args
94-
self._callback_args = _HANDLE_CANCELLED
95-
if callback_args is not _HANDLE_CANCELLED:
115+
callback_partial = self._callback_partial
116+
self._callback_partial = _HANDLE_CANCELLED
117+
if callback_partial is not _HANDLE_CANCELLED:
96118
if self._loop.get_debug():
97119
# Keep a representation in debug mode to keep callback and
98120
# parameters. For example, to log the warning
99121
# "Executing <Handle...> took 2.5 second"
100-
self._repr = self._repr_atomic(cancelling=True, callback_args=callback_args)
122+
self._repr = self._repr_atomic(cancelling=True, callback_partial=callback_partial)
101123

102124
def cancelled(self):
103-
return self._callback_args is _HANDLE_CANCELLED
125+
return self._callback_partial is _HANDLE_CANCELLED
104126

105127
@property
106128
def _cancelled(self):
107129
return self.cancelled()
108130

109131
@property
110132
def _callback(self):
111-
callback_args = self._callback_args
112-
if callback_args is _HANDLE_CANCELLED:
133+
callback_partial = self._callback_partial
134+
if callback_partial is _HANDLE_CANCELLED:
113135
return None
114-
return callback_args[0]
136+
return callback_partial.callback
115137

116138
@property
117139
def _args(self):
118-
callback_args = self._callback_args
119-
if callback_args is _HANDLE_CANCELLED:
140+
callback_partial = self._callback_partial
141+
if callback_partial is _HANDLE_CANCELLED:
120142
return None
121-
return callback_args[1]
143+
return callback_partial.args
122144

123145
def _run(self):
124-
callback_args = self._callback_args
125-
if callback_args is _HANDLE_CANCELLED:
126-
return
127-
callback, args = callback_args
146+
callback_partial = self._callback_partial
128147
try:
129-
self._context.run(callback, *args)
148+
self._context.run(callback_partial.callback, *callback_partial.args)
130149
except (SystemExit, KeyboardInterrupt):
131150
raise
132151
except BaseException as exc:
133152
cb = format_helpers._format_callback_source(
134-
callback, args,
153+
callback_partial.callback, callback_partial.args,
135154
debug=self._loop.get_debug())
136155
msg = f'Exception in callback {cb}'
137156
context = {
@@ -142,9 +161,7 @@ def _run(self):
142161
if self._source_traceback:
143162
context['source_traceback'] = self._source_traceback
144163
self._loop.call_exception_handler(context)
145-
callback = None
146-
args = None
147-
callback_args = None
164+
callback_partial = None
148165
self = None # Needed to break cycles when an exception occurs.
149166

150167

@@ -192,7 +209,7 @@ def __ge__(self, other):
192209
def __eq__(self, other):
193210
if isinstance(other, TimerHandle):
194211
return (self._when == other._when and
195-
self._callback_args == other._callback_args)
212+
self._callback_partial == other._callback_partial)
196213
return NotImplemented
197214

198215
def cancel(self):

0 commit comments

Comments
 (0)