]> granicus.if.org Git - python/commitdiff
bpo-34170: _PyCoreConfig_Read() leaves Py_IsolatedFlag unchanged (GH-8361)
authorVictor Stinner <vstinner@redhat.com>
Sat, 21 Jul 2018 01:54:20 +0000 (03:54 +0200)
committerGitHub <noreply@github.com>
Sat, 21 Jul 2018 01:54:20 +0000 (03:54 +0200)
* _PyCoreConfig_Read() no longer directly modifies Py_IsolatedFlag
  and Py_NoSiteFlag global configuration flags. The function now
  requires two pointers to integer, so these flags can be set later,
  to avoid side effets in _PyCoreConfig_Read().
* pathconfig_global_init() now leaves Py_IsolatedFlag and
  Py_NoSiteFlag unchanged.
* Fix pathconfig_global_init(): avoid computing the path
  configuration twice, use _PyCoreConfig_SetPathConfig().

Include/internal/pystate.h
Include/pylifecycle.h
Modules/main.c
PC/getpathp.c
Python/pathconfig.c
Python/pylifecycle.c

index 83fa7dc33cf618488bee007dac217e314d7eea02..6cee272a89e8f7e97911713379a097e51819b461 100644 (file)
@@ -52,9 +52,17 @@ typedef struct _PyPathConfig {
     wchar_t *program_name;
     /* Set by Py_SetPythonHome() or PYTHONHOME environment variable */
     wchar_t *home;
+    /* isolated and no_site_import are used to set Py_IsolatedFlag and
+       Py_NoSiteFlag flags on Windows in read_pth_file(). These fields
+       are ignored when their value are equal to -1 (unset). */
+    int isolated;
+    int no_site_import;
 } _PyPathConfig;
 
-#define _PyPathConfig_INIT {.module_search_path = NULL}
+#define _PyPathConfig_INIT \
+    {.module_search_path = NULL, \
+     .isolated = -1, \
+     .no_site_import = -1}
 /* Note: _PyPathConfig_INIT sets other fields to 0/NULL */
 
 PyAPI_DATA(_PyPathConfig) _Py_path_config;
index 9644116ba62c746bd8035f4959f027e3041f8fe3..2fbc4f979318660ec57fb28c06d097c89d6801f4 100644 (file)
@@ -54,12 +54,18 @@ PyAPI_FUNC(int) Py_SetStandardStreamEncoding(const char *encoding,
 PyAPI_FUNC(_PyInitError) _Py_InitializeCore(const _PyCoreConfig *);
 PyAPI_FUNC(int) _Py_IsCoreInitialized(void);
 
-PyAPI_FUNC(_PyInitError) _PyCoreConfig_Read(_PyCoreConfig *);
+PyAPI_FUNC(_PyInitError) _PyCoreConfig_Read(
+    _PyCoreConfig *config,
+    int *isolated,
+    int *no_site_import);
 PyAPI_FUNC(void) _PyCoreConfig_Clear(_PyCoreConfig *);
 PyAPI_FUNC(int) _PyCoreConfig_Copy(
     _PyCoreConfig *config,
     const _PyCoreConfig *config2);
-PyAPI_FUNC(_PyInitError) _PyCoreConfig_InitPathConfig(_PyCoreConfig *config);
+PyAPI_FUNC(_PyInitError) _PyCoreConfig_InitPathConfig(
+    _PyCoreConfig *config,
+    int *isolated,
+    int *no_site_import);
 PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetPathConfig(
     const _PyCoreConfig *config);
 
index 5166e7429208e482a045648c07b0ad3a6ff3b8a1..2b6818561df04b673d64fe035d27bcc94b3e5fd8 100644 (file)
@@ -1953,19 +1953,9 @@ pymain_read_conf_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
         return -1;
     }
 
-    /* On Windows, _PyPathConfig_Init() modifies Py_IsolatedFlag and
-       Py_NoSiteFlag variables if a "._pth" file is found. */
-    int init_isolated = Py_IsolatedFlag;
-    int init_no_site = Py_NoSiteFlag;
-    Py_IsolatedFlag = cmdline->isolated;
-    Py_NoSiteFlag = cmdline->no_site_import;
-
-    err = _PyCoreConfig_Read(config);
-
-    cmdline->isolated = Py_IsolatedFlag;
-    cmdline->no_site_import = Py_NoSiteFlag;
-    Py_IsolatedFlag = init_isolated;
-    Py_NoSiteFlag = init_no_site;
+    err = _PyCoreConfig_Read(config,
+                             &cmdline->isolated,
+                             &cmdline->no_site_import);
 
     if (_Py_INIT_FAILED(err)) {
         pymain->err = err;
@@ -2116,7 +2106,7 @@ config_init_locale(_PyCoreConfig *config)
  */
 
 _PyInitError
-_PyCoreConfig_Read(_PyCoreConfig *config)
+_PyCoreConfig_Read(_PyCoreConfig *config, int *isolated, int *no_site_import)
 {
     _PyInitError err;
 
@@ -2161,7 +2151,7 @@ _PyCoreConfig_Read(_PyCoreConfig *config)
     }
 
     if (!config->_disable_importlib) {
-        err = _PyCoreConfig_InitPathConfig(config);
+        err = _PyCoreConfig_InitPathConfig(config, isolated, no_site_import);
         if (_Py_INIT_FAILED(err)) {
             return err;
         }
index fa687b7056b2b514208761e793168a4902620e55..df4cb0a20e35776eaaac8a81f8444fadddfe0444 100644 (file)
@@ -553,8 +553,7 @@ get_program_full_path(const _PyCoreConfig *core_config,
 
 
 static int
-read_pth_file(_PyPathConfig *config, wchar_t *prefix, const wchar_t *path,
-              int *isolated, int *nosite)
+read_pth_file(_PyPathConfig *config, wchar_t *prefix, const wchar_t *path)
 {
     FILE *sp_file = _Py_wfopen(path, L"r");
     if (sp_file == NULL) {
@@ -563,8 +562,8 @@ read_pth_file(_PyPathConfig *config, wchar_t *prefix, const wchar_t *path,
 
     wcscpy_s(prefix, MAXPATHLEN+1, path);
     reduce(prefix);
-    *isolated = 1;
-    *nosite = 1;
+    config->isolated = 1;
+    config->no_site_import = 1;
 
     size_t bufsiz = MAXPATHLEN;
     size_t prefixlen = wcslen(prefix);
@@ -589,9 +588,10 @@ read_pth_file(_PyPathConfig *config, wchar_t *prefix, const wchar_t *path,
         }
 
         if (strcmp(line, "import site") == 0) {
-            *nosite = 0;
+            config->no_site_import = 0;
             continue;
-        } else if (strncmp(line, "import ", 7) == 0) {
+        }
+        else if (strncmp(line, "import ", 7) == 0) {
             Py_FatalError("only 'import site' is supported in ._pth file");
         }
 
@@ -680,11 +680,7 @@ calculate_pth_file(_PyPathConfig *config, wchar_t *prefix)
         return 0;
     }
 
-    /* FIXME, bpo-32030: Global configuration variables should not be modified
-       here, _PyPathConfig_Init() is called early in Python initialization:
-       see pymain_cmdline(). */
-    return read_pth_file(config, prefix, spbuffer,
-                         &Py_IsolatedFlag, &Py_NoSiteFlag);
+    return read_pth_file(config, prefix, spbuffer);
 }
 
 
index e987df1b1fdfba0f27450918d701c731da0d91a9..1f6177faec4eca8942a6244beb993744704df55a 100644 (file)
@@ -283,7 +283,8 @@ core_config_init_module_search_paths(_PyCoreConfig *config,
 
 
 _PyInitError
-_PyCoreConfig_InitPathConfig(_PyCoreConfig *config)
+_PyCoreConfig_InitPathConfig(_PyCoreConfig *config,
+                             int *isolated, int *no_site_import)
 {
     _PyPathConfig path_config = _PyPathConfig_INIT;
     _PyInitError err;
@@ -344,6 +345,13 @@ _PyCoreConfig_InitPathConfig(_PyCoreConfig *config)
         }
     }
 
+    if (path_config.isolated != -1 && isolated != NULL) {
+        *isolated = path_config.isolated;
+    }
+    if (path_config.no_site_import != -1 && no_site_import != NULL) {
+        *no_site_import = path_config.no_site_import;
+    }
+
     _PyPathConfig_Clear(&path_config);
     return _Py_INIT_OK();
 
@@ -365,30 +373,25 @@ pathconfig_global_init(void)
     }
 
     _PyInitError err;
-    _PyPathConfig path_config = _PyPathConfig_INIT;
     _PyCoreConfig config = _PyCoreConfig_INIT;
 
-    err = _PyCoreConfig_Read(&config);
+    /* Py_IsolatedFlag and Py_NoSiteFlag are left unchanged: pass NULL.
+       _PyCoreConfig_InitPathConfig() will be called later and will set
+       these flags. */
+    err = _PyCoreConfig_Read(&config, NULL, NULL);
     if (_Py_INIT_FAILED(err)) {
         goto error;
     }
 
-    err = _PyPathConfig_Calculate(&path_config, &config);
+    err = _PyCoreConfig_SetPathConfig(&config);
     if (_Py_INIT_FAILED(err)) {
         goto error;
     }
 
-    err = _PyPathConfig_SetGlobal(&path_config);
-    if (_Py_INIT_FAILED(err)) {
-        goto error;
-    }
-
-    _PyPathConfig_Clear(&path_config);
     _PyCoreConfig_Clear(&config);
     return;
 
 error:
-    _PyPathConfig_Clear(&path_config);
     _PyCoreConfig_Clear(&config);
     _Py_FatalInitError(err);
 }
index 325f42305f39422383fd06965bd056a8a6c48588..584aa556bda0660a5ce101edd3c892a351a95202 100644 (file)
@@ -928,7 +928,7 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib)
     config._disable_importlib = !install_importlib;
     config.install_signal_handlers = install_sigs;
 
-    err = _PyCoreConfig_Read(&config);
+    err = _PyCoreConfig_Read(&config, &Py_IsolatedFlag, &Py_NoSiteFlag);
     if (_Py_INIT_FAILED(err)) {
         goto done;
     }