[Python-checkins] bpo-32030: Add _PyMainInterpreterConfig.executable (#4876)
Victor Stinner
webhook-mailer at python.org
Thu Dec 14 20:05:33 EST 2017
https://github.com/python/cpython/commit/41264f1cd4d6066b2797ff07cae465c1e06ff3b2
commit: 41264f1cd4d6066b2797ff07cae465c1e06ff3b2
branch: master
author: Victor Stinner <victor.stinner at gmail.com>
committer: GitHub <noreply at github.com>
date: 2017-12-15T02:05:29+01:00
summary:
bpo-32030: Add _PyMainInterpreterConfig.executable (#4876)
* Add new fields to _PyMainInterpreterConfig:
* executable
* prefix
* base_prefix
* exec_prefix
* base_exec_prefix
* _PySys_EndInit() now sets sys attributes from
_PyMainInterpreterConfig
files:
M Include/pylifecycle.h
M Include/pystate.h
M Modules/main.c
M Python/pylifecycle.c
M Python/sysmodule.c
diff --git a/Include/pylifecycle.h b/Include/pylifecycle.h
index 39339da45af..dcb7fcb8495 100644
--- a/Include/pylifecycle.h
+++ b/Include/pylifecycle.h
@@ -135,7 +135,7 @@ PyAPI_FUNC(const char *) _Py_gitversion(void);
#ifndef Py_LIMITED_API
PyAPI_FUNC(PyObject *) _PyBuiltin_Init(void);
PyAPI_FUNC(_PyInitError) _PySys_BeginInit(PyObject **sysmod);
-PyAPI_FUNC(int) _PySys_EndInit(PyObject *sysdict);
+PyAPI_FUNC(int) _PySys_EndInit(PyObject *sysdict, _PyMainInterpreterConfig *config);
PyAPI_FUNC(_PyInitError) _PyImport_Init(PyInterpreterState *interp);
PyAPI_FUNC(void) _PyExc_Init(PyObject * bltinmod);
PyAPI_FUNC(_PyInitError) _PyImportHooks_Init(void);
diff --git a/Include/pystate.h b/Include/pystate.h
index e8cf4134a8c..a56c9b4ea6c 100644
--- a/Include/pystate.h
+++ b/Include/pystate.h
@@ -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 \
diff --git a/Modules/main.c b/Modules/main.c
index 8c4219c7ec3..339a0f5e681 100644
--- a/Modules/main.c
+++ b/Modules/main.c
@@ -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);
}
@@ -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;
}
@@ -2099,26 +2109,14 @@ 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;
@@ -2126,12 +2124,45 @@ _PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *config, _PyCoreConfig *c
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();
}
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 830f89d0d41..8c626075d5d 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -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");
}
@@ -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) {
@@ -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);
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index b33a316331a..24098b9daf8 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -2212,7 +2212,6 @@ _PySys_BeginInit(PyObject **sysmod)
}
#undef SET_SYS_FROM_STRING
-#undef SET_SYS_FROM_STRING_BORROW
/* Updating the sys namespace, returning integer error codes */
#define SET_SYS_FROM_STRING_INT_RESULT(key, value) \
@@ -2228,10 +2227,35 @@ _PySys_BeginInit(PyObject **sysmod)
} while (0)
int
-_PySys_EndInit(PyObject *sysdict)
+_PySys_EndInit(PyObject *sysdict, _PyMainInterpreterConfig *config)
{
int res;
+ /* _PyMainInterpreterConfig_Read() must set all these variables */
+ assert(config->module_search_path != NULL);
+ assert(config->executable != NULL);
+ assert(config->prefix != NULL);
+ assert(config->base_prefix != NULL);
+ assert(config->exec_prefix != NULL);
+ assert(config->base_exec_prefix != NULL);
+
+ SET_SYS_FROM_STRING_BORROW("path", config->module_search_path);
+ SET_SYS_FROM_STRING_BORROW("executable", config->executable);
+ SET_SYS_FROM_STRING_BORROW("prefix", config->prefix);
+ SET_SYS_FROM_STRING_BORROW("base_prefix", config->base_prefix);
+ SET_SYS_FROM_STRING_BORROW("exec_prefix", config->exec_prefix);
+ SET_SYS_FROM_STRING_BORROW("base_exec_prefix", config->base_exec_prefix);
+
+ if (config->argv != NULL) {
+ SET_SYS_FROM_STRING_BORROW("argv", config->argv);
+ }
+ if (config->warnoptions != NULL) {
+ SET_SYS_FROM_STRING_BORROW("warnoptions", config->warnoptions);
+ }
+ if (config->xoptions != NULL) {
+ SET_SYS_FROM_STRING_BORROW("_xoptions", config->xoptions);
+ }
+
/* Set flags to their final values */
SET_SYS_FROM_STRING_INT_RESULT("flags", make_flags());
/* prevent user from creating new instances */
@@ -2247,17 +2271,6 @@ _PySys_EndInit(PyObject *sysdict)
SET_SYS_FROM_STRING_INT_RESULT("dont_write_bytecode",
PyBool_FromLong(Py_DontWriteBytecodeFlag));
- SET_SYS_FROM_STRING_INT_RESULT("executable",
- PyUnicode_FromWideChar(
- Py_GetProgramFullPath(), -1));
- SET_SYS_FROM_STRING_INT_RESULT("prefix",
- PyUnicode_FromWideChar(Py_GetPrefix(), -1));
- SET_SYS_FROM_STRING_INT_RESULT("exec_prefix",
- PyUnicode_FromWideChar(Py_GetExecPrefix(), -1));
- SET_SYS_FROM_STRING_INT_RESULT("base_prefix",
- PyUnicode_FromWideChar(Py_GetPrefix(), -1));
- SET_SYS_FROM_STRING_INT_RESULT("base_exec_prefix",
- PyUnicode_FromWideChar(Py_GetExecPrefix(), -1));
if (get_warnoptions() == NULL)
return -1;
@@ -2268,8 +2281,12 @@ _PySys_EndInit(PyObject *sysdict)
if (PyErr_Occurred())
return -1;
return 0;
+
+err_occurred:
+ return -1;
}
+#undef SET_SYS_FROM_STRING_BORROW
#undef SET_SYS_FROM_STRING_INT_RESULT
static PyObject *
More information about the Python-checkins
mailing list