Repository navigation
Conversation
rwgk
left a comment
There was a problem hiding this comment.
Beyond the scope of this PR, but I want to log my thoughts:
Looking at the error-clearing code in this test, and the review of #6228 yesterday, made me wonder: How many similar situations do we have in production code?
PyErr_Occurred() detects all Python exceptions, including KeyboardInterrupt and SystemExit. Paths that then clear or replace the error can inadvertently suppress those exceptions. There are examples worth revisiting in py::getattr(..., default) and py::len_hint().
Two ideas to record for potential follow-ups:
- When replacing an exception to provide additional context, use
py::raise_fromto preserve the original cause. That would at least make a swallowed Ctrl-C visible in the reported exception chain. - Consider a helper with semantics similar to Python's
except Exception, for fallback paths that currently use rawPyErr_Occurred()checks. It should propagate otherBaseExceptionsubclasses automatically. Some callers may need narrower handling still, such as suppressing onlyAttributeError.
| PyErr_Clear(); | ||
| PyErr_SetString(PyExc_AssertionError, "sequence::end returned with a pending error"); |
There was a problem hiding this comment.
| PyErr_Clear(); | |
| PyErr_SetString(PyExc_AssertionError, "sequence::end returned with a pending error"); | |
| py::raise_from(PyExc_AssertionError, | |
| "sequence::end returned with a pending error"); |
py::raise_from is already public API. This preserves the original exception and its traceback as the cause of the assertion failure. In particular, a KeyboardInterrupt will remain visible in the exception chain.
This still wraps the interrupt in an AssertionError, but it seems like a reasonable scoped improvement for this test. The existing throw py::error_already_set() below should stay: raise_from sets the Python error indicator without throwing.
@rwgk someone's comment on #2862 (which I filed a long time ago) is what got me thinking about that exact thing. Astra did a scan and I had it create a separate branch for each fix it identified... there are 27 branches that I have locally. So... yeah, this potentially occurs a lot. I'll be pushing some of those branches tonight as PRs, hopefully. |
code and description is 🤖 generated, but it looks right. Related to #2862
Description
Check the signed PySequence_Size result before constructing sequence::end()'s iterator. This preserves length exceptions instead of producing an invalid end offset with a pending Python error.
Suggested changelog entry: