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

Async generator/anext with default-tuple-value results in SystemError: <class 'StopIteration'> returned with exception set #128078

Closed
manuel-koch opened this issue Dec 18, 2024 · 4 comments
Assignees
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error

Comments

@manuel-koch
Copy link

manuel-koch commented Dec 18, 2024

Bug report

Bug description:

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():

import asyncio

async def generator(it=None):
    if it is not None:
        yield (it, it)

async def my_func():
    # results in a=1 b=1
    a, b = await anext(generator(1), (2, 3))
    
    # results in no printing
    async for a, b in generator():
        print(a, b)
    
    # raises exception
    a, b = await anext(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
    return future.result()
           ^^^^^^^^^^^^^^^
  File "<stdin>", line 6, in my_func
SystemError: <class 'StopIteration'> returned a result with an exception set

CPython versions tested on:

3.11, 3.12, 3.13

Operating systems tested on:

macOS

Linked PRs

@manuel-koch manuel-koch added the type-bug An unexpected behavior, bug, or error label Dec 18, 2024
@kumaraditya303 kumaraditya303 added the interpreter-core (Objects, Python, Grammar, and Parser dirs) label Dec 19, 2024
@github-project-automation github-project-automation bot moved this to Todo in asyncio Dec 19, 2024
@picnixz picnixz removed this from asyncio Dec 27, 2024
@picnixz picnixz self-assigned this Dec 27, 2024
@kumaraditya303
Copy link
Contributor

FWIW I think its a bug in implementation of anext.
Specifically in these lines:

if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration)) {
_PyGen_SetStopIterationValue(obj->default_value);
}

This should clear the PyExc_StopAsyncIteration before calling _PyGen_SetStopIterationValue.

The following patch fixes it for me and all async gen tests pass:

diff --git a/Objects/iterobject.c b/Objects/iterobject.c
index 135ced9ea1f..b0938690dca 100644
--- a/Objects/iterobject.c
+++ b/Objects/iterobject.c
@@ -384,6 +384,7 @@ anextawaitable_iternext(anextawaitableobject *obj)
         return result;
     }
     if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration)) {
+        PyErr_Clear();
         _PyGen_SetStopIterationValue(obj->default_value);
     }
     return NULL;

@picnixz
Copy link
Member

picnixz commented Jan 11, 2025

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?

@kumaraditya303
Copy link
Contributor

I suggest to do both in different PRs, I would prefer to backport the simpler fix.

@picnixz
Copy link
Member

picnixz commented 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.

kumaraditya303 added a commit that referenced this issue Jan 13, 2025
miss-islington pushed a commit to miss-islington/cpython that referenced this issue Jan 13, 2025
…tStopIterationValue` (pythonGH-128780)

(cherry picked from commit 76ffaef)

Co-authored-by: Bénédikt Tran <[email protected]>
Co-authored-by: Kumar Aditya <[email protected]>
miss-islington pushed a commit to miss-islington/cpython that referenced this issue Jan 13, 2025
…tStopIterationValue` (pythonGH-128780)

(cherry picked from commit 76ffaef)

Co-authored-by: Bénédikt Tran <[email protected]>
Co-authored-by: Kumar Aditya <[email protected]>
kumaraditya303 added a commit that referenced this issue Jan 13, 2025
…etStopIterationValue` (GH-128780) (#128784)

gh-128078: Clear exception in `anext` before calling `_PyGen_SetStopIterationValue` (GH-128780)
(cherry picked from commit 76ffaef)

Co-authored-by: Bénédikt Tran <[email protected]>
Co-authored-by: Kumar Aditya <[email protected]>
kumaraditya303 added a commit that referenced this issue Jan 13, 2025
…etStopIterationValue` (GH-128780) (#128785)

gh-128078: Clear exception in `anext` before calling `_PyGen_SetStopIterationValue` (GH-128780)
(cherry picked from commit 76ffaef)

Co-authored-by: Bénédikt Tran <[email protected]>
Co-authored-by: Kumar Aditya <[email protected]>
kumaraditya303 added a commit that referenced this issue Jan 13, 2025
miss-islington pushed a commit to miss-islington/cpython that referenced this issue Jan 13, 2025
…rationValue` (pythonGH-128287)

(cherry picked from commit 402b91d)

Co-authored-by: Bénédikt Tran <[email protected]>
Co-authored-by: Kumar Aditya <[email protected]>
miss-islington pushed a commit to miss-islington/cpython that referenced this issue Jan 13, 2025
…rationValue` (pythonGH-128287)

(cherry picked from commit 402b91d)

Co-authored-by: Bénédikt Tran <[email protected]>
Co-authored-by: Kumar Aditya <[email protected]>
Yhg1s pushed a commit that referenced this issue Feb 3, 2025
…erationValue` (GH-128287) (#128790)

gh-128078: Use `PyErr_SetRaisedException` in `_PyGen_SetStopIterationValue` (GH-128287)
(cherry picked from commit 402b91d)

Co-authored-by: Bénédikt Tran <[email protected]>
Co-authored-by: Kumar Aditya <[email protected]>
Yhg1s pushed a commit that referenced this issue Feb 3, 2025
…erationValue` (GH-128287) (#128789)

gh-128078: Use `PyErr_SetRaisedException` in `_PyGen_SetStopIterationValue` (GH-128287)
(cherry picked from commit 402b91d)

Co-authored-by: Bénédikt Tran <[email protected]>
Co-authored-by: Kumar Aditya <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

4 participants