]> granicus.if.org Git - python/commitdiff
bpo-36763: _PyCoreConfig_SetPyArgv() preinitializes Python (GH-13037)
authorVictor Stinner <vstinner@redhat.com>
Thu, 2 May 2019 19:25:34 +0000 (15:25 -0400)
committerGitHub <noreply@github.com>
Thu, 2 May 2019 19:25:34 +0000 (15:25 -0400)
_PyCoreConfig_SetPyArgv() and _PyCoreConfig_SetWideString() now
pre-initialize Python if needed to ensure that the locale encoding is
properly configured.

* Add _Py_PreInitializeFromPyArgv() internal function.
* Add 'args' parameter to _Py_PreInitializeFromCoreConfig()

Include/internal/pycore_pylifecycle.h
Modules/main.c
Python/coreconfig.c
Python/pylifecycle.c

index 321cc5d27889bd0d16e8fc89a4f76af9ce62d719..adb1f5d90a5960e3fee0c041f6f3ac81ab077121 100644 (file)
@@ -8,7 +8,8 @@ extern "C" {
 #  error "this header requires Py_BUILD_CORE define"
 #endif
 
-#include "pycore_pystate.h"   /* _PyRuntimeState */
+#include "pycore_coreconfig.h"   /* _PyArgv */
+#include "pycore_pystate.h"      /* _PyRuntimeState */
 
 /* True if the main interpreter thread exited due to an unhandled
  * KeyboardInterrupt exception, suggesting the user pressed ^C. */
@@ -90,8 +91,12 @@ extern void _PyGILState_Fini(_PyRuntimeState *runtime);
 
 PyAPI_FUNC(void) _PyGC_DumpShutdownStats(_PyRuntimeState *runtime);
 
+PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromPyArgv(
+    const _PyPreConfig *src_config,
+    const _PyArgv *args);
 PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromCoreConfig(
-    const _PyCoreConfig *coreconfig);
+    const _PyCoreConfig *coreconfig,
+    const _PyArgv *args);
 
 #ifdef __cplusplus
 }
index 575683cd7f889f118137d7a8fb0ab43a11337a94..e117ef29e54dccc547e128970b23d899f1415240 100644 (file)
@@ -57,14 +57,7 @@ pymain_init(const _PyArgv *args)
        environment variables (PYTHONUTF8 and PYTHONCOERCECLOCALE)  */
     preconfig.coerce_c_locale = -1;
     preconfig.utf8_mode = -1;
-    if (args->use_bytes_argv) {
-        err = _Py_PreInitializeFromArgs(&preconfig,
-                                        args->argc, args->bytes_argv);
-    }
-    else {
-        err = _Py_PreInitializeFromWideArgs(&preconfig,
-                                            args->argc, args->wchar_argv);
-    }
+    err = _Py_PreInitializeFromPyArgv(&preconfig, args);
     if (_Py_INIT_FAILED(err)) {
         return err;
     }
index 15643be3765aa0f38dba19d37b8524e4f9cd19b1..52026949e202c34fcda882e90b7732aaffc3f298 100644 (file)
@@ -541,11 +541,15 @@ _PyCoreConfig_SetString(wchar_t **config_str, const wchar_t *str)
 }
 
 
-/* Decode str using Py_DecodeLocale() and set the result into *config_str */
 static _PyInitError
 _PyCoreConfig_DecodeLocaleErr(wchar_t **config_str, const char *str,
                               const char *decode_err_msg)
 {
+    _PyInitError err = _Py_PreInitialize(NULL);
+    if (_Py_INIT_FAILED(err)) {
+        return err;
+    }
+
     wchar_t *str2;
     if (str != NULL) {
         size_t len;
@@ -572,6 +576,9 @@ _PyCoreConfig_DecodeLocaleErr(wchar_t **config_str, const char *str,
     _PyCoreConfig_DecodeLocaleErr(config_str, str, "cannot decode " NAME)
 
 
+/* Decode str using Py_DecodeLocale() and set the result into *config_str.
+   Pre-initialize Python if needed to ensure that encodings are properly
+   configured. */
 _PyInitError
 _PyCoreConfig_DecodeLocale(wchar_t **config_str, const char *str)
 {
@@ -2100,10 +2107,30 @@ done:
 _PyInitError
 _PyCoreConfig_SetPyArgv(_PyCoreConfig *config, const _PyArgv *args)
 {
+    if (args->use_bytes_argv) {
+        _PyInitError err;
+
+        err = _PyRuntime_Initialize();
+        if (_Py_INIT_FAILED(err)) {
+            return err;
+        }
+        _PyRuntimeState *runtime = &_PyRuntime;
+
+        /* do nothing if Python is already pre-initialized:
+           _PyCoreConfig_Write() will update _PyRuntime.preconfig later */
+        if (!runtime->pre_initialized) {
+            err = _Py_PreInitializeFromCoreConfig(config, args);
+            if (_Py_INIT_FAILED(err)) {
+                return err;
+            }
+        }
+    }
     return _PyArgv_AsWstrList(args, &config->argv);
 }
 
 
+/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
+   if needed to ensure that encodings are properly configured. */
 _PyInitError
 _PyCoreConfig_SetArgv(_PyCoreConfig *config, int argc, char **argv)
 {
@@ -2138,7 +2165,7 @@ _PyCoreConfig_Read(_PyCoreConfig *config)
 {
     _PyInitError err;
 
-    err = _Py_PreInitializeFromCoreConfig(config);
+    err = _Py_PreInitializeFromCoreConfig(config, NULL);
     if (_Py_INIT_FAILED(err)) {
         return err;
     }
index 2a633cf1cf92733f4577146368c4757e0f31969b..2ba43b99cf3a4467f6155d1f4579a22041cee6e8 100644 (file)
@@ -683,8 +683,8 @@ _Py_InitializeCore_impl(_PyRuntimeState *runtime,
 }
 
 
-static _PyInitError
-preinit(const _PyPreConfig *src_config, const _PyArgv *args)
+_PyInitError
+_Py_PreInitializeFromPyArgv(const _PyPreConfig *src_config, const _PyArgv *args)
 {
     _PyInitError err;
 
@@ -726,11 +726,12 @@ done:
     return err;
 }
 
+
 _PyInitError
 _Py_PreInitializeFromArgs(const _PyPreConfig *src_config, int argc, char **argv)
 {
     _PyArgv args = {.use_bytes_argv = 1, .argc = argc, .bytes_argv = argv};
-    return preinit(src_config, &args);
+    return _Py_PreInitializeFromPyArgv(src_config, &args);
 }
 
 
@@ -738,24 +739,26 @@ _PyInitError
 _Py_PreInitializeFromWideArgs(const _PyPreConfig *src_config, int argc, wchar_t **argv)
 {
     _PyArgv args = {.use_bytes_argv = 0, .argc = argc, .wchar_argv = argv};
-    return preinit(src_config, &args);
+    return _Py_PreInitializeFromPyArgv(src_config, &args);
 }
 
 
 _PyInitError
 _Py_PreInitialize(const _PyPreConfig *src_config)
 {
-    return preinit(src_config, NULL);
+    return _Py_PreInitializeFromPyArgv(src_config, NULL);
 }
 
 
 _PyInitError
-_Py_PreInitializeFromCoreConfig(const _PyCoreConfig *coreconfig)
+_Py_PreInitializeFromCoreConfig(const _PyCoreConfig *coreconfig,
+                                const _PyArgv *args)
 {
-    assert(coreconfig != NULL);
     _PyPreConfig config = _PyPreConfig_INIT;
-    _PyCoreConfig_GetCoreConfig(&config, coreconfig);
-    return _Py_PreInitialize(&config);
+    if (coreconfig != NULL) {
+        _PyCoreConfig_GetCoreConfig(&config, coreconfig);
+    }
+    return _Py_PreInitializeFromPyArgv(&config, args);
     /* No need to clear config:
        _PyCoreConfig_GetCoreConfig() doesn't allocate memory */
 }
@@ -823,12 +826,7 @@ _Py_InitializeCore(_PyRuntimeState *runtime,
 {
     _PyInitError err;
 
-    if (src_config) {
-        err = _Py_PreInitializeFromCoreConfig(src_config);
-    }
-    else {
-        err = _Py_PreInitialize(NULL);
-    }
+    err = _Py_PreInitializeFromCoreConfig(src_config, args);
     if (_Py_INIT_FAILED(err)) {
         return err;
     }