@@ -4825,24 +4825,39 @@ PyType_GetModuleState(PyTypeObject *type)
48254825/* Get the module of the first superclass where the module has the
48264826 * given PyModuleDef.
48274827 */
4828- PyObject *
4829- PyType_GetModuleByDef (PyTypeObject * type , PyModuleDef * def )
4828+ static inline PyObject *
4829+ get_module_by_def (PyTypeObject * type , PyModuleDef * def )
48304830{
48314831 assert (PyType_Check (type ));
48324832
4833+ if (!_PyType_HasFeature (type , Py_TPFLAGS_HEAPTYPE )) {
4834+ // type_ready_mro() ensures that no heap type is
4835+ // contained in a static type MRO.
4836+ return NULL ;
4837+ }
4838+ else {
4839+ PyHeapTypeObject * ht = (PyHeapTypeObject * )type ;
4840+ PyObject * module = ht -> ht_module ;
4841+ if (module && _PyModule_GetDef (module ) == def ) {
4842+ return module ;
4843+ }
4844+ }
4845+
48334846 PyObject * res = NULL ;
48344847 BEGIN_TYPE_LOCK ()
48354848
48364849 PyObject * mro = lookup_tp_mro (type );
48374850 // The type must be ready
48384851 assert (mro != NULL );
48394852 assert (PyTuple_Check (mro ));
4840- // mro_invoke() ensures that the type MRO cannot be empty, so we don't have
4841- // to check i < PyTuple_GET_SIZE(mro) at the first loop iteration.
4853+ // mro_invoke() ensures that the type MRO cannot be empty.
48424854 assert (PyTuple_GET_SIZE (mro ) >= 1 );
4855+ // Also, the first item in the MRO is the type itself, which
4856+ // we already checked above. We skip it in the loop.
4857+ assert (PyTuple_GET_ITEM (mro , 0 ) == (PyObject * )type );
48434858
48444859 Py_ssize_t n = PyTuple_GET_SIZE (mro );
4845- for (Py_ssize_t i = 0 ; i < n ; i ++ ) {
4860+ for (Py_ssize_t i = 1 ; i < n ; i ++ ) {
48464861 PyObject * super = PyTuple_GET_ITEM (mro , i );
48474862 if (!_PyType_HasFeature ((PyTypeObject * )super , Py_TPFLAGS_HEAPTYPE )) {
48484863 // Static types in the MRO need to be skipped
@@ -4857,14 +4872,37 @@ PyType_GetModuleByDef(PyTypeObject *type, PyModuleDef *def)
48574872 }
48584873 }
48594874 END_TYPE_LOCK ()
4875+ return res ;
4876+ }
48604877
4861- if (res == NULL ) {
4878+ PyObject *
4879+ PyType_GetModuleByDef (PyTypeObject * type , PyModuleDef * def )
4880+ {
4881+ PyObject * module = get_module_by_def (type , def );
4882+ if (module == NULL ) {
48624883 PyErr_Format (
48634884 PyExc_TypeError ,
48644885 "PyType_GetModuleByDef: No superclass of '%s' has the given module" ,
48654886 type -> tp_name );
48664887 }
4867- return res ;
4888+ return module ;
4889+ }
4890+
4891+ PyObject *
4892+ _PyType_GetModuleByDef2 (PyTypeObject * left , PyTypeObject * right ,
4893+ PyModuleDef * def )
4894+ {
4895+ PyObject * module = get_module_by_def (left , def );
4896+ if (module == NULL ) {
4897+ module = get_module_by_def (right , def );
4898+ if (module == NULL ) {
4899+ PyErr_Format (
4900+ PyExc_TypeError ,
4901+ "PyType_GetModuleByDef: No superclass of '%s' nor '%s' has "
4902+ "the given module" , left -> tp_name , right -> tp_name );
4903+ }
4904+ }
4905+ return module ;
48684906}
48694907
48704908void *
0 commit comments