@@ -4643,9 +4643,14 @@ check_basicsize_includes_size_and_offsets(PyTypeObject* type)
4643
4643
}
4644
4644
4645
4645
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 )
4647
4647
{
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 ++ ) {
4649
4654
PyTypeObject * b = (PyTypeObject * )PyTuple_GET_ITEM (bases , i );
4650
4655
if (!b ) {
4651
4656
return -1 ;
@@ -4818,7 +4823,7 @@ _PyType_FromMetaclass_impl(
4818
4823
* and only heap types can be mutable.)
4819
4824
*/
4820
4825
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 ) {
4822
4827
goto finally ;
4823
4828
}
4824
4829
}
@@ -11190,8 +11195,17 @@ add_operators(PyTypeObject *type, PyTypeObject *def)
11190
11195
int
11191
11196
PyType_Freeze (PyTypeObject * type )
11192
11197
{
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 ) {
11195
11209
return -1 ;
11196
11210
}
11197
11211
0 commit comments