Skip to content
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

PyIter_Next clears a StopException, where tp_iternext does not #29

Open
mattip opened this issue May 14, 2023 · 3 comments
Open

PyIter_Next clears a StopException, where tp_iternext does not #29

mattip opened this issue May 14, 2023 · 3 comments
Labels
stakeholder: alternative implementations impacts implementations of python other than cpython stakeholder: code generator devs impacts projects that generate python code (like cython, pybind11, ...) theme: consistency theme: implementation flaws problems with the implementation of specific APIs

Comments

@mattip
Copy link

mattip commented May 14, 2023

Consider this code:

async def gen():
    yield 123

def test_last_yield(g):
    ai = g.__aiter__()
    an = ai.__anext__()
    try:
        next(an) 
    except StopIteration as ex:
        return ex.args
    else:
        return None 

ret = test_last_yield(gen())
assert ret[0] == 123

There are two ways to convert next(an) to C: either PyIter_Next(an) or an.tp_iternext(). There is a subtle difference: PyIter_Next will return NULL, signaling that the iteration is complete, and clear the StopIteration exception, erasing the ex.args. Calling tp_iternext will not clear the exception, so the yield value will be available through the ex.args. This came up in cython since it tends not to use the slot functions on non-CPython (in this case PyPy). As far as I can tell, there is no PyIter_* function to only call tp_iternext without clearing the exception.

@iritkatriel iritkatriel added theme: consistency stakeholder: alternative implementations impacts implementations of python other than cpython stakeholder: code generator devs impacts projects that generate python code (like cython, pybind11, ...) labels May 14, 2023
@gvanrossum
Copy link

(This one sounds like deja vu to me -- I wonder if we've done a similar inventory in the past.)

Another problem with PyIter_Next is that its NULL return is ambiguous -- it can mean an actual error occurred, or the end was reached. This particular API seems to be poorly designed, and we ought to replace it with something else that looks more complex but avoids the issues.

@vstinner
Copy link
Contributor

See also capi-workgroup/decisions#21

@serhiy-storchaka
Copy link

Note also that setting a StopIteration in tp_nextitem is optional. To signal the end of iteration it should either set a StopIteration and return NULL, or return NULL without setting any error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stakeholder: alternative implementations impacts implementations of python other than cpython stakeholder: code generator devs impacts projects that generate python code (like cython, pybind11, ...) theme: consistency theme: implementation flaws problems with the implementation of specific APIs
Projects
None yet
Development

No branches or pull requests

5 participants