mirror of https://github.com/python/cpython
bpo-32379: Faster MRO computation for single inheritance (#4932)
* bpo-32379: Faster MRO computation for single inheritance
This commit is contained in:
parent
776407fe89
commit
1f1a34c314
|
@ -1783,6 +1783,12 @@ order (MRO) for bases """
|
|||
def f(self): return "C"
|
||||
class D(B, C):
|
||||
pass
|
||||
self.assertEqual(A.mro(), [A, object])
|
||||
self.assertEqual(A.__mro__, (A, object))
|
||||
self.assertEqual(B.mro(), [B, A, object])
|
||||
self.assertEqual(B.__mro__, (B, A, object))
|
||||
self.assertEqual(C.mro(), [C, A, object])
|
||||
self.assertEqual(C.__mro__, (C, A, object))
|
||||
self.assertEqual(D.mro(), [D, B, C, A, object])
|
||||
self.assertEqual(D.__mro__, (D, B, C, A, object))
|
||||
self.assertEqual(D().f(), "C")
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Make MRO computation faster when a class inherits from a single base.
|
|
@ -1761,6 +1761,36 @@ mro_implementation(PyTypeObject *type)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
bases = type->tp_bases;
|
||||
n = PyTuple_GET_SIZE(bases);
|
||||
if (n == 1) {
|
||||
/* Fast path: if there is a single base, constructing the MRO
|
||||
* is trivial.
|
||||
*/
|
||||
PyTypeObject *base = (PyTypeObject *)PyTuple_GET_ITEM(bases, 0);
|
||||
Py_ssize_t k;
|
||||
|
||||
if (base->tp_mro == NULL) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"Cannot extend an incomplete type '%.100s'",
|
||||
base->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
k = PyTuple_GET_SIZE(base->tp_mro);
|
||||
result = PyTuple_New(k + 1);
|
||||
if (result == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
Py_INCREF(type);
|
||||
PyTuple_SET_ITEM(result, 0, (PyObject *) type);
|
||||
for (i = 0; i < k; i++) {
|
||||
PyObject *cls = PyTuple_GET_ITEM(base->tp_mro, i);
|
||||
Py_INCREF(cls);
|
||||
PyTuple_SET_ITEM(result, i + 1, cls);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Find a superclass linearization that honors the constraints
|
||||
of the explicit lists of bases and the constraints implied by
|
||||
each base class.
|
||||
|
@ -1770,9 +1800,6 @@ mro_implementation(PyTypeObject *type)
|
|||
to_merge is the declared list of bases.
|
||||
*/
|
||||
|
||||
bases = type->tp_bases;
|
||||
n = PyTuple_GET_SIZE(bases);
|
||||
|
||||
to_merge = PyList_New(n+1);
|
||||
if (to_merge == NULL)
|
||||
return NULL;
|
||||
|
@ -1830,7 +1857,12 @@ static PyObject *
|
|||
type_mro_impl(PyTypeObject *self)
|
||||
/*[clinic end generated code: output=bffc4a39b5b57027 input=28414f4e156db28d]*/
|
||||
{
|
||||
return mro_implementation(self);
|
||||
PyObject *seq;
|
||||
seq = mro_implementation(self);
|
||||
if (seq != NULL && !PyList_Check(seq)) {
|
||||
Py_SETREF(seq, PySequence_List(seq));
|
||||
}
|
||||
return seq;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
Loading…
Reference in New Issue