@@ -4825,24 +4825,39 @@ PyType_GetModuleState(PyTypeObject *type)
4825
4825
/* Get the module of the first superclass where the module has the
4826
4826
* given PyModuleDef.
4827
4827
*/
4828
- PyObject *
4829
- PyType_GetModuleByDef (PyTypeObject * type , PyModuleDef * def )
4828
+ static inline PyObject *
4829
+ get_module_by_def (PyTypeObject * type , PyModuleDef * def )
4830
4830
{
4831
4831
assert (PyType_Check (type ));
4832
4832
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
+
4833
4846
PyObject * res = NULL ;
4834
4847
BEGIN_TYPE_LOCK ()
4835
4848
4836
4849
PyObject * mro = lookup_tp_mro (type );
4837
4850
// The type must be ready
4838
4851
assert (mro != NULL );
4839
4852
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.
4842
4854
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 );
4843
4858
4844
4859
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 ++ ) {
4846
4861
PyObject * super = PyTuple_GET_ITEM (mro , i );
4847
4862
if (!_PyType_HasFeature ((PyTypeObject * )super , Py_TPFLAGS_HEAPTYPE )) {
4848
4863
// Static types in the MRO need to be skipped
@@ -4857,14 +4872,37 @@ PyType_GetModuleByDef(PyTypeObject *type, PyModuleDef *def)
4857
4872
}
4858
4873
}
4859
4874
END_TYPE_LOCK ()
4875
+ return res ;
4876
+ }
4860
4877
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 ) {
4862
4883
PyErr_Format (
4863
4884
PyExc_TypeError ,
4864
4885
"PyType_GetModuleByDef: No superclass of '%s' has the given module" ,
4865
4886
type -> tp_name );
4866
4887
}
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 ;
4868
4906
}
4869
4907
4870
4908
void *
0 commit comments