Skip to content

Commit 8e47832

Browse files
committed
Issue #18408: PyObject_Str(), PyObject_Repr() and type_call() now fail with an
assertion error if they are called with an exception set (PyErr_Occurred()). As PyEval_EvalFrameEx(), they may clear the current exception and so the caller looses its exception.
1 parent 4abda5d commit 8e47832

File tree

2 files changed

+23
-0
lines changed

2 files changed

+23
-0
lines changed

Objects/object.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,14 @@ PyObject_Repr(PyObject *v)
377377
if (Py_TYPE(v)->tp_repr == NULL)
378378
return PyUnicode_FromFormat("<%s object at %p>",
379379
v->ob_type->tp_name, v);
380+
381+
#ifdef Py_DEBUG
382+
/* PyObject_Repr() must not be called with an exception set,
383+
because it may clear it (directly or indirectly) and so the
384+
caller looses its exception */
385+
assert(!PyErr_Occurred());
386+
#endif
387+
380388
res = (*v->ob_type->tp_repr)(v);
381389
if (res == NULL)
382390
return NULL;
@@ -408,6 +416,7 @@ PyObject_Str(PyObject *v)
408416
#endif
409417
if (v == NULL)
410418
return PyUnicode_FromString("<NULL>");
419+
411420
if (PyUnicode_CheckExact(v)) {
412421
#ifndef Py_DEBUG
413422
if (PyUnicode_READY(v) < 0)
@@ -419,6 +428,13 @@ PyObject_Str(PyObject *v)
419428
if (Py_TYPE(v)->tp_str == NULL)
420429
return PyObject_Repr(v);
421430

431+
#ifdef Py_DEBUG
432+
/* PyObject_Str() must not be called with an exception set,
433+
because it may clear it (directly or indirectly) and so the
434+
caller looses its exception */
435+
assert(!PyErr_Occurred());
436+
#endif
437+
422438
/* It is possible for a type to have a tp_str representation that loops
423439
infinitely. */
424440
if (Py_EnterRecursiveCall(" while getting the str of an object"))

Objects/typeobject.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,13 @@ type_call(PyTypeObject *type, PyObject *args, PyObject *kwds)
736736
return NULL;
737737
}
738738

739+
#ifdef Py_DEBUG
740+
/* type_call() must not be called with an exception set,
741+
because it may clear it (directly or indirectly) and so the
742+
caller looses its exception */
743+
assert(!PyErr_Occurred());
744+
#endif
745+
739746
obj = type->tp_new(type, args, kwds);
740747
if (obj != NULL) {
741748
/* Ugly exception: when the call was type(something),

0 commit comments

Comments
 (0)