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

gh-128078: clear caller's StopAsyncIteration in _PyGen_SetStopIterationValue #128287

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

picnixz
Copy link
Contributor

@picnixz picnixz commented Dec 27, 2024

Some calls have a StopAsyncIteration exception set at this point but we should ignore them since this function is meant to create a StopIteration instead (or replace an existing StopAsyncIteration)

Alternative I have also envisaged:

  • Unconditionally clear an optional caller's exception: this would be probably fine but this could hide bugs.
  • Also clear StopIteration: strictly speaking I think we could also do it but as I'm not extremely familiar with the call graph, I'd prefer restricting it to StopAsyncIteration for now.

@picnixz picnixz requested a review from markshannon as a code owner December 27, 2024 12:48
@picnixz picnixz changed the title gh-128078: clear StopIteration-like exceptions in _PyGen_SetStopIterationValue gh-128078: clear caller's StopAsyncIteration in _PyGen_SetStopIterationValue Dec 27, 2024
@picnixz picnixz added needs backport to 3.12 bug and security fixes needs backport to 3.13 bugs and security fixes labels Dec 27, 2024
// an exception of another type should not already be set.
PyObject *run_ex = PyErr_Occurred();
if (run_ex) {
if (!PyErr_GivenExceptionMatches(run_ex, PyExc_StopAsyncIteration)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can just use PyErr_ExceptionMatches to skip the PyErr_Occurred call.

// Replace existing bad exception with a SystemError instead.
PyErr_Format(PyExc_SystemError,
"%s:%d: unexpected caller exception: %R",
__FILE__, __LINE__, run_ex);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have any precedent for passing __FILE__ and __LINE__ to errors from C? But anyways, I don't think displaying the exception like this is a good way to do it; we should just set it as a cause. (Also, this should probably be a RuntimeError instead of a SystemError--those should generally not be raisable from Python.)

You could do it with something like this:

PyObject *cause = PyErr_GetRaisedException();
PyErr_SetString(PyExc_RuntimeError, "unexpected exception");
PyObject *err = PyErr_GetRaisedException();
PyException_SetCause(err, cause);
PyErr_SetRaisedException(err);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting review needs backport to 3.12 bug and security fixes needs backport to 3.13 bugs and security fixes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants