| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -23,7 +23,8 @@ PyAPI_FUNC(int) Py_SetStandardStreamEncoding(const char *encoding, | |||
| 23 | 23 | /* PEP 432 Multi-phase initialization API (Private while provisional!) */ | |
| 24 | 24 | PyAPI_FUNC(void) _Py_InitializeCore(const _PyCoreConfig *); | |
| 25 | 25 | PyAPI_FUNC(int) _Py_IsCoreInitialized(void); | |
| 26 | - PyAPI_FUNC(int) _Py_InitializeMainInterpreter(int install_sigs); | ||
| 26 | + PyAPI_FUNC(int) _Py_ReadMainInterpreterConfig(_PyMainInterpreterConfig *); | ||
| 27 | + PyAPI_FUNC(int) _Py_InitializeMainInterpreter(const _PyMainInterpreterConfig *); | ||
| 27 | 28 | #endif | |
| 28 | 29 | ||
| 29 | 30 | /* Initialization and finalization */ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -33,6 +33,18 @@ typedef struct { | |||
| 33 | 33 | ||
| 34 | 34 | #define _PyCoreConfig_INIT {0, -1, 0, 0} | |
| 35 | 35 | ||
| 36 | + /* Placeholders while working on the new configuration API | ||
| 37 | + * | ||
| 38 | + * See PEP 432 for final anticipated contents | ||
| 39 | + * | ||
| 40 | + * For the moment, just handle the args to _Py_InitializeEx | ||
| 41 | + */ | ||
| 42 | + typedef struct { | ||
| 43 | + int install_signal_handlers; | ||
| 44 | + } _PyMainInterpreterConfig; | ||
| 45 | + | ||
| 46 | + #define _PyMainInterpreterConfig_INIT {-1} | ||
| 47 | + | ||
| 36 | 48 | typedef struct _is { | |
| 37 | 49 | ||
| 38 | 50 | struct _is *next; | |
@@ -53,6 +65,7 @@ typedef struct _is { | |||
| 53 | 65 | int fscodec_initialized; | |
| 54 | 66 | ||
| 55 | 67 | _PyCoreConfig core_config; | |
| 68 | + _PyMainInterpreterConfig config; | ||
| 56 | 69 | #ifdef HAVE_DLOPEN | |
| 57 | 70 | int dlopenflags; | |
| 58 | 71 | #endif | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -768,8 +768,21 @@ Py_Main(int argc, wchar_t **argv) | |||
| 768 | 768 | #else | |
| 769 | 769 | Py_SetProgramName(argv[0]); | |
| 770 | 770 | #endif | |
| 771 | - if (_Py_InitializeMainInterpreter(1)) | ||
| 772 | - Py_FatalError("Py_Main: Py_InitializeMainInterpreter failed"); | ||
| 771 | + /* Replaces previous call to Py_Initialize() | ||
| 772 | + * | ||
| 773 | + * TODO: Move environment queries (etc) into Py_ReadConfig | ||
| 774 | + */ | ||
| 775 | + { | ||
| 776 | + _PyMainInterpreterConfig config = _PyMainInterpreterConfig_INIT; | ||
| 777 | + | ||
| 778 | + /* TODO: Moar config options! */ | ||
| 779 | + config.install_signal_handlers = 1; | ||
| 780 | + /* TODO: Print any exceptions raised by these operations */ | ||
| 781 | + if (_Py_ReadMainInterpreterConfig(&config)) | ||
| 782 | + Py_FatalError("Py_Main: Py_ReadMainInterpreterConfig failed"); | ||
| 783 | + if (_Py_InitializeMainInterpreter(&config)) | ||
| 784 | + Py_FatalError("Py_Main: Py_InitializeMainInterpreter failed"); | ||
| 785 | + } | ||
| 773 | 786 | ||
| 774 | 787 | /* TODO: Move this to _PyRun_PrepareMain */ | |
| 775 | 788 | if (!Py_QuietFlag && (Py_VerboseFlag || | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -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 */ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,5 +1,12 @@ | |||
| 1 | 1 | ||
| 2 | - /* Python interpreter top-level routines, including init/exit */ | ||
| 2 | + /* Top level execution of Python code (including in __main__) */ | ||
| 3 | + | ||
| 4 | + /* To help control the interfaces between the startup, execution and | ||
| 5 | + * shutdown code, the phases are split across separate modules (boostrap, | ||
| 6 | + * pythonrun, shutdown) | ||
| 7 | + */ | ||
| 8 | + | ||
| 9 | + /* TODO: Cull includes following phase split */ | ||
| 3 | 10 | ||
| 4 | 11 | #include "Python.h" | |
| 5 | 12 | ||
@@ -59,7 +66,6 @@ static void err_input(perrdetail *); | |||
| 59 | 66 | static void err_free(perrdetail *); | |
| 60 | 67 | ||
| 61 | 68 | /* Parse input from a file and execute it */ | |
| 62 | - | ||
| 63 | 69 | int | |
| 64 | 70 | PyRun_AnyFileExFlags(FILE *fp, const char *filename, int closeit, | |
| 65 | 71 | PyCompilerFlags *flags) | |
| Back | FazBrowse Home | New Git URL |
0 commit comments