summaryrefslogtreecommitdiff
path: root/Objects
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2019-11-05 00:51:22 +0100
committerGitHub <noreply@github.com>2019-11-05 00:51:22 +0100
commitbe434dc0380d9f5c7c800de9943cc46d55fd9491 (patch)
treebbf95dcf9ccc433e071cb4ce09984b5c5128f67e /Objects
parentf4b1e3d7c64985f5d5b00f6cc9a1c146bbbfd613 (diff)
downloadcpython-git-be434dc0380d9f5c7c800de9943cc46d55fd9491.tar.gz
bpo-38644: Pass tstate to Py_EnterRecursiveCall() (GH-16997)
* Add _Py_EnterRecursiveCall() and _Py_LeaveRecursiveCall() which require a tstate argument. * Pass tstate to _Py_MakeRecCheck() and _Py_CheckRecursiveCall(). * Convert Py_EnterRecursiveCall() and Py_LeaveRecursiveCall() macros to static inline functions. _PyThreadState_GET() is the most efficient way to get the tstate, and so using it with _Py_EnterRecursiveCall() and _Py_LeaveRecursiveCall() should be a little bit more efficient than using Py_EnterRecursiveCall() and Py_LeaveRecursiveCall() which use the "slower" PyThreadState_GET().
Diffstat (limited to 'Objects')
-rw-r--r--Objects/abstract.c80
-rw-r--r--Objects/call.c42
-rw-r--r--Objects/descrobject.c34
-rw-r--r--Objects/methodobject.c50
-rw-r--r--Objects/object.c70
5 files changed, 162 insertions, 114 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c
index 3db56fab2c..dc8ba10762 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -1,6 +1,7 @@
/* Abstract Object Interface (many thanks to Jim Fulton) */
#include "Python.h"
+#include "pycore_pyerrors.h"
#include "pycore_pystate.h"
#include <ctype.h>
#include "structmember.h" /* we need the offsetof() macro from there */
@@ -2459,8 +2460,8 @@ recursive_isinstance(PyObject *inst, PyObject *cls)
return retval;
}
-int
-PyObject_IsInstance(PyObject *inst, PyObject *cls)
+static int
+object_isinstance(PyThreadState *tstate, PyObject *inst, PyObject *cls)
{
_Py_IDENTIFIER(__instancecheck__);
PyObject *checker;
@@ -2475,34 +2476,31 @@ PyObject_IsInstance(PyObject *inst, PyObject *cls)
}
if (PyTuple_Check(cls)) {
- Py_ssize_t i;
- Py_ssize_t n;
- int r = 0;
-
- if (Py_EnterRecursiveCall(" in __instancecheck__"))
+ if (_Py_EnterRecursiveCall(tstate, " in __instancecheck__")) {
return -1;
- n = PyTuple_GET_SIZE(cls);
- for (i = 0; i < n; ++i) {
+ }
+ Py_ssize_t n = PyTuple_GET_SIZE(cls);
+ int r = 0;
+ for (Py_ssize_t i = 0; i < n; ++i) {
PyObject *item = PyTuple_GET_ITEM(cls, i);
- r = PyObject_IsInstance(inst, item);
+ r = object_isinstance(tstate, inst, item);
if (r != 0)
/* either found it, or got an error */
break;
}
- Py_LeaveRecursiveCall();
+ _Py_LeaveRecursiveCall(tstate);
return r;
}
checker = _PyObject_LookupSpecial(cls, &PyId___instancecheck__);
if (checker != NULL) {
- PyObject *res;
int ok = -1;
- if (Py_EnterRecursiveCall(" in __instancecheck__")) {
+ if (_Py_EnterRecursiveCall(tstate, " in __instancecheck__")) {
Py_DECREF(checker);
return ok;
}
- res = _PyObject_CallOneArg(checker, inst);
- Py_LeaveRecursiveCall();
+ PyObject *res = _PyObject_CallOneArg(checker, inst);
+ _Py_LeaveRecursiveCall(tstate);
Py_DECREF(checker);
if (res != NULL) {
ok = PyObject_IsTrue(res);
@@ -2510,12 +2508,23 @@ PyObject_IsInstance(PyObject *inst, PyObject *cls)
}
return ok;
}
- else if (PyErr_Occurred())
+ else if (_PyErr_Occurred(tstate)) {
return -1;
+ }
+
/* Probably never reached anymore. */
return recursive_isinstance(inst, cls);
}
+
+int
+PyObject_IsInstance(PyObject *inst, PyObject *cls)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ return object_isinstance(tstate, inst, cls);
+}
+
+
static int
recursive_issubclass(PyObject *derived, PyObject *cls)
{
@@ -2534,8 +2543,8 @@ recursive_issubclass(PyObject *derived, PyObject *cls)
return abstract_issubclass(derived, cls);
}
-int
-PyObject_IsSubclass(PyObject *derived, PyObject *cls)
+static int
+object_issubclass(PyThreadState *tstate, PyObject *derived, PyObject *cls)
{
_Py_IDENTIFIER(__subclasscheck__);
PyObject *checker;
@@ -2549,34 +2558,32 @@ PyObject_IsSubclass(PyObject *derived, PyObject *cls)
}
if (PyTuple_Check(cls)) {
- Py_ssize_t i;
- Py_ssize_t n;
- int r = 0;
- if (Py_EnterRecursiveCall(" in __subclasscheck__"))
+ if (_Py_EnterRecursiveCall(tstate, " in __subclasscheck__")) {
return -1;
- n = PyTuple_GET_SIZE(cls);
- for (i = 0; i < n; ++i) {
+ }
+ Py_ssize_t n = PyTuple_GET_SIZE(cls);
+ int r = 0;
+ for (Py_ssize_t i = 0; i < n; ++i) {
PyObject *item = PyTuple_GET_ITEM(cls, i);
- r = PyObject_IsSubclass(derived, item);
+ r = object_issubclass(tstate, derived, item);
if (r != 0)
/* either found it, or got an error */
break;
}
- Py_LeaveRecursiveCall();
+ _Py_LeaveRecursiveCall(tstate);
return r;
}
checker = _PyObject_LookupSpecial(cls, &PyId___subclasscheck__);
if (checker != NULL) {
- PyObject *res;
int ok = -1;
- if (Py_EnterRecursiveCall(" in __subclasscheck__")) {
+ if (_Py_EnterRecursiveCall(tstate, " in __subclasscheck__")) {
Py_DECREF(checker);
return ok;
}
- res = _PyObject_CallOneArg(checker, derived);
- Py_LeaveRecursiveCall();
+ PyObject *res = _PyObject_CallOneArg(checker, derived);
+ _Py_LeaveRecursiveCall(tstate);
Py_DECREF(checker);
if (res != NULL) {
ok = PyObject_IsTrue(res);
@@ -2584,12 +2591,23 @@ PyObject_IsSubclass(PyObject *derived, PyObject *cls)
}
return ok;
}
- else if (PyErr_Occurred())
+ else if (_PyErr_Occurred(tstate)) {
return -1;
+ }
+
/* Probably never reached anymore. */
return recursive_issubclass(derived, cls);
}
+
+int
+PyObject_IsSubclass(PyObject *derived, PyObject *cls)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ return object_issubclass(tstate, derived, cls);
+}
+
+
int
_PyObject_RealIsInstance(PyObject *inst, PyObject *cls)
{
diff --git a/Objects/call.c b/Objects/call.c
index a715bcbee4..b7588b302f 100644
--- a/Objects/call.c
+++ b/Objects/call.c
@@ -1,5 +1,6 @@
#include "Python.h"
#include "pycore_object.h"
+#include "pycore_pyerrors.h"
#include "pycore_pystate.h"
#include "pycore_tupleobject.h"
#include "frameobject.h"
@@ -126,12 +127,15 @@ _PyObject_FastCallDict(PyObject *callable, PyObject *const *args,
PyObject *
_PyObject_MakeTpCall(PyObject *callable, PyObject *const *args, Py_ssize_t nargs, PyObject *keywords)
{
+ PyThreadState *tstate = _PyThreadState_GET();
+
/* Slow path: build a temporary tuple for positional arguments and a
* temporary dictionary for keyword arguments (if any) */
ternaryfunc call = Py_TYPE(callable)->tp_call;
if (call == NULL) {
- PyErr_Format(PyExc_TypeError, "'%.200s' object is not callable",
- Py_TYPE(callable)->tp_name);
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "'%.200s' object is not callable",
+ Py_TYPE(callable)->tp_name);
return NULL;
}
@@ -162,10 +166,10 @@ _PyObject_MakeTpCall(PyObject *callable, PyObject *const *args, Py_ssize_t nargs
}
PyObject *result = NULL;
- if (Py_EnterRecursiveCall(" while calling a Python object") == 0)
+ if (_Py_EnterRecursiveCall(tstate, " while calling a Python object") == 0)
{
result = call(callable, argstuple, kwdict);
- Py_LeaveRecursiveCall();
+ _Py_LeaveRecursiveCall(tstate);
}
Py_DECREF(argstuple);
@@ -220,13 +224,14 @@ PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwargs)
PyObject *
PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs)
{
+ PyThreadState *tstate = _PyThreadState_GET();
ternaryfunc call;
PyObject *result;
/* PyObject_Call() must not be called with an exception set,
because it can clear it (directly or indirectly) and so the
caller loses its exception */
- assert(!PyErr_Occurred());
+ assert(!_PyErr_Occurred(tstate));
assert(PyTuple_Check(args));
assert(kwargs == NULL || PyDict_Check(kwargs));
@@ -236,17 +241,19 @@ PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs)
else {
call = callable->ob_type->tp_call;
if (call == NULL) {
- PyErr_Format(PyExc_TypeError, "'%.200s' object is not callable",
- callable->ob_type->tp_name);
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "'%.200s' object is not callable",
+ callable->ob_type->tp_name);
return NULL;
}
- if (Py_EnterRecursiveCall(" while calling a Python object"))
+ if (_Py_EnterRecursiveCall(tstate, " while calling a Python object")) {
return NULL;
+ }
result = (*call)(callable, args, kwargs);
- Py_LeaveRecursiveCall();
+ _Py_LeaveRecursiveCall(tstate);
return _Py_CheckFunctionResult(callable, result, NULL);
}
@@ -266,30 +273,27 @@ static PyObject* _Py_HOT_FUNCTION
function_code_fastcall(PyCodeObject *co, PyObject *const *args, Py_ssize_t nargs,
PyObject *globals)
{
- PyFrameObject *f;
+ assert(globals != NULL);
+
PyThreadState *tstate = _PyThreadState_GET();
- PyObject **fastlocals;
- Py_ssize_t i;
- PyObject *result;
+ assert(tstate != NULL);
- assert(globals != NULL);
/* XXX Perhaps we should create a specialized
_PyFrame_New_NoTrack() that doesn't take locals, but does
take builtins without sanity checking them.
*/
- assert(tstate != NULL);
- f = _PyFrame_New_NoTrack(tstate, co, globals, NULL);
+ PyFrameObject *f = _PyFrame_New_NoTrack(tstate, co, globals, NULL);
if (f == NULL) {
return NULL;
}
- fastlocals = f->f_localsplus;
+ PyObject **fastlocals = f->f_localsplus;
- for (i = 0; i < nargs; i++) {
+ for (Py_ssize_t i = 0; i < nargs; i++) {
Py_INCREF(*args);
fastlocals[i] = *args++;
}
- result = PyEval_EvalFrameEx(f,0);
+ PyObject *result = PyEval_EvalFrameEx(f, 0);
if (Py_REFCNT(f) > 1) {
Py_DECREF(f);
diff --git a/Objects/descrobject.c b/Objects/descrobject.c
index c50fe00ce8..dbab4cd4da 100644
--- a/Objects/descrobject.c
+++ b/Objects/descrobject.c
@@ -271,9 +271,9 @@ method_check_args(PyObject *func, PyObject *const *args, Py_ssize_t nargs, PyObj
}
static inline funcptr
-method_enter_call(PyObject *func)
+method_enter_call(PyThreadState *tstate, PyObject *func)
{
- if (Py_EnterRecursiveCall(" while calling a Python object")) {
+ if (_Py_EnterRecursiveCall(tstate, " while calling a Python object")) {
return NULL;
}
return (funcptr)((PyMethodDescrObject *)func)->d_method->ml_meth;
@@ -284,6 +284,7 @@ static PyObject *
method_vectorcall_VARARGS(
PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
{
+ PyThreadState *tstate = _PyThreadState_GET();
Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
if (method_check_args(func, args, nargs, kwnames)) {
return NULL;
@@ -292,14 +293,14 @@ method_vectorcall_VARARGS(
if (argstuple == NULL) {
return NULL;
}
- PyCFunction meth = (PyCFunction)method_enter_call(func);
+ PyCFunction meth = (PyCFunction)method_enter_call(tstate, func);
if (meth == NULL) {
Py_DECREF(argstuple);
return NULL;
}
PyObject *result = meth(args[0], argstuple);
Py_DECREF(argstuple);
- Py_LeaveRecursiveCall();
+ _Py_LeaveRecursiveCall(tstate);
return result;
}
@@ -307,6 +308,7 @@ static PyObject *
method_vectorcall_VARARGS_KEYWORDS(
PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
{
+ PyThreadState *tstate = _PyThreadState_GET();
Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
if (method_check_args(func, args, nargs, NULL)) {
return NULL;
@@ -325,12 +327,12 @@ method_vectorcall_VARARGS_KEYWORDS(
}
}
PyCFunctionWithKeywords meth = (PyCFunctionWithKeywords)
- method_enter_call(func);
+ method_enter_call(tstate, func);
if (meth == NULL) {
goto exit;
}
result = meth(args[0], argstuple, kwdict);
- Py_LeaveRecursiveCall();
+ _Py_LeaveRecursiveCall(tstate);
exit:
Py_DECREF(argstuple);
Py_XDECREF(kwdict);
@@ -341,17 +343,18 @@ static PyObject *
method_vectorcall_FASTCALL(
PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
{
+ PyThreadState *tstate = _PyThreadState_GET();
Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
if (method_check_args(func, args, nargs, kwnames)) {
return NULL;
}
_PyCFunctionFast meth = (_PyCFunctionFast)
- method_enter_call(func);
+ method_enter_call(tstate, func);
if (meth == NULL) {
return NULL;
}
PyObject *result = meth(args[0], args+1, nargs-1);
- Py_LeaveRecursiveCall();
+ _Py_LeaveRecursiveCall(tstate);
return result;
}
@@ -359,17 +362,18 @@ static PyObject *
method_vectorcall_FASTCALL_KEYWORDS(
PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
{
+ PyThreadState *tstate = _PyThreadState_GET();
Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
if (method_check_args(func, args, nargs, NULL)) {
return NULL;
}
_PyCFunctionFastWithKeywords meth = (_PyCFunctionFastWithKeywords)
- method_enter_call(func);
+ method_enter_call(tstate, func);
if (meth == NULL) {
return NULL;
}
PyObject *result = meth(args[0], args+1, nargs-1, kwnames);
- Py_LeaveRecursiveCall();
+ _Py_LeaveRecursiveCall(tstate);
return result;
}
@@ -377,6 +381,7 @@ static PyObject *
method_vectorcall_NOARGS(
PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
{
+ PyThreadState *tstate = _PyThreadState_GET();
Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
if (method_check_args(func, args, nargs, kwnames)) {
return NULL;
@@ -386,12 +391,12 @@ method_vectorcall_NOARGS(
"%.200s() takes no arguments (%zd given)", get_name(func), nargs-1);
return NULL;
}
- PyCFunction meth = (PyCFunction)method_enter_call(func);
+ PyCFunction meth = (PyCFunction)method_enter_call(tstate, func);
if (meth == NULL) {
return NULL;
}
PyObject *result = meth(args[0], NULL);
- Py_LeaveRecursiveCall();
+ _Py_LeaveRecursiveCall(tstate);
return result;
}
@@ -399,6 +404,7 @@ static PyObject *
method_vectorcall_O(
PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
{
+ PyThreadState *tstate = _PyThreadState_GET();
Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
if (method_check_args(func, args, nargs, kwnames)) {
return NULL;
@@ -409,12 +415,12 @@ method_vectorcall_O(
get_name(func), nargs-1);
return NULL;
}
- PyCFunction meth = (PyCFunction)method_enter_call(func);
+ PyCFunction meth = (PyCFunction)method_enter_call(tstate, func);
if (meth == NULL) {
return NULL;
}
PyObject *result = meth(args[0], args[1]);
- Py_LeaveRecursiveCall();
+ _Py_LeaveRecursiveCall(tstate);
return result;
}
diff --git a/Objects/methodobject.c b/Objects/methodobject.c
index a5f0c5d346..3ce15604b9 100644
--- a/Objects/methodobject.c
+++ b/Objects/methodobject.c
@@ -3,6 +3,7 @@
#include "Python.h"
#include "pycore_object.h"
+#include "pycore_pyerrors.h"
#include "pycore_pymem.h"
#include "pycore_pystate.h"
#include "structmember.h"
@@ -344,22 +345,22 @@ get_name(PyObject *func)
typedef void (*funcptr)(void);
static inline int
-cfunction_check_kwargs(PyObject *func, PyObject *kwnames)
+cfunction_check_kwargs(PyThreadState *tstate, PyObject *func, PyObject *kwnames)
{
- assert(!PyErr_Occurred());
+ assert(!_PyErr_Occurred(tstate));
assert(PyCFunction_Check(func));
if (kwnames && PyTuple_GET_SIZE(kwnames)) {
- PyErr_Format(PyExc_TypeError,
- "%.200s() takes no keyword arguments", get_name(func));
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "%.200s() takes no keyword arguments", get_name(func));
return -1;
}
return 0;
}
static inline funcptr
-cfunction_enter_call(PyObject *func)
+cfunction_enter_call(PyThreadState *tstate, PyObject *func)
{
- if (Py_EnterRecursiveCall(" while calling a Python object")) {
+ if (_Py_EnterRecursiveCall(tstate, " while calling a Python object")) {
return NULL;
}
return (funcptr)PyCFunction_GET_FUNCTION(func);
@@ -370,17 +371,18 @@ static PyObject *
cfunction_vectorcall_FASTCALL(
PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
{
- if (cfunction_check_kwargs(func, kwnames)) {
+ PyThreadState *tstate = _PyThreadState_GET();
+ if (cfunction_check_kwargs(tstate, func, kwnames)) {
return NULL;
}
Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
_PyCFunctionFast meth = (_PyCFunctionFast)
- cfunction_enter_call(func);
+ cfunction_enter_call(tstate, func);
if (meth == NULL) {
return NULL;
}
PyObject *result = meth(PyCFunction_GET_SELF(func), args, nargs);
- Py_LeaveRecursiveCall();
+ _Py_LeaveRecursiveCall(tstate);
return result;
}
@@ -388,14 +390,15 @@ static PyObject *
cfunction_vectorcall_FASTCALL_KEYWORDS(
PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
{
+ PyThreadState *tstate = _PyThreadState_GET();
Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
_PyCFunctionFastWithKeywords meth = (_PyCFunctionFastWithKeywords)
- cfunction_enter_call(func);
+ cfunction_enter_call(tstate, func);
if (meth == NULL) {
return NULL;
}
PyObject *result = meth(PyCFunction_GET_SELF(func), args, nargs, kwnames);
- Py_LeaveRecursiveCall();
+ _Py_LeaveRecursiveCall(tstate);
return result;
}
@@ -403,21 +406,23 @@ static PyObject *
cfunction_vectorcall_NOARGS(
PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
{
- if (cfunction_check_kwargs(func, kwnames)) {
+ PyThreadState *tstate = _PyThreadState_GET();
+ if (cfunction_check_kwargs(tstate, func, kwnames)) {
return NULL;
}
Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
if (nargs != 0) {
- PyErr_Format(PyExc_TypeError,
- "%.200s() takes no arguments (%zd given)", get_name(func), nargs);
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "%.200s() takes no arguments (%zd given)",
+ get_name(func), nargs);
return NULL;
}
- PyCFunction meth = (PyCFunction)cfunction_enter_call(func);
+ PyCFunction meth = (PyCFunction)cfunction_enter_call(tstate, func);
if (meth == NULL) {
return NULL;
}
PyObject *result = meth(PyCFunction_GET_SELF(func), NULL);
- Py_LeaveRecursiveCall();
+ _Py_LeaveRecursiveCall(tstate);
return result;
}
@@ -425,22 +430,23 @@ static PyObject *
cfunction_vectorcall_O(
PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
{
- if (cfunction_check_kwargs(func, kwnames)) {
+ PyThreadState *tstate = _PyThreadState_GET();
+ if (cfunction_check_kwargs(tstate, func, kwnames)) {
return NULL;
}
Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
if (nargs != 1) {
- PyErr_Format(PyExc_TypeError,
- "%.200s() takes exactly one argument (%zd given)",
- get_name(func), nargs);
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "%.200s() takes exactly one argument (%zd given)",
+ get_name(func), nargs);
return NULL;
}
- PyCFunction meth = (PyCFunction)cfunction_enter_call(func);
+ PyCFunction meth = (PyCFunction)cfunction_enter_call(tstate, func);
if (meth == NULL) {
return NULL;
}
PyObject *result = meth(PyCFunction_GET_SELF(func), args[0]);
- Py_LeaveRecursiveCall();
+ _Py_LeaveRecursiveCall(tstate);
return result;
}
diff --git a/Objects/object.c b/Objects/object.c
index 2c8e823f05..9536d467f5 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -2,10 +2,11 @@
/* Generic object operations; and implementation of None */
#include "Python.h"
+#include "pycore_context.h"
#include "pycore_initconfig.h"
#include "pycore_object.h"
+#include "pycore_pyerrors.h"
#include "pycore_pystate.h"
-#include "pycore_context.h"
#include "frameobject.h"
#include "interpreteridobject.h"
@@ -525,31 +526,37 @@ PyObject_Repr(PyObject *v)
return PyUnicode_FromFormat("<%s object at %p>",
v->ob_type->tp_name, v);
+ PyThreadState *tstate = _PyThreadState_GET();
#ifdef Py_DEBUG
/* PyObject_Repr() must not be called with an exception set,
because it can clear it (directly or indirectly) and so the
caller loses its exception */
- assert(!PyErr_Occurred());
+ assert(!_PyErr_Occurred(tstate));
#endif
/* It is possible for a type to have a tp_repr representation that loops
infinitely. */
- if (Py_EnterRecursiveCall(" while getting the repr of an object"))
+ if (_Py_EnterRecursiveCall(tstate,
+ " while getting the repr of an object")) {
return NULL;
+ }
res = (*v->ob_type->tp_repr)(v);
- Py_LeaveRecursiveCall();
- if (res == NULL)
+ _Py_LeaveRecursiveCall(tstate);
+
+ if (res == NULL) {
return NULL;
+ }
if (!PyUnicode_Check(res)) {
- PyErr_Format(PyExc_TypeError,
- "__repr__ returned non-string (type %.200s)",
- res->ob_type->tp_name);
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "__repr__ returned non-string (type %.200s)",
+ res->ob_type->tp_name);
Py_DECREF(res);
return NULL;
}
#ifndef Py_DEBUG
- if (PyUnicode_READY(res) < 0)
+ if (PyUnicode_READY(res) < 0) {
return NULL;
+ }
#endif
return res;
}
@@ -579,31 +586,36 @@ PyObject_Str(PyObject *v)
if (Py_TYPE(v)->tp_str == NULL)
return PyObject_Repr(v);
+ PyThreadState *tstate = _PyThreadState_GET();
#ifdef Py_DEBUG
/* PyObject_Str() must not be called with an exception set,
because it can clear it (directly or indirectly) and so the
caller loses its exception */
- assert(!PyErr_Occurred());
+ assert(!_PyErr_Occurred(tstate));
#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"))
+ if (_Py_EnterRecursiveCall(tstate, " while getting the str of an object")) {
return NULL;
+ }
res = (*Py_TYPE(v)->tp_str)(v);
- Py_LeaveRecursiveCall();
- if (res == NULL)
+ _Py_LeaveRecursiveCall(tstate);
+
+ if (res == NULL) {
return NULL;
+ }
if (!PyUnicode_Check(res)) {
- PyErr_Format(PyExc_TypeError,
- "__str__ returned non-string (type %.200s)",
- Py_TYPE(res)->tp_name);
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "__str__ returned non-string (type %.200s)",
+ Py_TYPE(res)->tp_name);
Py_DECREF(res);
return NULL;
}
#ifndef Py_DEBUG
- if (PyUnicode_READY(res) < 0)
+ if (PyUnicode_READY(res) < 0) {
return NULL;
+ }
#endif
assert(_PyUnicode_CheckConsistency(res, 1));
return res;
@@ -707,7 +719,7 @@ static const char * const opstrings[] = {"<", "<=", "==", "!=", ">", ">="};
/* Perform a rich comparison, raising TypeError when the requested comparison
operator is not supported. */
static PyObject *
-do_richcompare(PyObject *v, PyObject *w, int op)
+do_richcompare(PyThreadState *tstate, PyObject *v, PyObject *w, int op)
{
richcmpfunc f;
PyObject *res;
@@ -744,11 +756,11 @@ do_richcompare(PyObject *v, PyObject *w, int op)
res = (v != w) ? Py_True : Py_False;
break;
default:
- PyErr_Format(PyExc_TypeError,
- "'%s' not supported between instances of '%.100s' and '%.100s'",
- opstrings[op],
- v->ob_type->tp_name,
- w->ob_type->tp_name);
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "'%s' not supported between instances of '%.100s' and '%.100s'",
+ opstrings[op],
+ v->ob_type->tp_name,
+ w->ob_type->tp_name);
return NULL;
}
Py_INCREF(res);
@@ -761,18 +773,20 @@ do_richcompare(PyObject *v, PyObject *w, int op)
PyObject *
PyObject_RichCompare(PyObject *v, PyObject *w, int op)
{
- PyObject *res;
+ PyThreadState *tstate = _PyThreadState_GET();
assert(Py_LT <= op && op <= Py_GE);
if (v == NULL || w == NULL) {
- if (!PyErr_Occurred())
+ if (!_PyErr_Occurred(tstate)) {
PyErr_BadInternalCall();
+ }
return NULL;
}
- if (Py_EnterRecursiveCall(" in comparison"))
+ if (_Py_EnterRecursiveCall(tstate, " in comparison")) {
return NULL;
- res = do_richcompare(v, w, op);
- Py_LeaveRecursiveCall();
+ }
+ PyObject *res = do_richcompare(tstate, v, w, op);
+ _Py_LeaveRecursiveCall(tstate);
return res;
}