| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1946,89 +1946,13 @@ Py_GetArgcArgv() | |||
| 1946 | 1946 | ||
| 1947 | 1947 | See also :c:member:`PyConfig.orig_argv` member. | |
| 1948 | 1948 | ||
| 1949 | + Delaying main module execution | ||
| 1950 | + ============================== | ||
| 1949 | 1951 | ||
| 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. | ||
| 1952 | 1954 | ||
| 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. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1375,3 +1375,7 @@ Removed | |||
| 1375 | 1375 | ||
| 1376 | 1376 | * Creating :c:data:`immutable types <Py_TPFLAGS_IMMUTABLETYPE>` with mutable | |
| 1377 | 1377 | bases was deprecated since 3.12 and now raises a :exc:`TypeError`. | |
| 1378 | + | ||
| 1379 | + * Remove the private ``_Py_InitializeMain()`` function. It was a | ||
| 1380 | + :term:`provisional API` added to Python 3.8 by :pep:`587`. | ||
| 1381 | + (Contributed by Victor Stinner in :gh:`129033`.) | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -25,9 +25,6 @@ PyAPI_FUNC(PyStatus) Py_PreInitializeFromArgs( | |||
| 25 | 25 | PyAPI_FUNC(PyStatus) Py_InitializeFromConfig( | |
| 26 | 26 | const PyConfig *config); | |
| 27 | 27 | ||
| 28 | - // Python 3.8 provisional API (PEP 587) | ||
| 29 | - PyAPI_FUNC(PyStatus) _Py_InitializeMain(void); | ||
| 30 | - | ||
| 31 | 28 | PyAPI_FUNC(int) Py_RunMain(void); | |
| 32 | 29 | ||
| 33 | 30 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1274,24 +1274,6 @@ def test_init_run_main(self): | |||
| 1274 | 1274 | } | |
| 1275 | 1275 | self.check_all_configs("test_init_run_main", config, api=API_PYTHON) | |
| 1276 | 1276 | ||
| 1277 | - def test_init_main(self): | ||
| 1278 | - code = ('import _testinternalcapi, json; ' | ||
| 1279 | - 'print(json.dumps(_testinternalcapi.get_configs()))') | ||
| 1280 | - config = { | ||
| 1281 | - 'argv': ['-c', 'arg2'], | ||
| 1282 | - 'orig_argv': ['python3', | ||
| 1283 | - '-c', code, | ||
| 1284 | - 'arg2'], | ||
| 1285 | - 'program_name': './python3', | ||
| 1286 | - 'run_command': code + '\n', | ||
| 1287 | - 'parse_argv': True, | ||
| 1288 | - '_init_main': False, | ||
| 1289 | - 'sys_path_0': '', | ||
| 1290 | - } | ||
| 1291 | - self.check_all_configs("test_init_main", config, | ||
| 1292 | - api=API_PYTHON, | ||
| 1293 | - stderr="Run Python code before _Py_InitializeMain") | ||
| 1294 | - | ||
| 1295 | 1277 | def test_init_parse_argv(self): | |
| 1296 | 1278 | config = { | |
| 1297 | 1279 | 'parse_argv': True, | |
@@ -1768,7 +1750,6 @@ def test_init_warnoptions(self): | |||
| 1768 | 1750 | ||
| 1769 | 1751 | def test_init_set_config(self): | |
| 1770 | 1752 | config = { | |
| 1771 | - '_init_main': 0, | ||
| 1772 | 1753 | 'bytes_warning': 2, | |
| 1773 | 1754 | 'warnoptions': ['error::BytesWarning'], | |
| 1774 | 1755 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,3 @@ | |||
| 1 | + Remove the private ``_Py_InitializeMain()`` function. It was a | ||
| 2 | + :term:`provisional API` added to Python 3.8 by :pep:`587`. Patch by Victor | ||
| 3 | + Stinner. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1818,7 +1818,6 @@ static int test_init_set_config(void) | |||
| 1818 | 1818 | PyConfig config; | |
| 1819 | 1819 | PyConfig_InitIsolatedConfig(&config); | |
| 1820 | 1820 | config_set_string(&config, &config.program_name, PROGRAM_NAME); | |
| 1821 | - config._init_main = 0; | ||
| 1822 | 1821 | config.bytes_warning = 0; | |
| 1823 | 1822 | init_from_config_clear(&config); | |
| 1824 | 1823 | ||
@@ -1828,12 +1827,6 @@ static int test_init_set_config(void) | |||
| 1828 | 1827 | return 1; | |
| 1829 | 1828 | } | |
| 1830 | 1829 | ||
| 1831 | - // Finish initialization: main part | ||
| 1832 | - PyStatus status = _Py_InitializeMain(); | ||
| 1833 | - if (PyStatus_Exception(status)) { | ||
| 1834 | - Py_ExitStatusException(status); | ||
| 1835 | - } | ||
| 1836 | - | ||
| 1837 | 1830 | dump_config(); | |
| 1838 | 1831 | Py_Finalize(); | |
| 1839 | 1832 | return 0; | |
@@ -2089,33 +2082,6 @@ static int test_init_run_main(void) | |||
| 2089 | 2082 | } | |
| 2090 | 2083 | ||
| 2091 | 2084 | ||
| 2092 | - static int test_init_main(void) | ||
| 2093 | - { | ||
| 2094 | - PyConfig config; | ||
| 2095 | - PyConfig_InitPythonConfig(&config); | ||
| 2096 | - | ||
| 2097 | - configure_init_main(&config); | ||
| 2098 | - config._init_main = 0; | ||
| 2099 | - init_from_config_clear(&config); | ||
| 2100 | - | ||
| 2101 | - /* sys.stdout don't exist yet: it is created by _Py_InitializeMain() */ | ||
| 2102 | - int res = PyRun_SimpleString( | ||
| 2103 | - "import sys; " | ||
| 2104 | - "print('Run Python code before _Py_InitializeMain', " | ||
| 2105 | - "file=sys.stderr)"); | ||
| 2106 | - if (res < 0) { | ||
| 2107 | - exit(1); | ||
| 2108 | - } | ||
| 2109 | - | ||
| 2110 | - PyStatus status = _Py_InitializeMain(); | ||
| 2111 | - if (PyStatus_Exception(status)) { | ||
| 2112 | - Py_ExitStatusException(status); | ||
| 2113 | - } | ||
| 2114 | - | ||
| 2115 | - return Py_RunMain(); | ||
| 2116 | - } | ||
| 2117 | - | ||
| 2118 | - | ||
| 2119 | 2085 | static int test_run_main(void) | |
| 2120 | 2086 | { | |
| 2121 | 2087 | PyConfig config; | |
@@ -2473,7 +2439,6 @@ static struct TestCase TestCases[] = { | |||
| 2473 | 2439 | {"test_preinit_dont_parse_argv", test_preinit_dont_parse_argv}, | |
| 2474 | 2440 | {"test_init_read_set", test_init_read_set}, | |
| 2475 | 2441 | {"test_init_run_main", test_init_run_main}, | |
| 2476 | - {"test_init_main", test_init_main}, | ||
| 2477 | 2442 | {"test_init_sys_add", test_init_sys_add}, | |
| 2478 | 2443 | {"test_init_setpath", test_init_setpath}, | |
| 2479 | 2444 | {"test_init_setpath_config", test_init_setpath_config}, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1505,18 +1505,6 @@ Py_Initialize(void) | |||
| 1505 | 1505 | } | |
| 1506 | 1506 | ||
| 1507 | 1507 | ||
| 1508 | - PyStatus | ||
| 1509 | - _Py_InitializeMain(void) | ||
| 1510 | - { | ||
| 1511 | - PyStatus status = _PyRuntime_Initialize(); | ||
| 1512 | - if (_PyStatus_EXCEPTION(status)) { | ||
| 1513 | - return status; | ||
| 1514 | - } | ||
| 1515 | - PyThreadState *tstate = _PyThreadState_GET(); | ||
| 1516 | - return pyinit_main(tstate); | ||
| 1517 | - } | ||
| 1518 | - | ||
| 1519 | - | ||
| 1520 | 1508 | static void | |
| 1521 | 1509 | finalize_modules_delete_special(PyThreadState *tstate, int verbose) | |
| 1522 | 1510 | { | |
| Back | FazBrowse Home | New Git URL |
0 commit comments