Skip to content

Commit b58afdb

Browse files
committed
Closes #22540: speed up PyObject_IsInstance and PyObject_IsSubclass in the common case that the second argument has metaclass "type".
1 parent b7a3e84 commit b58afdb

2 files changed

Lines changed: 18 additions & 0 deletions

File tree

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ Release date: TBA
1010
Core and Builtins
1111
-----------------
1212

13+
- Issue #22540: speed up `PyObject_IsInstance` and `PyObject_IsSubclass` in the
14+
common case that the second argument has metaclass `type`.
15+
1316
- Issue #18711: Add a new `PyErr_FormatV` function, similar to `PyErr_Format`
1417
but accepting a `va_list` argument.
1518

Objects/abstract.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2538,6 +2538,11 @@ PyObject_IsInstance(PyObject *inst, PyObject *cls)
25382538
if (Py_TYPE(inst) == (PyTypeObject *)cls)
25392539
return 1;
25402540

2541+
/* We know what type's __instancecheck__ does. */
2542+
if (PyType_CheckExact(cls)) {
2543+
return recursive_isinstance(inst, cls);
2544+
}
2545+
25412546
if (PyTuple_Check(cls)) {
25422547
Py_ssize_t i;
25432548
Py_ssize_t n;
@@ -2576,6 +2581,7 @@ PyObject_IsInstance(PyObject *inst, PyObject *cls)
25762581
}
25772582
else if (PyErr_Occurred())
25782583
return -1;
2584+
/* Probably never reached anymore. */
25792585
return recursive_isinstance(inst, cls);
25802586
}
25812587

@@ -2603,6 +2609,14 @@ PyObject_IsSubclass(PyObject *derived, PyObject *cls)
26032609
_Py_IDENTIFIER(__subclasscheck__);
26042610
PyObject *checker;
26052611

2612+
/* We know what type's __subclasscheck__ does. */
2613+
if (PyType_CheckExact(cls)) {
2614+
/* Quick test for an exact match */
2615+
if (derived == cls)
2616+
return 1;
2617+
return recursive_issubclass(derived, cls);
2618+
}
2619+
26062620
if (PyTuple_Check(cls)) {
26072621
Py_ssize_t i;
26082622
Py_ssize_t n;
@@ -2641,6 +2655,7 @@ PyObject_IsSubclass(PyObject *derived, PyObject *cls)
26412655
}
26422656
else if (PyErr_Occurred())
26432657
return -1;
2658+
/* Probably never reached anymore. */
26442659
return recursive_issubclass(derived, cls);
26452660
}
26462661

0 commit comments

Comments
 (0)