Skip to content

Commit beea5e3

Browse files
committed
Check __mro__ instead of __bases__
1 parent 1fcda68 commit beea5e3

File tree

1 file changed

+19
-5
lines changed

1 file changed

+19
-5
lines changed

Objects/typeobject.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4643,9 +4643,14 @@ check_basicsize_includes_size_and_offsets(PyTypeObject* type)
46434643
}
46444644

46454645
static int
4646-
check_immutable_bases(const char *type_name, PyObject *bases)
4646+
check_immutable_bases(const char *type_name, PyObject *bases, int skip_first)
46474647
{
4648-
for (Py_ssize_t i=0; i<PyTuple_GET_SIZE(bases); i++) {
4648+
Py_ssize_t i = 0;
4649+
if (skip_first) {
4650+
// When testing the MRO, skip the type itself
4651+
i = 1;
4652+
}
4653+
for (; i<PyTuple_GET_SIZE(bases); i++) {
46494654
PyTypeObject *b = (PyTypeObject*)PyTuple_GET_ITEM(bases, i);
46504655
if (!b) {
46514656
return -1;
@@ -4818,7 +4823,7 @@ _PyType_FromMetaclass_impl(
48184823
* and only heap types can be mutable.)
48194824
*/
48204825
if (spec->flags & Py_TPFLAGS_IMMUTABLETYPE) {
4821-
if (check_immutable_bases(spec->name, bases) < 0) {
4826+
if (check_immutable_bases(spec->name, bases, 0) < 0) {
48224827
goto finally;
48234828
}
48244829
}
@@ -11190,8 +11195,17 @@ add_operators(PyTypeObject *type, PyTypeObject *def)
1119011195
int
1119111196
PyType_Freeze(PyTypeObject *type)
1119211197
{
11193-
PyObject *bases = type->tp_bases;
11194-
if (check_immutable_bases(type->tp_name, bases) < 0) {
11198+
// gh-121654: Check the __mro__ instead of __bases__
11199+
PyObject *mro = type_get_mro(type, NULL);
11200+
if (!PyTuple_Check(mro)) {
11201+
Py_DECREF(mro);
11202+
PyErr_SetString(PyExc_TypeError, "unable to get the type MRO");
11203+
return -1;
11204+
}
11205+
11206+
int check = check_immutable_bases(type->tp_name, mro, 1);
11207+
Py_DECREF(mro);
11208+
if (check < 0) {
1119511209
return -1;
1119611210
}
1119711211

0 commit comments

Comments
 (0)