summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2013-07-17 23:49:30 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2013-07-17 23:49:30 (GMT)
commit8e4783273709df286fb6a83506ead4df8483a695 (patch)
tree007d4eca024d94eed5443aac681da95e5c5e7feb /Objects
parent4abda5d5b08f5ed09f4c72e7ba9726f89aaf8780 (diff)
downloadcpython-8e4783273709df286fb6a83506ead4df8483a695.zip
cpython-8e4783273709df286fb6a83506ead4df8483a695.tar.gz
cpython-8e4783273709df286fb6a83506ead4df8483a695.tar.bz2
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.
Diffstat (limited to 'Objects')
-rw-r--r--Objects/object.c16
-rw-r--r--Objects/typeobject.c7
2 files changed, 23 insertions, 0 deletions
diff --git a/Objects/object.c b/Objects/object.c
index e957d9d..47d3ebd 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -377,6 +377,14 @@ PyObject_Repr(PyObject *v)
if (Py_TYPE(v)->tp_repr == NULL)
return PyUnicode_FromFormat("<%s object at %p>",
v->ob_type->tp_name, v);
+
+#ifdef Py_DEBUG
+ /* PyObject_Repr() must not be called with an exception set,
+ because it may clear it (directly or indirectly) and so the
+ caller looses its exception */
+ assert(!PyErr_Occurred());
+#endif
+
res = (*v->ob_type->tp_repr)(v);
if (res == NULL)
return NULL;
@@ -408,6 +416,7 @@ PyObject_Str(PyObject *v)
#endif
if (v == NULL)
return PyUnicode_FromString("<NULL>");
+
if (PyUnicode_CheckExact(v)) {
#ifndef Py_DEBUG
if (PyUnicode_READY(v) < 0)
@@ -419,6 +428,13 @@ PyObject_Str(PyObject *v)
if (Py_TYPE(v)->tp_str == NULL)
return PyObject_Repr(v);
+#ifdef Py_DEBUG
+ /* PyObject_Str() must not be called with an exception set,
+ because it may clear it (directly or indirectly) and so the
+ caller looses its exception */
+ assert(!PyErr_Occurred());
+#endif
+
/* It is possible for a type to have a tp_str representation that loops
infinitely. */
if (Py_EnterRecursiveCall(" while getting the str of an object"))
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index c970ada..0eea384 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -736,6 +736,13 @@ type_call(PyTypeObject *type, PyObject *args, PyObject *kwds)
return NULL;
}
+#ifdef Py_DEBUG
+ /* type_call() must not be called with an exception set,
+ because it may clear it (directly or indirectly) and so the
+ caller looses its exception */
+ assert(!PyErr_Occurred());
+#endif
+
obj = type->tp_new(type, args, kwds);
if (obj != NULL) {
/* Ugly exception: when the call was type(something),