diff options
| author | Antoine Pitrou <pitrou@free.fr> | 2017-12-20 15:58:21 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-12-20 15:58:21 +0100 |
| commit | 1f1a34c3145781628e10534440017b3b43211a60 (patch) | |
| tree | a69adc703ecdbd1749bc9b6671d73d04742c9843 /Objects/typeobject.c | |
| parent | 776407fe893fd42972c7e3f71423d9d86741d07c (diff) | |
| download | cpython-git-1f1a34c3145781628e10534440017b3b43211a60.tar.gz | |
bpo-32379: Faster MRO computation for single inheritance (#4932)
* bpo-32379: Faster MRO computation for single inheritance
Diffstat (limited to 'Objects/typeobject.c')
| -rw-r--r-- | Objects/typeobject.c | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c index aa90701885..849c6dc192 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -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 |
