@@ -69,6 +69,7 @@ extern void _PyFaulthandler_Fini(void);
69
69
extern void _PyHash_Fini (void );
70
70
extern int _PyTraceMalloc_Init (void );
71
71
extern int _PyTraceMalloc_Fini (void );
72
+ extern void _Py_ReadyTypes (void );
72
73
73
74
#ifdef WITH_THREAD
74
75
extern void _PyGILState_Init (PyInterpreterState * , PyThreadState * );
@@ -112,6 +113,7 @@ PyModule_GetWarningsModule(void)
112
113
return PyImport_ImportModule ("warnings" );
113
114
}
114
115
116
+
115
117
/* APIs to access the initialization flags
116
118
*
117
119
* Can be called prior to Py_Initialize.
@@ -366,8 +368,8 @@ void _Py_InitializeCore(const _PyCoreConfig *config)
366
368
PyThreadState * tstate ;
367
369
PyObject * bimod , * sysmod , * pstderr ;
368
370
char * p ;
369
- extern void _Py_ReadyTypes (void );
370
371
_PyCoreConfig core_config = _PyCoreConfig_INIT ;
372
+ _PyMainInterpreterConfig preinit_config = _PyMainInterpreterConfig_INIT ;
371
373
372
374
if (config != NULL ) {
373
375
core_config = * config ;
@@ -428,6 +430,7 @@ void _Py_InitializeCore(const _PyCoreConfig *config)
428
430
if (interp == NULL )
429
431
Py_FatalError ("Py_InitializeCore: can't make main interpreter" );
430
432
interp -> core_config = core_config ;
433
+ interp -> config = preinit_config ;
431
434
432
435
tstate = PyThreadState_New (interp );
433
436
if (tstate == NULL )
@@ -518,21 +521,62 @@ void _Py_InitializeCore(const _PyCoreConfig *config)
518
521
_Py_CoreInitialized = 1 ;
519
522
}
520
523
521
- int
522
- _Py_InitializeMainInterpreter (int install_sigs )
524
+ /* Read configuration settings from standard locations
525
+ *
526
+ * This function doesn't make any changes to the interpreter state - it
527
+ * merely populates any missing configuration settings. This allows an
528
+ * embedding application to completely override a config option by
529
+ * setting it before calling this function, or else modify the default
530
+ * setting before passing the fully populated config to Py_EndInitialization.
531
+ *
532
+ * More advanced selective initialization tricks are possible by calling
533
+ * this function multiple times with various preconfigured settings.
534
+ */
535
+
536
+ int _Py_ReadMainInterpreterConfig (_PyMainInterpreterConfig * config )
537
+ {
538
+ /* Signal handlers are installed by default */
539
+ if (config -> install_signal_handlers < 0 ) {
540
+ config -> install_signal_handlers = 1 ;
541
+ }
542
+
543
+ return 0 ;
544
+ }
545
+
546
+ /* Update interpreter state based on supplied configuration settings
547
+ *
548
+ * After calling this function, most of the restrictions on the interpreter
549
+ * are lifted. The only remaining incomplete settings are those related
550
+ * to the main module (sys.argv[0], __main__ metadata)
551
+ *
552
+ * Calling this when the interpreter is not initializing, is already
553
+ * initialized or without a valid current thread state is a fatal error.
554
+ * Other errors should be reported as normal Python exceptions with a
555
+ * non-zero return code.
556
+ */
557
+ int _Py_InitializeMainInterpreter (const _PyMainInterpreterConfig * config )
523
558
{
524
559
PyInterpreterState * interp ;
525
560
PyThreadState * tstate ;
526
561
562
+ if (!_Py_CoreInitialized ) {
563
+ Py_FatalError ("Py_InitializeMainInterpreter: runtime core not initialized" );
564
+ }
565
+ if (_Py_Initialized ) {
566
+ Py_FatalError ("Py_InitializeMainInterpreter: main interpreter already initialized" );
567
+ }
568
+
527
569
/* Get current thread state and interpreter pointer */
528
570
tstate = PyThreadState_GET ();
529
571
if (!tstate )
530
- Py_FatalError ("Py_Initialize : failed to read thread state" );
572
+ Py_FatalError ("Py_InitializeMainInterpreter : failed to read thread state" );
531
573
interp = tstate -> interp ;
532
574
if (!interp )
533
- Py_FatalError ("Py_Initialize : failed to get interpreter" );
575
+ Py_FatalError ("Py_InitializeMainInterpreter : failed to get interpreter" );
534
576
535
577
/* Now finish configuring the main interpreter */
578
+ interp -> config = * config ;
579
+
536
580
if (interp -> core_config ._disable_importlib ) {
537
581
/* Special mode for freeze_importlib: run with no import system
538
582
*
@@ -545,7 +589,7 @@ _Py_InitializeMainInterpreter(int install_sigs)
545
589
/* TODO: Report exceptions rather than fatal errors below here */
546
590
547
591
if (_PyTime_Init () < 0 )
548
- Py_FatalError ("Py_Initialize : can't initialize time" );
592
+ Py_FatalError ("Py_InitializeMainInterpreter : can't initialize time" );
549
593
550
594
/* Finish setting up the sys module and import system */
551
595
/* GetPath may initialize state that _PySys_EndInit locks
@@ -559,21 +603,21 @@ _Py_InitializeMainInterpreter(int install_sigs)
559
603
560
604
/* initialize the faulthandler module */
561
605
if (_PyFaulthandler_Init ())
562
- Py_FatalError ("Py_Initialize : can't initialize faulthandler" );
606
+ Py_FatalError ("Py_InitializeMainInterpreter : can't initialize faulthandler" );
563
607
564
608
if (initfsencoding (interp ) < 0 )
565
- Py_FatalError ("Py_Initialize : unable to load the file system codec" );
609
+ Py_FatalError ("Py_InitializeMainInterpreter : unable to load the file system codec" );
566
610
567
- if (install_sigs )
611
+ if (config -> install_signal_handlers )
568
612
initsigs (); /* Signal handling stuff, including initintr() */
569
613
570
614
if (_PyTraceMalloc_Init () < 0 )
571
- Py_FatalError ("Py_Initialize : can't initialize tracemalloc" );
615
+ Py_FatalError ("Py_InitializeMainInterpreter : can't initialize tracemalloc" );
572
616
573
617
initmain (interp ); /* Module __main__ */
574
618
if (initstdio () < 0 )
575
619
Py_FatalError (
576
- "Py_Initialize : can't initialize sys standard streams" );
620
+ "Py_InitializeMainInterpreter : can't initialize sys standard streams" );
577
621
578
622
/* Initialize warnings. */
579
623
if (PySys_HasWarnOptions ()) {
@@ -590,19 +634,27 @@ _Py_InitializeMainInterpreter(int install_sigs)
590
634
if (!Py_NoSiteFlag )
591
635
initsite (); /* Module site */
592
636
593
- return 0 ;
637
+ return 0 ;
594
638
}
595
639
640
+ #undef _INIT_DEBUG_PRINT
641
+
596
642
void
597
643
_Py_InitializeEx_Private (int install_sigs , int install_importlib )
598
644
{
599
645
_PyCoreConfig core_config = _PyCoreConfig_INIT ;
646
+ _PyMainInterpreterConfig config = _PyMainInterpreterConfig_INIT ;
600
647
601
648
/* TODO: Moar config options! */
602
649
core_config .ignore_environment = Py_IgnoreEnvironmentFlag ;
603
650
core_config ._disable_importlib = !install_importlib ;
651
+ config .install_signal_handlers = install_sigs ;
604
652
_Py_InitializeCore (& core_config );
605
- _Py_InitializeMainInterpreter (install_sigs );
653
+ /* TODO: Print any exceptions raised by these operations */
654
+ if (_Py_ReadMainInterpreterConfig (& config ))
655
+ Py_FatalError ("Py_Initialize: Py_ReadMainInterpreterConfig failed" );
656
+ if (_Py_InitializeMainInterpreter (& config ))
657
+ Py_FatalError ("Py_Initialize: Py_InitializeMainInterpreter failed" );
606
658
}
607
659
608
660
@@ -932,10 +984,12 @@ Py_NewInterpreter(void)
932
984
/* Copy the current interpreter config into the new interpreter */
933
985
if (save_tstate != NULL ) {
934
986
interp -> core_config = save_tstate -> interp -> core_config ;
987
+ interp -> config = save_tstate -> interp -> config ;
935
988
} else {
936
989
/* No current thread state, copy from the main interpreter */
937
990
PyInterpreterState * main_interp = PyInterpreterState_Main ();
938
991
interp -> core_config = main_interp -> core_config ;
992
+ interp -> config = main_interp -> config ;
939
993
}
940
994
941
995
/* XXX The following is lax in error checking */
0 commit comments