bpo-46771: Implement task cancel requests by Tinche · Pull Request #31513 · python/cpython
So this needs to be reviewed carefully by @agronholm and @Tinche -- not so much regarding "code review" but regarding "does this address our concerns, does it fix the edge cases, can we implement Trio-like behavior in 3rd party libraries when we need it". I'd also like @cjerdonek to think about this.
We also, separately, need to debate whether the lines
if self._num_cancels_requested > 1: return False
should stay in or not. IIRC @agronholm has claimed that this (or the previous incarnation) broke several AnyIO tests.
There are two aspects that would change if we removed these two lines:
- The cancel message. See https://bugs.python.org/issue46829. In 3.10, after
t.cancel("first"); t.cancel("2nd")the cancel message ended up being set to"2nd"; with 3.11 main it ends up"first". If we remove these two lines it would become"2nd"again. - How many CancelledError exceptions will the task see? In 3.10, the task may see multiple cancellations -- but it may not. In particular, if the second cancel() call finds the must-cancel flag already set, only one cancellation will be delivered. However, if the first cancellation is delivered, and the task catches the CancelledError and then uses
awaitto do some cleanup, in 3.10 (and again if we remove those two lines) that cleanupawaitwill be cancelled; but if we keep those two lines, thatawaitwill be shielded.