New submission from Martin Teichmann <[email protected]>:
asyncio.gather() returns a _GatheringFuture, which inherits from
asyncio.Future. This is weird in current asyncio, as futures are supposed to be
created with loop.create_future(). So I tried to reimplement gather() without
this weird special future. I succeeded, yet I stumbled over weird
inconsistencies with cancellation. There are three cases:
- coroutines have no special notion of cancellation, they treat CancelledError
as any other exception
- futures have a clear distinction between exceptions and cancellation:
future.set_exception(CancelledError()) is different from future.cancel(), as
only for the latter future.cancelled() is True. This is used in the
_GatheringFuture: it is cancelled() only if it got cancelled via
future.cancel(), if its children gets cancelled it may
set_exception(CancelledError()), but it will not be cancelled itself.
- Tasks consider raising a CancelledError always as a cancellation, whether it
actually got cancelled or the wrapped coroutine raised CancelledError for
whatever other reason. There is one exception: if the coroutine manages to
return immediately after being cancelled, it raises a CancelledError, but
task.cancelled() is false. So if a coroutine ends in
current_task().cancel()
return
the current task raises a CancelledError, but task.cancelled() is false.
I consider the last exception actually a bug, but it allows me to make my
inheritance-free gather() look to the outside exactly like it used to be.
----------
messages: 316085
nosy: Martin.Teichmann
priority: normal
severity: normal
status: open
title: asyncio.gather should not use special Future
type: behavior
versions: Python 3.8
_______________________________________
Python tracker <[email protected]>
<https://bugs.python.org/issue33413>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com