bpo-32030: Add _PyMainInterpreterConfig.executable by vstinner · Pull Request #4876 · python/cpython · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Include/pylifecycle.h
15 changes: 9 additions & 6 deletions Include/pystate.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,18 @@ typedef struct {
/* Placeholders while working on the new configuration API
*
* See PEP 432 for final anticipated contents
*
* For the moment, just handle the args to _Py_InitializeEx
*/
typedef struct {
int install_signal_handlers;
PyObject *argv; /* sys.argv list, can be NULL */
PyObject *module_search_path; /* sys.path list */
PyObject *warnoptions; /* sys.warnoptions list, can be NULL */
PyObject *xoptions; /* sys._xoptions dict, can be NULL */
PyObject *argv; /* sys.argv list, can be NULL */
PyObject *executable; /* sys.executable str */
PyObject *prefix; /* sys.prefix str */
PyObject *base_prefix; /* sys.base_prefix str, can be NULL */
PyObject *exec_prefix; /* sys.exec_prefix str */
PyObject *base_exec_prefix; /* sys.base_exec_prefix str, can be NULL */
PyObject *warnoptions; /* sys.warnoptions list, can be NULL */
PyObject *xoptions; /* sys._xoptions dict, can be NULL */
PyObject *module_search_path; /* sys.path list */
} _PyMainInterpreterConfig;

#define _PyMainInterpreterConfig_INIT \
Expand Down
69 changes: 50 additions & 19 deletions Modules/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2005,9 +2005,14 @@ void
_PyMainInterpreterConfig_Clear(_PyMainInterpreterConfig *config)
{
Py_CLEAR(config->argv);
Py_CLEAR(config->module_search_path);
Py_CLEAR(config->executable);
Py_CLEAR(config->prefix);
Py_CLEAR(config->base_prefix);
Py_CLEAR(config->exec_prefix);
Py_CLEAR(config->base_exec_prefix);
Py_CLEAR(config->warnoptions);
Py_CLEAR(config->xoptions);
Py_CLEAR(config->module_search_path);
}


Expand Down Expand Up @@ -2052,9 +2057,14 @@ _PyMainInterpreterConfig_Copy(_PyMainInterpreterConfig *config,
} while (0)

COPY_ATTR(argv);
COPY_ATTR(module_search_path);
COPY_ATTR(executable);
COPY_ATTR(prefix);
COPY_ATTR(base_prefix);
COPY_ATTR(exec_prefix);
COPY_ATTR(base_exec_prefix);
COPY_ATTR(warnoptions);
COPY_ATTR(xoptions);
COPY_ATTR(module_search_path);
#undef COPY_ATTR
return 0;
}
Expand Down Expand Up @@ -2099,39 +2109,60 @@ config_create_path_list(const wchar_t *path, wchar_t delim)
}


static _PyInitError
config_init_module_search_path(_PyMainInterpreterConfig *config, _PyCoreConfig *core_config)
_PyInitError
_PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *config, _PyCoreConfig *core_config)
{
_PyInitError err = _PyPathConfig_Init(core_config);
if (_Py_INIT_FAILED(err)) {
return err;
}
wchar_t *sys_path = Py_GetPath();

config->module_search_path = config_create_path_list(sys_path, DELIM);
if (config->module_search_path == NULL) {
return _Py_INIT_NO_MEMORY();
}
return _Py_INIT_OK();
}


_PyInitError
_PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *config, _PyCoreConfig *core_config)
{
/* Signal handlers are installed by default */
if (config->install_signal_handlers < 0) {
config->install_signal_handlers = 1;
}

if (config->module_search_path == NULL &&
!core_config->_disable_importlib)

{
_PyInitError err = config_init_module_search_path(config, core_config);
if (_Py_INIT_FAILED(err)) {
return err;
wchar_t *sys_path = Py_GetPath();
config->module_search_path = config_create_path_list(sys_path, DELIM);
if (config->module_search_path == NULL) {
return _Py_INIT_NO_MEMORY();
}
}

if (config->executable == NULL) {
config->executable = PyUnicode_FromWideChar(Py_GetProgramFullPath(), -1);
if (config->executable == NULL) {
return _Py_INIT_NO_MEMORY();
}
}

if (config->prefix == NULL) {
config->prefix = PyUnicode_FromWideChar(Py_GetPrefix(), -1);
if (config->prefix == NULL) {
return _Py_INIT_NO_MEMORY();
}
}

if (config->exec_prefix == NULL) {
config->exec_prefix = PyUnicode_FromWideChar(Py_GetExecPrefix(), -1);
if (config->exec_prefix == NULL) {
return _Py_INIT_NO_MEMORY();
}
}

if (config->base_prefix == NULL) {
Py_INCREF(config->prefix);
config->base_prefix = config->prefix;
}

if (config->base_exec_prefix == NULL) {
Py_INCREF(config->exec_prefix);
config->base_exec_prefix = config->exec_prefix;
}
return _Py_INIT_OK();
}

Expand Down
32 changes: 2 additions & 30 deletions Python/pylifecycle.c
Original file line number Diff line number Diff line change
Expand Up @@ -830,28 +830,7 @@ _Py_InitializeMainInterpreter(const _PyMainInterpreterConfig *config)
return _Py_INIT_ERR("can't initialize time");
}

/* Set sys attributes */
assert(interp->config.module_search_path != NULL);
if (PySys_SetObject("path", interp->config.module_search_path) != 0) {
return _Py_INIT_ERR("can't assign sys.path");
}
if (interp->config.argv != NULL) {
if (PySys_SetObject("argv", interp->config.argv) != 0) {
return _Py_INIT_ERR("can't assign sys.argv");
}
}
if (interp->config.warnoptions != NULL) {
if (PySys_SetObject("warnoptions", interp->config.warnoptions)) {
return _Py_INIT_ERR("can't assign sys.warnoptions");
}
}
if (interp->config.xoptions != NULL) {
if (PySys_SetObject("_xoptions", interp->config.xoptions)) {
return _Py_INIT_ERR("can't assign sys._xoptions");
}
}

if (_PySys_EndInit(interp->sysdict) < 0) {
if (_PySys_EndInit(interp->sysdict, &interp->config) < 0) {
return _Py_INIT_ERR("can't finish initializing sys");
}

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

err = _PyPathConfig_Init(&interp->core_config);
if (_Py_INIT_FAILED(err)) {
return err;
}
wchar_t *sys_path = Py_GetPath();

/* XXX The following is lax in error checking */
PyObject *modules = PyDict_New();
if (modules == NULL) {
Expand All @@ -1334,8 +1307,7 @@ new_interpreter(PyThreadState **tstate_p)
goto handle_error;
Py_INCREF(interp->sysdict);
PyDict_SetItemString(interp->sysdict, "modules", modules);
PySys_SetPath(sys_path);
_PySys_EndInit(interp->sysdict);
_PySys_EndInit(interp->sysdict, &interp->config);
}

bimod = _PyImport_FindBuiltin("builtins", modules);
Expand Down
43 changes: 30 additions & 13 deletions Python/sysmodule.c