◐ Shell
clean mode source ↗

Inconsistencies in error propagation after calling `_PyFrame_GetFrameObject`

Bug report

Bug description:

There are 3 callers of _PyFrame_GetFrameObject which explicitly clear error when it returns NULL.

  1. take_ownership
    PyFrameObject *back = _PyFrame_GetFrameObject(prev);
    if (back == NULL) {
    /* Memory error here. */
    assert(PyErr_ExceptionMatches(PyExc_MemoryError));
    /* Nothing we can do about it */
    PyErr_Clear();
  2. PyEval_GetFrame
    PyFrameObject *f = _PyFrame_GetFrameObject(frame);
    if (f == NULL) {
    PyErr_Clear();
  3. PyThreadState_GetFrame
    PyFrameObject *frame = _PyFrame_GetFrameObject(f);
    if (frame == NULL) {
    PyErr_Clear();

PyEval_GetFrame and PyThreadState_GetFrame docs say that NULL is returned when "no frame is currently executing", and doesn't say anything about any error (probably as they explicitly clear it?).

I wonder whether PyFrame_GetBack also would want to clear error

if (prev) {
back = _PyFrame_GetFrameObject(prev);
}

PyFrame_GetBack's documentation doesn't say anything about MemoryError which can be set by its internal API calls https://docs.python.org/3.15/c-api/frame.html#c.PyFrame_GetBack

The rest of the _PyFrame_GetFrameObject callers that don't clear error including PyFrame_GetBack are

And PyEval_GetLocals and PyFrame_GetBack are public C APIs that don't check for NULL and don't clear the error. I guess the internals are ok to propagate the errors?

Can someone explain whether PyFrame_GetBack not clearing error on null is ok/intended or it's a discrepancy/bug?

I would prefer PyFrame_GetBack to not propagate an error given that its documentation doesn't say anything about MemoryError.

CPython versions tested on:

CPython main branch

Operating systems tested on:

No response

Linked PRs