@@ -632,44 +632,45 @@ _PyImport_ClearModulesByIndex(PyInterpreterState *interp)
632
632
633
633
(6). first time (not found in _PyRuntime.imports.extensions):
634
634
A. _imp_create_dynamic_impl() -> import_find_extension()
635
- B. _imp_create_dynamic_impl() -> _PyImport_LoadDynamicModuleWithSpec()
636
- C. _PyImport_LoadDynamicModuleWithSpec(): load <module init func>
637
- D. _PyImport_LoadDynamicModuleWithSpec(): call <module init func>
638
- E. <module init func> -> PyModule_Create() -> PyModule_Create2()
635
+ B. _imp_create_dynamic_impl() -> _PyImport_GetModInitFunc()
636
+ C. _PyImport_GetModInitFunc(): load <module init func>
637
+ D. _imp_create_dynamic_impl() -> _PyImport_RunModInitFunc()
638
+ E. _PyImport_RunModInitFunc(): call <module init func>
639
+ F. <module init func> -> PyModule_Create() -> PyModule_Create2()
639
640
-> PyModule_CreateInitialized()
640
- F. PyModule_CreateInitialized() -> PyModule_New()
641
- G. PyModule_CreateInitialized(): allocate mod->md_state
642
- H. PyModule_CreateInitialized() -> PyModule_AddFunctions()
643
- I. PyModule_CreateInitialized() -> PyModule_SetDocString()
644
- J. PyModule_CreateInitialized(): set mod->md_def
645
- K. <module init func>: initialize the module, etc.
646
- L. _PyImport_LoadDynamicModuleWithSpec()
647
- -> _PyImport_CheckSubinterpIncompatibleExtensionAllowed()
648
- M. _PyImport_LoadDynamicModuleWithSpec(): set def->m_base.m_init
649
- N. _PyImport_LoadDynamicModuleWithSpec() -> _PyImport_FixupExtensionObject()
650
- O. _PyImport_FixupExtensionObject() -> update_global_state_for_extension()
651
- P. update_global_state_for_extension():
652
- copy __dict__ into def->m_base.m_copy
653
- Q. update_global_state_for_extension():
654
- add it to _PyRuntime.imports.extensions
655
- R. _PyImport_FixupExtensionObject() -> finish_singlephase_extension()
656
- S. finish_singlephase_extension():
657
- add it to interp->imports.modules_by_index
658
- T. finish_singlephase_extension(): add it to sys.modules
659
- U. _imp_create_dynamic_impl(): set __file__
660
-
661
- Step (P) is skipped for core modules (sys/builtins).
641
+ G. PyModule_CreateInitialized() -> PyModule_New()
642
+ H. PyModule_CreateInitialized(): allocate mod->md_state
643
+ I. PyModule_CreateInitialized() -> PyModule_AddFunctions()
644
+ J. PyModule_CreateInitialized() -> PyModule_SetDocString()
645
+ K. PyModule_CreateInitialized(): set mod->md_def
646
+ L. <module init func>: initialize the module, etc.
647
+ M. _PyImport_RunModInitFunc(): set def->m_base.m_init
648
+ N. _imp_create_dynamic_impl()
649
+ -> _PyImport_CheckSubinterpIncompatibleExtensionAllowed()
650
+ O. _imp_create_dynamic_impl(): set __file__
651
+ P. _imp_create_dynamic_impl() -> update_global_state_for_extension()
652
+ Q. update_global_state_for_extension():
653
+ copy __dict__ into def->m_base.m_copy
654
+ R. update_global_state_for_extension():
655
+ add it to _PyRuntime.imports.extensions
656
+ S. _imp_create_dynamic_impl() -> finish_singlephase_extension()
657
+ T. finish_singlephase_extension():
658
+ add it to interp->imports.modules_by_index
659
+ U. finish_singlephase_extension(): add it to sys.modules
660
+
661
+ Step (Q) is skipped for core modules (sys/builtins).
662
662
663
663
(6). subsequent times (found in _PyRuntime.imports.extensions):
664
664
A. _imp_create_dynamic_impl() -> import_find_extension()
665
- B. import_find_extension() -> import_add_module()
666
- C. if name in sys.modules: use that module
667
- D. else:
665
+ B. import_find_extension()
666
+ -> _PyImport_CheckSubinterpIncompatibleExtensionAllowed()
667
+ C. import_find_extension() -> import_add_module()
668
+ D. if name in sys.modules: use that module
669
+ E. else:
668
670
1. import_add_module() -> PyModule_NewObject()
669
671
2. import_add_module(): set it on sys.modules
670
- E. import_find_extension(): copy the "m_copy" dict into __dict__
671
- F. _imp_create_dynamic_impl()
672
- -> _PyImport_CheckSubinterpIncompatibleExtensionAllowed()
672
+ F. import_find_extension(): copy the "m_copy" dict into __dict__
673
+ G. import_find_extension(): add to modules_by_index
673
674
674
675
(10). (every time):
675
676
A. noop
@@ -678,19 +679,22 @@ _PyImport_ClearModulesByIndex(PyInterpreterState *interp)
678
679
...for single-phase init modules, where m_size >= 0:
679
680
680
681
(6). not main interpreter and never loaded there - every time (not found in _PyRuntime.imports.extensions):
681
- A-N . (same as for m_size == -1)
682
- O-Q . (skipped)
683
- R -U. (same as for m_size == -1)
682
+ A-O . (same as for m_size == -1)
683
+ P-R . (skipped)
684
+ S -U. (same as for m_size == -1)
684
685
685
686
(6). main interpreter - first time (not found in _PyRuntime.imports.extensions):
686
- A-O . (same as for m_size == -1)
687
- P . (skipped)
688
- Q -U. (same as for m_size == -1)
687
+ A-Q . (same as for m_size == -1)
688
+ R . (skipped)
689
+ S -U. (same as for m_size == -1)
689
690
690
- (6). previously loaded in main interpreter (found in _PyRuntime.imports.extensions):
691
+ (6). subsequent times (found in _PyRuntime.imports.extensions):
691
692
A. _imp_create_dynamic_impl() -> import_find_extension()
692
- B. import_find_extension(): call def->m_base.m_init
693
- C. import_find_extension(): add the module to sys.modules
693
+ B. import_find_extension()
694
+ -> _PyImport_CheckSubinterpIncompatibleExtensionAllowed()
695
+ C. import_find_extension(): call def->m_base.m_init (see above)
696
+ D. import_find_extension(): add the module to sys.modules
697
+ E. import_find_extension(): add to modules_by_index
694
698
695
699
(10). every time:
696
700
A. noop
@@ -1270,7 +1274,7 @@ finish_singlephase_extension(PyThreadState *tstate,
1270
1274
PyObject * name , PyObject * modules )
1271
1275
{
1272
1276
assert (mod != NULL && PyModule_Check (mod ));
1273
- assert (def == PyModule_GetDef (mod ));
1277
+ assert (def == _PyModule_GetDef (mod ));
1274
1278
1275
1279
if (_modules_by_index_set (tstate -> interp , def , mod ) < 0 ) {
1276
1280
return -1 ;
@@ -1285,47 +1289,6 @@ finish_singlephase_extension(PyThreadState *tstate,
1285
1289
return 0 ;
1286
1290
}
1287
1291
1288
- int
1289
- _PyImport_FixupExtensionObject (PyObject * mod , PyObject * name ,
1290
- PyObject * filename , PyObject * modules )
1291
- {
1292
- PyThreadState * tstate = _PyThreadState_GET ();
1293
-
1294
- if (mod == NULL || !PyModule_Check (mod )) {
1295
- PyErr_BadInternalCall ();
1296
- return -1 ;
1297
- }
1298
- PyModuleDef * def = PyModule_GetDef (mod );
1299
- if (def == NULL ) {
1300
- PyErr_BadInternalCall ();
1301
- return -1 ;
1302
- }
1303
-
1304
- /* Only single-phase init extension modules can reach here. */
1305
- assert (is_singlephase (def ));
1306
- assert (!is_core_module (tstate -> interp , name , filename ));
1307
- assert (!is_core_module (tstate -> interp , name , name ));
1308
-
1309
- struct singlephase_global_update singlephase = {0 };
1310
- // gh-88216: Extensions and def->m_base.m_copy can be updated
1311
- // when the extension module doesn't support sub-interpreters.
1312
- if (def -> m_size == -1 ) {
1313
- singlephase .m_dict = PyModule_GetDict (mod );
1314
- assert (singlephase .m_dict != NULL );
1315
- }
1316
- if (update_global_state_for_extension (
1317
- tstate , filename , name , def , & singlephase ) < 0 )
1318
- {
1319
- return -1 ;
1320
- }
1321
-
1322
- if (finish_singlephase_extension (tstate , mod , def , name , modules ) < 0 ) {
1323
- return -1 ;
1324
- }
1325
-
1326
- return 0 ;
1327
- }
1328
-
1329
1292
1330
1293
static PyObject *
1331
1294
import_find_extension (PyThreadState * tstate ,
@@ -1514,7 +1477,12 @@ create_builtin(PyThreadState *tstate, PyObject *name, PyObject *spec)
1514
1477
}
1515
1478
1516
1479
PyObject * mod = import_find_extension (tstate , & info );
1517
- if (mod || _PyErr_Occurred (tstate )) {
1480
+ if (mod != NULL ) {
1481
+ assert (!_PyErr_Occurred (tstate ));
1482
+ assert (is_singlephase (_PyModule_GetDef (mod )));
1483
+ goto finally ;
1484
+ }
1485
+ else if (_PyErr_Occurred (tstate )) {
1518
1486
goto finally ;
1519
1487
}
1520
1488
@@ -3900,31 +3868,35 @@ _imp_create_dynamic_impl(PyObject *module, PyObject *spec, PyObject *file)
3900
3868
/*[clinic end generated code: output=83249b827a4fde77 input=c31b954f4cf4e09d]*/
3901
3869
{
3902
3870
PyObject * mod = NULL ;
3903
- FILE * fp ;
3871
+ PyModuleDef * def = NULL ;
3872
+ PyThreadState * tstate = _PyThreadState_GET ();
3904
3873
3905
3874
struct _Py_ext_module_loader_info info ;
3906
3875
if (_Py_ext_module_loader_info_init_from_spec (& info , spec ) < 0 ) {
3907
3876
return NULL ;
3908
3877
}
3909
3878
3910
- PyThreadState * tstate = _PyThreadState_GET ();
3911
3879
mod = import_find_extension (tstate , & info );
3912
- if (mod != NULL || _PyErr_Occurred (tstate )) {
3913
- assert (mod == NULL || !_PyErr_Occurred (tstate ));
3880
+ if (mod != NULL ) {
3881
+ assert (!_PyErr_Occurred (tstate ));
3882
+ assert (is_singlephase (_PyModule_GetDef (mod )));
3914
3883
goto finally ;
3915
3884
}
3885
+ else if (_PyErr_Occurred (tstate )) {
3886
+ goto finally ;
3887
+ }
3888
+ /* Otherwise it must be multi-phase init or the first time it's loaded. */
3916
3889
3917
3890
if (PySys_Audit ("import" , "OOOOO" , info .name , info .filename ,
3918
3891
Py_None , Py_None , Py_None ) < 0 )
3919
3892
{
3920
3893
goto finally ;
3921
3894
}
3922
3895
3923
- /* Is multi-phase init or this is the first time being loaded. */
3924
-
3925
3896
/* We would move this (and the fclose() below) into
3926
3897
* _PyImport_GetModInitFunc(), but it isn't clear if the intervening
3927
3898
* code relies on fp still being open. */
3899
+ FILE * fp ;
3928
3900
if (file != NULL ) {
3929
3901
fp = _Py_fopen_obj (info .filename , "r" );
3930
3902
if (fp == NULL ) {
@@ -3935,7 +3907,70 @@ _imp_create_dynamic_impl(PyObject *module, PyObject *spec, PyObject *file)
3935
3907
fp = NULL ;
3936
3908
}
3937
3909
3938
- mod = _PyImport_LoadDynamicModuleWithSpec (& info , spec , fp );
3910
+ PyModInitFunction p0 = _PyImport_GetModInitFunc (& info , fp );
3911
+ if (p0 == NULL ) {
3912
+ goto finally ;
3913
+ }
3914
+
3915
+ struct _Py_ext_module_loader_result res ;
3916
+ if (_PyImport_RunModInitFunc (p0 , & info , & res ) < 0 ) {
3917
+ assert (PyErr_Occurred ());
3918
+ goto finally ;
3919
+ }
3920
+
3921
+ mod = res .module ;
3922
+ res .module = NULL ;
3923
+ def = res .def ;
3924
+ assert (def != NULL );
3925
+
3926
+ if (mod == NULL ) {
3927
+ //assert(!is_singlephase(def));
3928
+ mod = PyModule_FromDefAndSpec (def , spec );
3929
+ if (mod == NULL ) {
3930
+ goto finally ;
3931
+ }
3932
+ }
3933
+ else {
3934
+ assert (is_singlephase (def ));
3935
+ assert (!is_core_module (tstate -> interp , info .name , info .filename ));
3936
+ assert (!is_core_module (tstate -> interp , info .name , info .name ));
3937
+
3938
+ const char * name_buf = PyBytes_AS_STRING (info .name_encoded );
3939
+ if (_PyImport_CheckSubinterpIncompatibleExtensionAllowed (name_buf ) < 0 ) {
3940
+ Py_CLEAR (mod );
3941
+ goto finally ;
3942
+ }
3943
+
3944
+ /* Remember pointer to module init function. */
3945
+ res .def -> m_base .m_init = p0 ;
3946
+
3947
+ /* Remember the filename as the __file__ attribute */
3948
+ if (PyModule_AddObjectRef (mod , "__file__" , info .filename ) < 0 ) {
3949
+ PyErr_Clear (); /* Not important enough to report */
3950
+ }
3951
+
3952
+ struct singlephase_global_update singlephase = {0 };
3953
+ // gh-88216: Extensions and def->m_base.m_copy can be updated
3954
+ // when the extension module doesn't support sub-interpreters.
3955
+ if (def -> m_size == -1 ) {
3956
+ singlephase .m_dict = PyModule_GetDict (mod );
3957
+ assert (singlephase .m_dict != NULL );
3958
+ }
3959
+ if (update_global_state_for_extension (
3960
+ tstate , info .filename , info .name , def , & singlephase ) < 0 )
3961
+ {
3962
+ Py_CLEAR (mod );
3963
+ goto finally ;
3964
+ }
3965
+
3966
+ PyObject * modules = get_modules_dict (tstate , true);
3967
+ if (finish_singlephase_extension (
3968
+ tstate , mod , def , info .name , modules ) < 0 )
3969
+ {
3970
+ Py_CLEAR (mod );
3971
+ goto finally ;
3972
+ }
3973
+ }
3939
3974
3940
3975
// XXX Shouldn't this happen in the error cases too.
3941
3976
if (fp ) {
0 commit comments