◐ Shell
clean mode source ↗

gh-118331: Don't raise an error if tuple allocation fails when clearing weakrefs by mpage · Pull Request #118338 · python/cpython

It's not safe to raise an exception in PyObject_ClearWeakRefs() if one is not already set. PyObject_ClearWeakRefs() may be called (transitively) by _Py_Dealloc(), which contains

// gh-89373: The tp_dealloc function must leave the current exception
// unchanged.
if (tstate != NULL && tstate->current_exception != old_exc) {
const char *err;
if (old_exc == NULL) {
err = "Deallocator of type '%s' raised an exception";
}
else if (tstate->current_exception == NULL) {
err = "Deallocator of type '%s' cleared the current exception";
}
else {
// It can happen if dealloc() normalized the current exception.
// A deallocator function must not change the current exception,
// not even normalize it.
err = "Deallocator of type '%s' overrode the current exception";
}
_Py_FatalErrorFormat(__func__, err, type->tp_name);
}

Additionally, make sure we clear the weakrefs when tuple allocation fails.

This bug predates gh-111926. It exists in 3.12 and likely in earlier versions too. If it's getting tickled now, I suspect it's because we always allocate a tuple now when clearing weakrefs that have callbacks, whereas previously we only did so if there was more than one weakref with a callback, making it more likely that we fail to allocate a tuple when running test_repl.TestInteractiveInterpreter.test_no_memory.