GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — gh-116720: Fix corner cases of taskgroups by gvanrossum · Pull Request #117407 · python/cpython Conversation
|
|
@arthur-tacca, what do you think of this PR? Does it pass all your tests? Do you want to contribute in any way (e.g. by converting your example programs into unittests)? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
@agronholm I wonder if you could review this PR? (It's in draft mode because there are no tests or doc yet, but the changes to taskgroups.py and tasks.py are as I plan to keep them.) It might affect anyio because of two things: (a) Better support for nested taskgroups; (b) change to uncancel() to reset the internal "must cancel" flag when the pending cancellation count reaches zero. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
@Tinche Same question for you -- you might have an opinion on the changes that I'm proposing to make to asyncio task and task group behavior here. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Sure, I can take a look. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
It's hard to definitively say if this will affect AnyIO, but I did run the task group tests against this PR and they passed. The only place where AnyIO looks at this flag is in |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Sorry, which flag is that? ‘cancelling()’ or ‘_must_cancel’? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| if self._num_cancels_requested > 0: | ||
| self._num_cancels_requested -= 1 | ||
| if self._num_cancels_requested == 0: | ||
| self._must_cancel = False |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this also clear the cancel message?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
I doubt it -- self._cancel_message is never cleared, and it's never used unless self._must_cancel is set.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Okay – I was just confused by that Py_CLEAR() in the C version, but this explains it.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Oh, you're right, that CLEAR is unnecessary there too. :-)
Sorry, something went wrong.
There was an error while loading. Please reload this page.
This fixes the one failing test in test_timeouts. Surprisingly, it doesn't break any other asyncio tests.
Co-Authored-By: @Tinche
Co-Authored-By: @arthur-tacca
Co-Authored-By: @arthur-tacca
|
Still to do are docs updates for uncancel and for task groups. Also, I'd love help with shortening the news blurb. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
@willingc Would you be my reviewer for this PR? I feel particularly challenged by the various documentation updates -- this is a pretty subtle improvement (given how long it's taken before someone reported the issue :-) and I'm struggling describing the changes and the end state appropriately in various places:
I'd say that currently the Changelog news item is probably too long, and there's too much duplication between all three forms of documentation. @arthur-tacca: I haven't heard from you on the issue in a while. Your feedback on any part of this PR would be much appreciated. I plan to give you credit by adding |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
@gvanrossum Sorry for ghosting you. I had some limited time for open source between jobs (which I actually planned to spend mainly on something else), which has run out and it's now hard for me to post even short comments like this one. Super-brief review: Your code changes look good to me. As I said in an earlier comment, I think it's good that you've just moved (rather than duplicated) the Credit: Thanks for crediting me, that's much appreciated. I don't think my contributions are significant enough to need a CLA but in any case I have signed one (for a small change to typing extensions). Changelog:
Docs changes: "Task groups are careful not to drop outside cancellations when they collide with a cancellation internal to the task group." I must admit, I would struggle to understand what this means if I hadn't been involved in this issue. But that isn't very helpful since I don't have a better suggestion to give. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| self._errors.append(exc) | ||
|
|
||
| if self._errors: | ||
| # If the parent task is being cancelled from the outside, |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
| # If the parent task is being cancelled from the outside, | |
| # If the parent task is being cancelled from the outside of the taskgroup, |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
@gvanrossum Overall, this looks good. I made a few suggestions on wording, but the existing text is also fine. Thanks!
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
|
||
| if self._errors: | ||
| # If the parent task is being cancelled from the outside, | ||
| # re-cancel it, while keeping the cancel count stable. |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
| # re-cancel it, while keeping the cancel count stable. | |
| # un-cancel and re-cancel the parent task, which will keep the cancel count stable. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| the cancellation state. | ||
|
|
||
| When this method decrements the cancellation count to zero, | ||
| if a previous :meth:`cancel` call had arranged for a |
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
| if a previous :meth:`cancel` call had arranged for a | |
| the method checks if a previous :meth:`cancel` call had arranged for |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
|
||
| When this method decrements the cancellation count to zero, | ||
| if a previous :meth:`cancel` call had arranged for a | ||
| :exc:`CancelledError` to be thrown into the task, |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
| :exc:`CancelledError` to be thrown into the task, | |
| :exc:`CancelledError` to be thrown into the task. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| When this method decrements the cancellation count to zero, | ||
| if a previous :meth:`cancel` call had arranged for a | ||
| :exc:`CancelledError` to be thrown into the task, | ||
| but this hadn't been done yet, that arrangement will be |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
| but this hadn't been done yet, that arrangement will be | |
| If this hadn't been done yet, that arrangement will be |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| (Contributed by Arthur Tacca and Jason Zhang in :gh:`115957`.) | ||
|
|
||
| * Improved behavior of :class:`asyncio.TaskGroup` when an outside cancellation | ||
| collides with an internal cancellation. For example, when two task groups |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Nice!
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Also switch to consistently using internal/external instead of inside/outside.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Looks good. Thanks everyone.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
@gvanrossum would you mind if I copied your solution into quattro to serve as a backport of sorts, for 3.11 and 3.12? Quattro is Apache 2 licensed, that's compatible right? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
That should be absolutely fine -- if I understand the PSF license correctly, all you need to do is add this text somewhere and add a copy of the PSF license for 3.13 somewhere. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
This prevents external cancellations of a task group's parent task to be dropped when an internal cancellation happens at the same time. Also strengthen the semantics of uncancel() to clear self._must_cancel when the cancellation count reaches zero. Co-Authored-By: Tin Tvrtković <[email protected]> Co-Authored-By: Arthur Tacca
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.