@@ -5226,6 +5226,57 @@ get_module_by_def(PyTypeObject *type, PyModuleDef *def)
5226
5226
return res ;
5227
5227
}
5228
5228
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
+
5229
5280
PyObject *
5230
5281
PyType_GetModuleByDef (PyTypeObject * type , PyModuleDef * def )
5231
5282
{
0 commit comments