summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@redhat.com>2019-05-02 19:25:34 (GMT)
committerGitHub <noreply@github.com>2019-05-02 19:25:34 (GMT)
commit70005ac0fddd8585725b92acd1bc2b8e7b81999c (patch)
treef1be156bc866978bc4d251879f1e285cfa2df7ee
parent709d23dee69e700b87d5a4cb59e149d0e1af7993 (diff)
downloadcpython-70005ac0fddd8585725b92acd1bc2b8e7b81999c.zip
cpython-70005ac0fddd8585725b92acd1bc2b8e7b81999c.tar.gz
cpython-70005ac0fddd8585725b92acd1bc2b8e7b81999c.tar.bz2
bpo-36763: _PyCoreConfig_SetPyArgv() preinitializes Python (GH-13037)
_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()
-rw-r--r--Include/internal/pycore_pylifecycle.h9
-rw-r--r--Modules/main.c9
-rw-r--r--Python/coreconfig.c31
-rw-r--r--Python/pylifecycle.c28
4 files changed, 50 insertions, 27 deletions
diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h
index 321cc5d..adb1f5d 100644
--- a/Include/internal/pycore_pylifecycle.h
+++ b/Include/internal/pycore_pylifecycle.h
@@ -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
}
diff --git a/Modules/main.c b/Modules/main.c
index 575683c..e117ef2 100644
--- a/Modules/main.c
+++ b/Modules/main.c
@@ -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;
}
diff --git a/Python/coreconfig.c b/Python/coreconfig.c
index 15643be..5202694 100644
--- a/Python/coreconfig.c
+++ b/Python/coreconfig.c
@@ -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;
}
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 2a633cf..2ba43b9 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -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;
}