[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