bpo-38644: Pass tstate to Py_EnterRecursiveCall() (GH-16997) · python/cpython@be434dc
11/* Abstract Object Interface (many thanks to Jim Fulton) */
2233#include "Python.h"
4+#include "pycore_pyerrors.h"
45#include "pycore_pystate.h"
56#include <ctype.h>
67#include "structmember.h" /* we need the offsetof() macro from there */
@@ -2459,8 +2460,8 @@ recursive_isinstance(PyObject *inst, PyObject *cls)
24592460return retval;
24602461}
246124622462-int
2463-PyObject_IsInstance(PyObject *inst, PyObject *cls)
2463+static int
2464+object_isinstance(PyThreadState *tstate, PyObject *inst, PyObject *cls)
24642465{
24652466_Py_IDENTIFIER(__instancecheck__);
24662467PyObject *checker;
@@ -2475,47 +2476,55 @@ PyObject_IsInstance(PyObject *inst, PyObject *cls)
24752476 }
2476247724772478if (PyTuple_Check(cls)) {
2478-Py_ssize_t i;
2479-Py_ssize_t n;
2480-int r = 0;
2481-2482-if (Py_EnterRecursiveCall(" in __instancecheck__"))
2479+if (_Py_EnterRecursiveCall(tstate, " in __instancecheck__")) {
24832480return -1;
2484-n = PyTuple_GET_SIZE(cls);
2485-for (i = 0; i < n; ++i) {
2481+ }
2482+Py_ssize_t n = PyTuple_GET_SIZE(cls);
2483+int r = 0;
2484+for (Py_ssize_t i = 0; i < n; ++i) {
24862485PyObject *item = PyTuple_GET_ITEM(cls, i);
2487-r = PyObject_IsInstance(inst, item);
2486+r = object_isinstance(tstate, inst, item);
24882487if (r != 0)
24892488/* either found it, or got an error */
24902489break;
24912490 }
2492-Py_LeaveRecursiveCall();
2491+_Py_LeaveRecursiveCall(tstate);
24932492return r;
24942493 }
2495249424962495checker = _PyObject_LookupSpecial(cls, &PyId___instancecheck__);
24972496if (checker != NULL) {
2498-PyObject *res;
24992497int ok = -1;
2500-if (Py_EnterRecursiveCall(" in __instancecheck__")) {
2498+if (_Py_EnterRecursiveCall(tstate, " in __instancecheck__")) {
25012499Py_DECREF(checker);
25022500return ok;
25032501 }
2504-res = _PyObject_CallOneArg(checker, inst);
2505-Py_LeaveRecursiveCall();
2502+PyObject *res = _PyObject_CallOneArg(checker, inst);
2503+_Py_LeaveRecursiveCall(tstate);
25062504Py_DECREF(checker);
25072505if (res != NULL) {
25082506ok = PyObject_IsTrue(res);
25092507Py_DECREF(res);
25102508 }
25112509return ok;
25122510 }
2513-else if (PyErr_Occurred())
2511+else if (_PyErr_Occurred(tstate)) {
25142512return -1;
2513+ }
2514+25152515/* Probably never reached anymore. */
25162516return recursive_isinstance(inst, cls);
25172517}
251825182519+2520+int
2521+PyObject_IsInstance(PyObject *inst, PyObject *cls)
2522+{
2523+PyThreadState *tstate = _PyThreadState_GET();
2524+return object_isinstance(tstate, inst, cls);
2525+}
2526+2527+25192528static int
25202529recursive_issubclass(PyObject *derived, PyObject *cls)
25212530{
@@ -2534,8 +2543,8 @@ recursive_issubclass(PyObject *derived, PyObject *cls)
25342543return abstract_issubclass(derived, cls);
25352544}
253625452537-int
2538-PyObject_IsSubclass(PyObject *derived, PyObject *cls)
2546+static int
2547+object_issubclass(PyThreadState *tstate, PyObject *derived, PyObject *cls)
25392548{
25402549_Py_IDENTIFIER(__subclasscheck__);
25412550PyObject *checker;
@@ -2549,47 +2558,56 @@ PyObject_IsSubclass(PyObject *derived, PyObject *cls)
25492558 }
2550255925512560if (PyTuple_Check(cls)) {
2552-Py_ssize_t i;
2553-Py_ssize_t n;
2554-int r = 0;
255525612556-if (Py_EnterRecursiveCall(" in __subclasscheck__"))
2562+if (_Py_EnterRecursiveCall(tstate, " in __subclasscheck__")) {
25572563return -1;
2558-n = PyTuple_GET_SIZE(cls);
2559-for (i = 0; i < n; ++i) {
2564+ }
2565+Py_ssize_t n = PyTuple_GET_SIZE(cls);
2566+int r = 0;
2567+for (Py_ssize_t i = 0; i < n; ++i) {
25602568PyObject *item = PyTuple_GET_ITEM(cls, i);
2561-r = PyObject_IsSubclass(derived, item);
2569+r = object_issubclass(tstate, derived, item);
25622570if (r != 0)
25632571/* either found it, or got an error */
25642572break;
25652573 }
2566-Py_LeaveRecursiveCall();
2574+_Py_LeaveRecursiveCall(tstate);
25672575return r;
25682576 }
2569257725702578checker = _PyObject_LookupSpecial(cls, &PyId___subclasscheck__);
25712579if (checker != NULL) {
2572-PyObject *res;
25732580int ok = -1;
2574-if (Py_EnterRecursiveCall(" in __subclasscheck__")) {
2581+if (_Py_EnterRecursiveCall(tstate, " in __subclasscheck__")) {
25752582Py_DECREF(checker);
25762583return ok;
25772584 }
2578-res = _PyObject_CallOneArg(checker, derived);
2579-Py_LeaveRecursiveCall();
2585+PyObject *res = _PyObject_CallOneArg(checker, derived);
2586+_Py_LeaveRecursiveCall(tstate);
25802587Py_DECREF(checker);
25812588if (res != NULL) {
25822589ok = PyObject_IsTrue(res);
25832590Py_DECREF(res);
25842591 }
25852592return ok;
25862593 }
2587-else if (PyErr_Occurred())
2594+else if (_PyErr_Occurred(tstate)) {
25882595return -1;
2596+ }
2597+25892598/* Probably never reached anymore. */
25902599return recursive_issubclass(derived, cls);
25912600}
259226012602+2603+int
2604+PyObject_IsSubclass(PyObject *derived, PyObject *cls)
2605+{
2606+PyThreadState *tstate = _PyThreadState_GET();
2607+return object_issubclass(tstate, derived, cls);
2608+}
2609+2610+25932611int
25942612_PyObject_RealIsInstance(PyObject *inst, PyObject *cls)
25952613{