asyncio: Optimize Task._wakeup

See https://github.com/python/asyncio/pull/289 for details.
This commit is contained in:
Yury Selivanov 2015-11-16 15:12:10 -05:00
parent 1744d53930
commit a4afc4876b
1 changed files with 11 additions and 2 deletions

View File

@ -93,6 +93,7 @@ class Task(futures.Future):
futures.Future.__del__(self)
def _repr_info(self):
# Private method, do not use it.
info = super()._repr_info()
if self._must_cancel:
@ -221,6 +222,7 @@ class Task(futures.Future):
return True
def _step(self, value=None, exc=None):
# Private method, do not use it.
assert not self.done(), \
'_step(): already done: {!r}, {!r}, {!r}'.format(self, value, exc)
if self._must_cancel:
@ -284,13 +286,20 @@ class Task(futures.Future):
self = None # Needed to break cycles when an exception occurs.
def _wakeup(self, future):
# Private method, do not use it.
try:
value = future.result()
future.result()
except Exception as exc:
# This may also be a cancellation.
self._step(None, exc)
else:
self._step(value, None)
# Don't pass the value of `future.result()` explicitly,
# as `Future.__iter__` and `Future.__await__` don't need it.
# If we call `_step(value, None)` instead of `_step()`,
# Python eval loop would use `.send(value)` method call,
# instead of `__next__()`, which is slower for futures
# that return non-generator iterators from their `__iter__`.
self._step()
self = None # Needed to break cycles when an exception occurs.