Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 850a4bd

Browse files
authored
Restore PyObject_IsInstance() comment (GH-18345)
Restore PyObject_IsInstance() comment explaining why only tuples of types are accepted, but not general sequence. Comment written by Guido van Rossum in commit 03290ec which implements isinstance(x, (A, B, ...)). The comment was lost in a PyObject_IsInstance() optimization: commit ec569b7. Cleanup also the code. recursive_isinstance() is no longer recursive, so rename it to object_isinstance(), whereas object_isinstance() is recursive and so rename it to object_recursive_isinstance().
1 parent 4590f72 commit 850a4bd

1 file changed

Lines changed: 23 additions & 17 deletions

File tree

Objects/abstract.c

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2423,7 +2423,7 @@ check_class(PyObject *cls, const char *error)
24232423
}
24242424

24252425
static int
2426-
recursive_isinstance(PyObject *inst, PyObject *cls)
2426+
object_isinstance(PyObject *inst, PyObject *cls)
24272427
{
24282428
PyObject *icls;
24292429
int retval;
@@ -2461,67 +2461,73 @@ recursive_isinstance(PyObject *inst, PyObject *cls)
24612461
}
24622462

24632463
static int
2464-
object_isinstance(PyThreadState *tstate, PyObject *inst, PyObject *cls)
2464+
object_recursive_isinstance(PyThreadState *tstate, PyObject *inst, PyObject *cls)
24652465
{
24662466
_Py_IDENTIFIER(__instancecheck__);
2467-
PyObject *checker;
24682467

24692468
/* Quick test for an exact match */
2470-
if (Py_TYPE(inst) == (PyTypeObject *)cls)
2469+
if (Py_TYPE(inst) == (PyTypeObject *)cls) {
24712470
return 1;
2471+
}
24722472

24732473
/* We know what type's __instancecheck__ does. */
24742474
if (PyType_CheckExact(cls)) {
2475-
return recursive_isinstance(inst, cls);
2475+
return object_isinstance(inst, cls);
24762476
}
24772477

24782478
if (PyTuple_Check(cls)) {
2479+
/* Not a general sequence -- that opens up the road to
2480+
recursion and stack overflow. */
24792481
if (_Py_EnterRecursiveCall(tstate, " in __instancecheck__")) {
24802482
return -1;
24812483
}
24822484
Py_ssize_t n = PyTuple_GET_SIZE(cls);
24832485
int r = 0;
24842486
for (Py_ssize_t i = 0; i < n; ++i) {
24852487
PyObject *item = PyTuple_GET_ITEM(cls, i);
2486-
r = object_isinstance(tstate, inst, item);
2487-
if (r != 0)
2488+
r = object_recursive_isinstance(tstate, inst, item);
2489+
if (r != 0) {
24882490
/* either found it, or got an error */
24892491
break;
2492+
}
24902493
}
24912494
_Py_LeaveRecursiveCall(tstate);
24922495
return r;
24932496
}
24942497

2495-
checker = _PyObject_LookupSpecial(cls, &PyId___instancecheck__);
2498+
PyObject *checker = _PyObject_LookupSpecial(cls, &PyId___instancecheck__);
24962499
if (checker != NULL) {
2497-
int ok = -1;
24982500
if (_Py_EnterRecursiveCall(tstate, " in __instancecheck__")) {
24992501
Py_DECREF(checker);
2500-
return ok;
2502+
return -1;
25012503
}
2504+
25022505
PyObject *res = _PyObject_CallOneArg(checker, inst);
25032506
_Py_LeaveRecursiveCall(tstate);
25042507
Py_DECREF(checker);
2505-
if (res != NULL) {
2506-
ok = PyObject_IsTrue(res);
2507-
Py_DECREF(res);
2508+
2509+
if (res == NULL) {
2510+
return -1;
25082511
}
2512+
int ok = PyObject_IsTrue(res);
2513+
Py_DECREF(res);
2514+
25092515
return ok;
25102516
}
25112517
else if (_PyErr_Occurred(tstate)) {
25122518
return -1;
25132519
}
25142520

2515-
/* Probably never reached anymore. */
2516-
return recursive_isinstance(inst, cls);
2521+
/* cls has no __instancecheck__() method */
2522+
return object_isinstance(inst, cls);
25172523
}
25182524

25192525

25202526
int
25212527
PyObject_IsInstance(PyObject *inst, PyObject *cls)
25222528
{
25232529
PyThreadState *tstate = _PyThreadState_GET();
2524-
return object_isinstance(tstate, inst, cls);
2530+
return object_recursive_isinstance(tstate, inst, cls);
25252531
}
25262532

25272533

@@ -2611,7 +2617,7 @@ PyObject_IsSubclass(PyObject *derived, PyObject *cls)
26112617
int
26122618
_PyObject_RealIsInstance(PyObject *inst, PyObject *cls)
26132619
{
2614-
return recursive_isinstance(inst, cls);
2620+
return object_isinstance(inst, cls);
26152621
}
26162622

26172623
int

0 commit comments

Comments
 (0)