diff options
author | Victor Stinner <vstinner@python.org> | 2021-01-27 16:39:16 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-27 16:39:16 (GMT) |
commit | c9b8e9c421b57acdcaf24fab0c93bc29b3ef7c67 (patch) | |
tree | f174c17b926bd968bf19ddd330524bda46e7aa8e /Objects/call.c | |
parent | eeb701adc0fc29ba803fddf133d917ff45639a00 (diff) | |
download | cpython-c9b8e9c421b57acdcaf24fab0c93bc29b3ef7c67.zip cpython-c9b8e9c421b57acdcaf24fab0c93bc29b3ef7c67.tar.gz cpython-c9b8e9c421b57acdcaf24fab0c93bc29b3ef7c67.tar.bz2 |
bpo-42979: Enhance abstract.c assertions checking slot result (GH-24352)
* bpo-42979: Enhance abstract.c assertions checking slot result
Add _Py_CheckSlotResult() function which fails with a fatal error if
a slot function succeeded with an exception set or failed with no
exception set: write the slot name, the type name and the current
exception (if an exception is set).
Diffstat (limited to 'Objects/call.c')
-rw-r--r-- | Objects/call.c | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/Objects/call.c b/Objects/call.c index 35b06a9..1fb85ef 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -39,16 +39,16 @@ _Py_CheckFunctionResult(PyThreadState *tstate, PyObject *callable, if (!_PyErr_Occurred(tstate)) { if (callable) _PyErr_Format(tstate, PyExc_SystemError, - "%R returned NULL without setting an error", + "%R returned NULL without setting an exception", callable); else _PyErr_Format(tstate, PyExc_SystemError, - "%s returned NULL without setting an error", + "%s returned NULL without setting an exception", where); #ifdef Py_DEBUG /* Ensure that the bug is caught in debug mode. Py_FatalError() logs the SystemError exception raised above. */ - Py_FatalError("a function returned NULL without setting an error"); + Py_FatalError("a function returned NULL without setting an exception"); #endif return NULL; } @@ -60,17 +60,17 @@ _Py_CheckFunctionResult(PyThreadState *tstate, PyObject *callable, if (callable) { _PyErr_FormatFromCauseTstate( tstate, PyExc_SystemError, - "%R returned a result with an error set", callable); + "%R returned a result with an exception set", callable); } else { _PyErr_FormatFromCauseTstate( tstate, PyExc_SystemError, - "%s returned a result with an error set", where); + "%s returned a result with an exception set", where); } #ifdef Py_DEBUG /* Ensure that the bug is caught in debug mode. Py_FatalError() logs the SystemError exception raised above. */ - Py_FatalError("a function returned a result with an error set"); + Py_FatalError("a function returned a result with an exception set"); #endif return NULL; } @@ -79,6 +79,30 @@ _Py_CheckFunctionResult(PyThreadState *tstate, PyObject *callable, } +int +_Py_CheckSlotResult(PyObject *obj, const char *slot_name, int success) +{ + PyThreadState *tstate = _PyThreadState_GET(); + if (!success) { + if (!_PyErr_Occurred(tstate)) { + _Py_FatalErrorFormat(__func__, + "Slot %s of type %s failed " + "without setting an exception", + slot_name, Py_TYPE(obj)->tp_name); + } + } + else { + if (_PyErr_Occurred(tstate)) { + _Py_FatalErrorFormat(__func__, + "Slot %s of type %s succeeded " + "with an exception set", + slot_name, Py_TYPE(obj)->tp_name); + } + } + return 1; +} + + /* --- Core PyObject call functions ------------------------------- */ /* Call a callable Python object without any arguments */ |