[3.7] bpo-28866: No type cache for types with specialized mro, invali… · python/cpython@bfd0b77 (original) (raw)
`@@ -77,6 +77,9 @@ slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
`
77
77
`static void
`
78
78
`clear_slotdefs(void);
`
79
79
``
``
80
`+
static PyObject *
`
``
81
`+
lookup_maybe_method(PyObject *self, _Py_Identifier *attrid, int *unbound);
`
``
82
+
80
83
`/*
`
81
84
` * finds the beginning of the docstring's introspection signature.
`
82
85
` * if present, returns a pointer pointing to the first '('.
`
`@@ -281,17 +284,35 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) {
`
281
284
``
282
285
` Unset HAVE_VERSION_TAG and VALID_VERSION_TAG if the type
`
283
286
` has a custom MRO that includes a type which is not officially
`
284
``
`-
super type.
`
``
287
`+
super type, or if the type implements its own mro() method.
`
285
288
``
286
289
` Called from mro_internal, which will subsequently be called on
`
287
290
` each subclass when their mro is recursively updated.
`
288
291
` */
`
289
292
`Py_ssize_t i, n;
`
290
``
`-
int clear = 0;
`
``
293
`+
int custom = (Py_TYPE(type) != &PyType_Type);
`
``
294
`+
int unbound;
`
``
295
`+
PyObject *mro_meth = NULL;
`
``
296
`+
PyObject *type_mro_meth = NULL;
`
291
297
``
292
298
`if (!PyType_HasFeature(type, Py_TPFLAGS_HAVE_VERSION_TAG))
`
293
299
`return;
`
294
300
``
``
301
`+
if (custom) {
`
``
302
`+
_Py_IDENTIFIER(mro);
`
``
303
`+
mro_meth = lookup_maybe_method(
`
``
304
`+
(PyObject *)type, &PyId_mro, &unbound);
`
``
305
`+
if (mro_meth == NULL)
`
``
306
`+
goto clear;
`
``
307
`+
type_mro_meth = lookup_maybe_method(
`
``
308
`+
(PyObject *)&PyType_Type, &PyId_mro, &unbound);
`
``
309
`+
if (type_mro_meth == NULL)
`
``
310
`+
goto clear;
`
``
311
`+
if (mro_meth != type_mro_meth)
`
``
312
`+
goto clear;
`
``
313
`+
Py_XDECREF(mro_meth);
`
``
314
`+
Py_XDECREF(type_mro_meth);
`
``
315
`+
}
`
295
316
`n = PyTuple_GET_SIZE(bases);
`
296
317
`for (i = 0; i < n; i++) {
`
297
318
`PyObject *b = PyTuple_GET_ITEM(bases, i);
`
`@@ -302,14 +323,15 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) {
`
302
323
``
303
324
`if (!PyType_HasFeature(cls, Py_TPFLAGS_HAVE_VERSION_TAG) ||
`
304
325
` !PyType_IsSubtype(type, cls)) {
`
305
``
`-
clear = 1;
`
306
``
`-
break;
`
``
326
`+
goto clear;
`
307
327
` }
`
308
328
` }
`
309
``
-
310
``
`-
if (clear)
`
311
``
`-
type->tp_flags &= ~(Py_TPFLAGS_HAVE_VERSION_TAG|
`
312
``
`-
Py_TPFLAGS_VALID_VERSION_TAG);
`
``
329
`+
return;
`
``
330
`+
clear:
`
``
331
`+
Py_XDECREF(mro_meth);
`
``
332
`+
Py_XDECREF(type_mro_meth);
`
``
333
`+
type->tp_flags &= ~(Py_TPFLAGS_HAVE_VERSION_TAG|
`
``
334
`+
Py_TPFLAGS_VALID_VERSION_TAG);
`
313
335
`}
`
314
336
``
315
337
`static int
`