You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Async generator/anext with default-tuple-value results in SystemError: <class 'StopIteration'> returned with exception set #128078
I asked a question on stackoverflow because I found a strange error while writing code that makes use an async generator function and the built-in anext() function when using a tuple value for the default argument of anext().
One of the stackoverflow answers contains a good analysis and a possible cause of the problem.
The failing code is the second line with anext():
importasyncioasyncdefgenerator(it=None):
ifitisnotNone:
yield (it, it)
asyncdefmy_func():
# results in a=1 b=1a, b=awaitanext(generator(1), (2, 3))
# results in no printingasyncfora, bingenerator():
print(a, b)
# raises exceptiona, b=awaitanext(generator(), (2, 3))
loop=asyncio.new_event_loop()
loop.run_until_complete(my_func())
It raises this unexpected exception:
StopAsyncIteration
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<stdin>", line 1, in<module>
File "/Users/manuel/.pyenv/versions/3.12.0/lib/python3.12/asyncio/base_events.py", line 664, in run_until_complete
returnfuture.result()
^^^^^^^^^^^^^^^
File "<stdin>", line 6, in my_func
SystemError: <class 'StopIteration'> returned a result with an exception set
This is something I've also wondered. We could clear the exception before calling _PyGen_SetStopIterationValue but Mark also suggested removing the specialized path for tuples. So we can perhaps do both in my PR?
Doing both is fine. I'm not on my dev session anymore but if you want to do the PyErr_Clear() part, it's better to merge it first. Then I'll merge mine where I can just check that no exception is currently set instead.
Activity
kumaraditya303 commentedon Jan 11, 2025
FWIW I think its a bug in implementation of anext.
Specifically in these lines:
cpython/Objects/iterobject.c
Lines 386 to 388 in 3a570c6
This should clear the
PyExc_StopAsyncIterationbefore calling_PyGen_SetStopIterationValue.The following patch fixes it for me and all async gen tests pass:
picnixz commentedon Jan 11, 2025
This is something I've also wondered. We could clear the exception before calling
_PyGen_SetStopIterationValuebut Mark also suggested removing the specialized path for tuples. So we can perhaps do both in my PR?kumaraditya303 commentedon Jan 11, 2025
I suggest to do both in different PRs, I would prefer to backport the simpler fix.
picnixz commentedon Jan 11, 2025
Doing both is fine. I'm not on my dev session anymore but if you want to do the
PyErr_Clear()part, it's better to merge it first. Then I'll merge mine where I can just check that no exception is currently set instead.gh-128078: Clear exception in `anext` before calling `_PyGen_SetStopIâĶ
pythongh-128078: Clear exception in `anext` before calling `_PyGen_SeâĶ
pythongh-128078: Clear exception in `anext` before calling `_PyGen_SeâĶ
[3.12] gh-128078: Clear exception in `anext` before calling `_PyGen_SâĶ
[3.13] gh-128078: Clear exception in `anext` before calling `_PyGen_SâĶ
gh-128078: Use `PyErr_SetRaisedException` in `_PyGen_SetStopIterationâĶ
pythongh-128078: Use `PyErr_SetRaisedException` in `_PyGen_SetStopIteâĶ
pythongh-128078: Use `PyErr_SetRaisedException` in `_PyGen_SetStopIteâĶ
[3.12] gh-128078: Use `PyErr_SetRaisedException` in `_PyGen_SetStopItâĶ
[3.13] gh-128078: Use `PyErr_SetRaisedException` in `_PyGen_SetStopItâĶ