@@ -1946,89 +1946,13 @@ Py_GetArgcArgv()
19461946
19471947 See also :c:member: `PyConfig.orig_argv ` member.
19481948
1949+ Delaying main module execution
1950+ ==============================
19491951
1950- Multi-Phase Initialization Private Provisional API
1951- ==================================================
1952+ In some embedding use cases, it may be desirable to separate interpreter initialization
1953+ from the execution of the main module.
19521954
1953- This section is a private provisional API introducing multi-phase
1954- initialization, the core feature of :pep: `432 `:
1955-
1956- * "Core" initialization phase, "bare minimum Python":
1957-
1958- * Builtin types;
1959- * Builtin exceptions;
1960- * Builtin and frozen modules;
1961- * The :mod: `sys ` module is only partially initialized
1962- (ex: :data: `sys.path ` doesn't exist yet).
1963-
1964- * "Main" initialization phase, Python is fully initialized:
1965-
1966- * Install and configure :mod:`importlib`;
1967- * Apply the :ref: `Path Configuration <init-path-config >`;
1968- * Install signal handlers;
1969- * Finish :mod: `sys ` module initialization (ex: create :data: `sys.stdout `
1970- and :data: `sys.path `);
1971- * Enable optional features like :mod: `faulthandler ` and :mod: `tracemalloc `;
1972- * Import the :mod: `site ` module;
1973- * etc.
1974-
1975- Private provisional API:
1976-
1977- * :c:member: `PyConfig._init_main `: if set to ``0 ``,
1978- :c:func: `Py_InitializeFromConfig ` stops at the "Core" initialization phase.
1979-
1980- .. c :function :: PyStatus _Py_InitializeMain (void)
1981-
1982- Move to the "Main" initialization phase, finish the Python initialization.
1983-
1984- No module is imported during the "Core" phase and the ``importlib`` module is
1985- not configured: the :ref:`Path Configuration <init-path-config>` is only
1986- applied during the "Main" phase. It may allow to customize Python in Python to
1987- override or tune the :ref:`Path Configuration <init-path-config>`, maybe
1988- install a custom :data:`sys.meta_path` importer or an import hook, etc.
1989-
1990- It may become possible to calculate the :ref:`Path Configuration
1991- <init-path-config>` in Python, after the Core phase and before the Main phase,
1992- which is one of the :pep:`432` motivation.
1993-
1994- The "Core" phase is not properly defined: what should be and what should
1995- not be available at this phase is not specified yet. The API is marked
1996- as private and provisional: the API can be modified or even be removed
1997- anytime until a proper public API is designed.
1998-
1999- Example running Python code between "Core" and "Main" initialization
2000- phases::
2001-
2002- void init_python(void)
2003- {
2004- PyStatus status;
2005-
2006- PyConfig config;
2007- PyConfig_InitPythonConfig (&config);
2008- config._init_main = 0;
2009-
2010- /* ... customize 'config' configuration ... */
2011-
2012- status = Py_InitializeFromConfig (&config);
2013- PyConfig_Clear (&config);
2014- if (PyStatus_Exception (status)) {
2015- Py_ExitStatusException (status);
2016- }
2017-
2018- /* Use sys.stderr because sys.stdout is only created
2019- by _Py_InitializeMain () */
2020- int res = PyRun_SimpleString(
2021- "import sys; "
2022- "print('Run Python code before _Py_InitializeMain', "
2023- "file=sys.stderr)");
2024- if (res < 0) {
2025- exit(1);
2026- }
2027-
2028- /* ... put more configuration code here ... */
2029-
2030- status = _Py_InitializeMain ();
2031- if (PyStatus_Exception (status)) {
2032- Py_ExitStatusException (status);
2033- }
2034- }
1955+ This separation can be achieved by setting ``PyConfig.run_command `` to the empty
1956+ string during initialization (to prevent the interpreter from dropping into the
1957+ interactive prompt), and then subsequently executing the desired main module
1958+ code using ``__main__.__dict__`` as the global namespace.
0 commit comments