bpo-32030: Add _PyMainInterpreterConfig.executable (#4876) · pythoncapi/cpython@41264f1 · GitHub
Skip to content

Commit 41264f1

Browse files
authored
bpo-32030: Add _PyMainInterpreterConfig.executable (python#4876)
* Add new fields to _PyMainInterpreterConfig: * executable * prefix * base_prefix * exec_prefix * base_exec_prefix * _PySys_EndInit() now sets sys attributes from _PyMainInterpreterConfig
1 parent da27341 commit 41264f1

5 files changed

Lines changed: 92 additions & 69 deletions

File tree

Include/pylifecycle.h

Lines changed: 1 addition & 1 deletion

Include/pystate.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,18 @@ typedef struct {
5252
/* Placeholders while working on the new configuration API
5353
*
5454
* See PEP 432 for final anticipated contents
55-
*
56-
* For the moment, just handle the args to _Py_InitializeEx
5755
*/
5856
typedef struct {
5957
int install_signal_handlers;
60-
PyObject *argv; /* sys.argv list, can be NULL */
61-
PyObject *module_search_path; /* sys.path list */
62-
PyObject *warnoptions; /* sys.warnoptions list, can be NULL */
63-
PyObject *xoptions; /* sys._xoptions dict, can be NULL */
58+
PyObject *argv; /* sys.argv list, can be NULL */
59+
PyObject *executable; /* sys.executable str */
60+
PyObject *prefix; /* sys.prefix str */
61+
PyObject *base_prefix; /* sys.base_prefix str, can be NULL */
62+
PyObject *exec_prefix; /* sys.exec_prefix str */
63+
PyObject *base_exec_prefix; /* sys.base_exec_prefix str, can be NULL */
64+
PyObject *warnoptions; /* sys.warnoptions list, can be NULL */
65+
PyObject *xoptions; /* sys._xoptions dict, can be NULL */
66+
PyObject *module_search_path; /* sys.path list */
6467
} _PyMainInterpreterConfig;
6568

6669
#define _PyMainInterpreterConfig_INIT \

Modules/main.c

Lines changed: 50 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2005,9 +2005,14 @@ void
20052005
_PyMainInterpreterConfig_Clear(_PyMainInterpreterConfig *config)
20062006
{
20072007
Py_CLEAR(config->argv);
2008-
Py_CLEAR(config->module_search_path);
2008+
Py_CLEAR(config->executable);
2009+
Py_CLEAR(config->prefix);
2010+
Py_CLEAR(config->base_prefix);
2011+
Py_CLEAR(config->exec_prefix);
2012+
Py_CLEAR(config->base_exec_prefix);
20092013
Py_CLEAR(config->warnoptions);
20102014
Py_CLEAR(config->xoptions);
2015+
Py_CLEAR(config->module_search_path);
20112016
}
20122017

20132018

@@ -2052,9 +2057,14 @@ _PyMainInterpreterConfig_Copy(_PyMainInterpreterConfig *config,
20522057
} while (0)
20532058

20542059
COPY_ATTR(argv);
2055-
COPY_ATTR(module_search_path);
2060+
COPY_ATTR(executable);
2061+
COPY_ATTR(prefix);
2062+
COPY_ATTR(base_prefix);
2063+
COPY_ATTR(exec_prefix);
2064+
COPY_ATTR(base_exec_prefix);
20562065
COPY_ATTR(warnoptions);
20572066
COPY_ATTR(xoptions);
2067+
COPY_ATTR(module_search_path);
20582068
#undef COPY_ATTR
20592069
return 0;
20602070
}
@@ -2099,39 +2109,60 @@ config_create_path_list(const wchar_t *path, wchar_t delim)
20992109
}
21002110

21012111

2102-
static _PyInitError
2103-
config_init_module_search_path(_PyMainInterpreterConfig *config, _PyCoreConfig *core_config)
2112+
_PyInitError
2113+
_PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *config, _PyCoreConfig *core_config)
21042114
{
21052115
_PyInitError err = _PyPathConfig_Init(core_config);
21062116
if (_Py_INIT_FAILED(err)) {
21072117
return err;
21082118
}
2109-
wchar_t *sys_path = Py_GetPath();
21102119

2111-
config->module_search_path = config_create_path_list(sys_path, DELIM);
2112-
if (config->module_search_path == NULL) {
2113-
return _Py_INIT_NO_MEMORY();
2114-
}
2115-
return _Py_INIT_OK();
2116-
}
2117-
2118-
2119-
_PyInitError
2120-
_PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *config, _PyCoreConfig *core_config)
2121-
{
21222120
/* Signal handlers are installed by default */
21232121
if (config->install_signal_handlers < 0) {
21242122
config->install_signal_handlers = 1;
21252123
}
21262124

21272125
if (config->module_search_path == NULL &&
21282126
!core_config->_disable_importlib)
2127+
21292128
{
2130-
_PyInitError err = config_init_module_search_path(config, core_config);
2131-
if (_Py_INIT_FAILED(err)) {
2132-
return err;
2129+
wchar_t *sys_path = Py_GetPath();
2130+
config->module_search_path = config_create_path_list(sys_path, DELIM);
2131+
if (config->module_search_path == NULL) {
2132+
return _Py_INIT_NO_MEMORY();
21332133
}
21342134
}
2135+
2136+
if (config->executable == NULL) {
2137+
config->executable = PyUnicode_FromWideChar(Py_GetProgramFullPath(), -1);
2138+
if (config->executable == NULL) {
2139+
return _Py_INIT_NO_MEMORY();
2140+
}
2141+
}
2142+
2143+
if (config->prefix == NULL) {
2144+
config->prefix = PyUnicode_FromWideChar(Py_GetPrefix(), -1);
2145+
if (config->prefix == NULL) {
2146+
return _Py_INIT_NO_MEMORY();
2147+
}
2148+
}
2149+
2150+
if (config->exec_prefix == NULL) {
2151+
config->exec_prefix = PyUnicode_FromWideChar(Py_GetExecPrefix(), -1);
2152+
if (config->exec_prefix == NULL) {
2153+
return _Py_INIT_NO_MEMORY();
2154+
}
2155+
}
2156+
2157+
if (config->base_prefix == NULL) {
2158+
Py_INCREF(config->prefix);
2159+
config->base_prefix = config->prefix;
2160+
}
2161+
2162+
if (config->base_exec_prefix == NULL) {
2163+
Py_INCREF(config->exec_prefix);
2164+
config->base_exec_prefix = config->exec_prefix;
2165+
}
21352166
return _Py_INIT_OK();
21362167
}
21372168

Python/pylifecycle.c

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -830,28 +830,7 @@ _Py_InitializeMainInterpreter(const _PyMainInterpreterConfig *config)
830830
return _Py_INIT_ERR("can't initialize time");
831831
}
832832

833-
/* Set sys attributes */
834-
assert(interp->config.module_search_path != NULL);
835-
if (PySys_SetObject("path", interp->config.module_search_path) != 0) {
836-
return _Py_INIT_ERR("can't assign sys.path");
837-
}
838-
if (interp->config.argv != NULL) {
839-
if (PySys_SetObject("argv", interp->config.argv) != 0) {
840-
return _Py_INIT_ERR("can't assign sys.argv");
841-
}
842-
}
843-
if (interp->config.warnoptions != NULL) {
844-
if (PySys_SetObject("warnoptions", interp->config.warnoptions)) {
845-
return _Py_INIT_ERR("can't assign sys.warnoptions");
846-
}
847-
}
848-
if (interp->config.xoptions != NULL) {
849-
if (PySys_SetObject("_xoptions", interp->config.xoptions)) {
850-
return _Py_INIT_ERR("can't assign sys._xoptions");
851-
}
852-
}
853-
854-
if (_PySys_EndInit(interp->sysdict) < 0) {
833+
if (_PySys_EndInit(interp->sysdict, &interp->config) < 0) {
855834
return _Py_INIT_ERR("can't finish initializing sys");
856835
}
857836

@@ -1314,12 +1293,6 @@ new_interpreter(PyThreadState **tstate_p)
13141293
return _Py_INIT_ERR("failed to copy main interpreter config");
13151294
}
13161295

1317-
err = _PyPathConfig_Init(&interp->core_config);
1318-
if (_Py_INIT_FAILED(err)) {
1319-
return err;
1320-
}
1321-
wchar_t *sys_path = Py_GetPath();
1322-
13231296
/* XXX The following is lax in error checking */
13241297
PyObject *modules = PyDict_New();
13251298
if (modules == NULL) {
@@ -1334,8 +1307,7 @@ new_interpreter(PyThreadState **tstate_p)
13341307
goto handle_error;
13351308
Py_INCREF(interp->sysdict);
13361309
PyDict_SetItemString(interp->sysdict, "modules", modules);
1337-
PySys_SetPath(sys_path);
1338-
_PySys_EndInit(interp->sysdict);
1310+
_PySys_EndInit(interp->sysdict, &interp->config);
13391311
}
13401312

13411313
bimod = _PyImport_FindBuiltin("builtins", modules);

Python/sysmodule.c

Lines changed: 30 additions & 13 deletions

0 commit comments

Comments
 (0)