-
-
Notifications
You must be signed in to change notification settings - Fork 7.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
py/objgenerator.c: Allow pend_throw to an unstarted generator. #5275
Conversation
This wasn't necessary as the wrapped function already has a reference to its globals. But it had a dual purpose of tracking whether the function was currently running, so replace it with a bool.
c76e9c7
to
78b61ff
Compare
I just tested the behaviour and can confirm that it works as expected. Thanks. |
78b61ff
to
dcbdfba
Compare
Updated tests to catch the missing coverage. |
Overall code-size change for this PR is:
So, independently of whether this is eventually useful for uasyncio, I'd say it's a good change because 1) it generalises a feature; 2) it reduces code size. |
dcbdfba
to
70154ec
Compare
raised CancelledError() | ||
None | ||
CancelledError() | ||
raised ValueError('exception',) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
now needs to be replaced with raised ValueError()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
70154ec
to
ef209b1
Compare
A quick question to your PR: If it indicates the general status of a generator, could it be used to implement the CPython equivalent of "task.done()" returning if the generator is finished executing code? |
It's the latter. i.e. the generator is currently executing code up to the next yield. This really only exists to prevent trying to call next/send/throw (or pend_throw) on itself. (See the test case I added that shows this in action).
Yeah, unfortunately it doesn't, but it could actually be easily extended to do so with another sentinel value (this is actually what I had in my mind when I wrote "another extension to objgenerator.c to interrogate a generator instance and find out whether it has finished" on #5242 |
py/objgenerator.c
Outdated
mp_raise_TypeError("can't pend throw to just-started generator"); | ||
if (exc_in == mp_const_none) { | ||
mp_raise_ValueError(NULL); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this restriction needed? Can this check just be removed? If the user passes in None
then it just cancels any pending throw, which seems sensible/possible...?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you're right. Removed and updated the test to check that this works.
I think this was left over from when I had the meaning of MP_OBJ_NULL
and mp_const_none
the other way around.
Replace the is_running field with a tri-state variable to indicate running/not-running/pending-exception. Update tests to cover the various cases. This allows cancellation in uasyncio even if the coroutine hasn't been executed yet. Fixes micropython#5242
ef209b1
to
fdaa191
Compare
With the latest changes/fixes to this PR the code-size change is:
|
…y-headers Fix crash in gen_display_resources.py
pend_throw
is a MicroPython-specific extension but allows simplification of the implementation of uasyncio. It injects an exception into the generator such that it will be raised as soon as it is next resumed.This fixes the behaviour specifically such that uasyncio.cancel() will work on an unstarted generator. See #5242