@@ -5226,6 +5226,57 @@ get_module_by_def(PyTypeObject *type, PyModuleDef *def)
52265226 return res ;
52275227}
52285228
5229+ // copied from the above
5230+ Py_NO_INLINE static PyObject *
5231+ get_module_by_def_NoInline (PyTypeObject * type , PyModuleDef * def )
5232+ {
5233+ assert (PyType_Check (type ));
5234+
5235+ if (!_PyType_HasFeature (type , Py_TPFLAGS_HEAPTYPE )) {
5236+ // type_ready_mro() ensures that no heap type is
5237+ // contained in a static type MRO.
5238+ return NULL ;
5239+ }
5240+ else {
5241+ PyHeapTypeObject * ht = (PyHeapTypeObject * )type ;
5242+ PyObject * module = ht -> ht_module ;
5243+ if (module && _PyModule_GetDef (module ) == def ) {
5244+ return module ;
5245+ }
5246+ }
5247+
5248+ PyObject * res = NULL ;
5249+ BEGIN_TYPE_LOCK ();
5250+
5251+ PyObject * mro = lookup_tp_mro (type );
5252+ // The type must be ready
5253+ assert (mro != NULL );
5254+ assert (PyTuple_Check (mro ));
5255+ // mro_invoke() ensures that the type MRO cannot be empty.
5256+ assert (PyTuple_GET_SIZE (mro ) >= 1 );
5257+ // Also, the first item in the MRO is the type itself, which
5258+ // we already checked above. We skip it in the loop.
5259+ assert (PyTuple_GET_ITEM (mro , 0 ) == (PyObject * )type );
5260+
5261+ Py_ssize_t n = PyTuple_GET_SIZE (mro );
5262+ for (Py_ssize_t i = 1 ; i < n ; i ++ ) {
5263+ PyObject * super = PyTuple_GET_ITEM (mro , i );
5264+ if (!_PyType_HasFeature ((PyTypeObject * )super , Py_TPFLAGS_HEAPTYPE )) {
5265+ // Static types in the MRO need to be skipped
5266+ continue ;
5267+ }
5268+
5269+ PyHeapTypeObject * ht = (PyHeapTypeObject * )super ;
5270+ PyObject * module = ht -> ht_module ;
5271+ if (module && _PyModule_GetDef (module ) == def ) {
5272+ res = module ;
5273+ break ;
5274+ }
5275+ }
5276+ END_TYPE_LOCK ();
5277+ return res ;
5278+ }
5279+
52295280PyObject *
52305281PyType_GetModuleByDef (PyTypeObject * type , PyModuleDef * def )
52315282{
0 commit comments