diff options
Diffstat (limited to 'Lib/asyncio')
-rw-r--r-- | Lib/asyncio/futures.py | 7 | ||||
-rw-r--r-- | Lib/asyncio/tasks.py | 24 |
2 files changed, 21 insertions, 10 deletions
diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py index 24843c016a..13fb47cdc6 100644 --- a/Lib/asyncio/futures.py +++ b/Lib/asyncio/futures.py @@ -239,14 +239,15 @@ class Future: self._schedule_callbacks() self._log_traceback = True - def __iter__(self): + def __await__(self): if not self.done(): self._asyncio_future_blocking = True yield self # This tells Task to wait for completion. - assert self.done(), "await wasn't used with future" + if not self.done(): + raise RuntimeError("await wasn't used with future") return self.result() # May raise too. - __await__ = __iter__ # make compatible with 'await' expression + __iter__ = __await__ # make compatible with 'yield from'. # Needed for testing purposes. diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index 572e707333..b11808853e 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -37,7 +37,9 @@ def all_tasks(loop=None): return {t for t in _all_tasks if futures._get_loop(t) is loop} -class Task(futures.Future): +class Task(futures._PyFuture): # Inherit Python Task implementation + # from a Python Future implementation. + """A coroutine wrapped in a Future.""" # An important invariant maintained while a Task not done: @@ -107,11 +109,17 @@ class Task(futures.Future): if self._source_traceback: context['source_traceback'] = self._source_traceback self._loop.call_exception_handler(context) - futures.Future.__del__(self) + super().__del__() def _repr_info(self): return base_tasks._task_repr_info(self) + def set_result(self, result): + raise RuntimeError('Task does not support set_result operation') + + def set_exception(self, exception): + raise RuntimeError('Task does not support set_exception operation') + def get_stack(self, *, limit=None): """Return the list of stack frames for this task's coroutine. @@ -180,7 +188,9 @@ class Task(futures.Future): return True def _step(self, exc=None): - assert not self.done(), f'_step(): already done: {self!r}, {exc!r}' + if self.done(): + raise futures.InvalidStateError( + f'_step(): already done: {self!r}, {exc!r}') if self._must_cancel: if not isinstance(exc, futures.CancelledError): exc = futures.CancelledError() @@ -201,15 +211,15 @@ class Task(futures.Future): if self._must_cancel: # Task is cancelled right before coro stops. self._must_cancel = False - self.set_exception(futures.CancelledError()) + super().set_exception(futures.CancelledError()) else: - self.set_result(exc.value) + super().set_result(exc.value) except futures.CancelledError: super().cancel() # I.e., Future.cancel(self). except Exception as exc: - self.set_exception(exc) + super().set_exception(exc) except BaseException as exc: - self.set_exception(exc) + super().set_exception(exc) raise else: blocking = getattr(result, '_asyncio_future_blocking', None) |