Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork32.1k
bpo-46841: Don't jump duringthrow()
#31968
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
I'm not sure that this is worthwhile, at least not in this form. The current approach is very fragile, as you rightly point out. However, this PR moves code from a cold path Although the points you raise are valid, they all safe for now (although they probably won't be in future).
Until the compiler freely re-orders blocks, the oparg will only ever be very small as it only jumps over a couple of instructions.
Again, it's OK because we know what instructions we are scanning over.
Technically, it steps back to the IMO, the "proper" fix for this is to wrap the Now:
With hidden try-except:
This was part of the motivation for splitting out |
This seems unhelpfully pedantic.
I don’t think I agree (at least not yet). It's not too clear how your suggestion would work, so just to make sure my understanding is correct:
I'm not sure if I got that right, since a lot of this code is new to me. If so, it seems much, much more complex and expensive than what I've proposed here: clearing the sub-iterator when it returns and adding a single, easily-predictable |
markshannon commentedMar 20, 2022 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
I hadn't considered the special case for If
|
No, this is an important detail. |
brandtbucher commentedMay 6, 2022 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
With the beta freeze looming, Istrongly feel that we should go with this approach (at least for 3.11). It's a working, very minimal change to the existing code that helps other projects (like JITs, PEP 523 hooks, etc.) that need this logic to be moved back into the bytecode. The additional branch is cheap, easily predictable, and fits naturally with the existing code. For reference, I've now tried two other approaches with virtual Attempt #1 uses a new ======================================================================ERROR:test_anext_iter (test.test_asyncgen.AsyncGenAsyncioTest.test_anext_iter) [pure-Pythonanext()]----------------------------------------------------------------------Traceback (mostrecentcalllast):File"/home/brandtbucher/cpython/Lib/test/test_asyncgen.py",line735,inrun_testtest(py_anext)^^^^^^^^^^^^^^File"/home/brandtbucher/cpython/Lib/test/test_asyncgen.py",line674,intest3g.close()^^^^^^^^^File"/home/brandtbucher/cpython/Lib/test/test_asyncgen.py",line78,inanext_implreturnawait__anext__(iterator)^^^^^^^^^^^^^^^^^^^^^^^^^RuntimeError:cannotreusealreadyawaited__anext__()/asend()---------------------------------------------------------------------- I'm also not confident that the rest of the logic is 100% correct. Attempt #2 uses a more complicated virtual I'll leave the decision up to you,@markshannon. |
markshannon commentedMay 9, 2022 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
Well, this didn't make it into 3.11. Approach 2 passes the tests, and has fewer changes to the instruction set. That seems better than approach 1. One other question. |
Closing in favor of#96010. |
Uh oh!
There was an error while loading.Please reload this page.
We currently perform some awkward control flow in
_gen_throw
to handle the case where ayield from
/await
sub-iterator returns a value during athrow()
call.The current code is quite sensitive to slight changes in the bytecode, and is technically invalid for three reasons:
SEND
has anEXTENDED_ARG
.YIELD_VALUE
instruction, which isn't really supposed to be possible.Instead, this PR handles this edge-case by pushing
NULL
and the return value in place of the sub-iterator and its next value.SEND
then handles this by adjusting the stack and jumping the same way it does when handling other return values.This also updates the docs for
SEND
(which are currently lacking a bit).https://bugs.python.org/issue46841