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()
This commit is contained in:
parent
709d23dee6
commit
70005ac0fd
|
@ -8,7 +8,8 @@ extern "C" {
|
||||||
# error "this header requires Py_BUILD_CORE define"
|
# error "this header requires Py_BUILD_CORE define"
|
||||||
#endif
|
#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
|
/* True if the main interpreter thread exited due to an unhandled
|
||||||
* KeyboardInterrupt exception, suggesting the user pressed ^C. */
|
* 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(void) _PyGC_DumpShutdownStats(_PyRuntimeState *runtime);
|
||||||
|
|
||||||
|
PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromPyArgv(
|
||||||
|
const _PyPreConfig *src_config,
|
||||||
|
const _PyArgv *args);
|
||||||
PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromCoreConfig(
|
PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromCoreConfig(
|
||||||
const _PyCoreConfig *coreconfig);
|
const _PyCoreConfig *coreconfig,
|
||||||
|
const _PyArgv *args);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,14 +57,7 @@ pymain_init(const _PyArgv *args)
|
||||||
environment variables (PYTHONUTF8 and PYTHONCOERCECLOCALE) */
|
environment variables (PYTHONUTF8 and PYTHONCOERCECLOCALE) */
|
||||||
preconfig.coerce_c_locale = -1;
|
preconfig.coerce_c_locale = -1;
|
||||||
preconfig.utf8_mode = -1;
|
preconfig.utf8_mode = -1;
|
||||||
if (args->use_bytes_argv) {
|
err = _Py_PreInitializeFromPyArgv(&preconfig, args);
|
||||||
err = _Py_PreInitializeFromArgs(&preconfig,
|
|
||||||
args->argc, args->bytes_argv);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
err = _Py_PreInitializeFromWideArgs(&preconfig,
|
|
||||||
args->argc, args->wchar_argv);
|
|
||||||
}
|
|
||||||
if (_Py_INIT_FAILED(err)) {
|
if (_Py_INIT_FAILED(err)) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
static _PyInitError
|
||||||
_PyCoreConfig_DecodeLocaleErr(wchar_t **config_str, const char *str,
|
_PyCoreConfig_DecodeLocaleErr(wchar_t **config_str, const char *str,
|
||||||
const char *decode_err_msg)
|
const char *decode_err_msg)
|
||||||
{
|
{
|
||||||
|
_PyInitError err = _Py_PreInitialize(NULL);
|
||||||
|
if (_Py_INIT_FAILED(err)) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
wchar_t *str2;
|
wchar_t *str2;
|
||||||
if (str != NULL) {
|
if (str != NULL) {
|
||||||
size_t len;
|
size_t len;
|
||||||
|
@ -572,6 +576,9 @@ _PyCoreConfig_DecodeLocaleErr(wchar_t **config_str, const char *str,
|
||||||
_PyCoreConfig_DecodeLocaleErr(config_str, str, "cannot decode " NAME)
|
_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
|
_PyInitError
|
||||||
_PyCoreConfig_DecodeLocale(wchar_t **config_str, const char *str)
|
_PyCoreConfig_DecodeLocale(wchar_t **config_str, const char *str)
|
||||||
{
|
{
|
||||||
|
@ -2100,10 +2107,30 @@ done:
|
||||||
_PyInitError
|
_PyInitError
|
||||||
_PyCoreConfig_SetPyArgv(_PyCoreConfig *config, const _PyArgv *args)
|
_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);
|
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
|
_PyInitError
|
||||||
_PyCoreConfig_SetArgv(_PyCoreConfig *config, int argc, char **argv)
|
_PyCoreConfig_SetArgv(_PyCoreConfig *config, int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
@ -2138,7 +2165,7 @@ _PyCoreConfig_Read(_PyCoreConfig *config)
|
||||||
{
|
{
|
||||||
_PyInitError err;
|
_PyInitError err;
|
||||||
|
|
||||||
err = _Py_PreInitializeFromCoreConfig(config);
|
err = _Py_PreInitializeFromCoreConfig(config, NULL);
|
||||||
if (_Py_INIT_FAILED(err)) {
|
if (_Py_INIT_FAILED(err)) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -683,8 +683,8 @@ _Py_InitializeCore_impl(_PyRuntimeState *runtime,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static _PyInitError
|
_PyInitError
|
||||||
preinit(const _PyPreConfig *src_config, const _PyArgv *args)
|
_Py_PreInitializeFromPyArgv(const _PyPreConfig *src_config, const _PyArgv *args)
|
||||||
{
|
{
|
||||||
_PyInitError err;
|
_PyInitError err;
|
||||||
|
|
||||||
|
@ -726,11 +726,12 @@ done:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_PyInitError
|
_PyInitError
|
||||||
_Py_PreInitializeFromArgs(const _PyPreConfig *src_config, int argc, char **argv)
|
_Py_PreInitializeFromArgs(const _PyPreConfig *src_config, int argc, char **argv)
|
||||||
{
|
{
|
||||||
_PyArgv args = {.use_bytes_argv = 1, .argc = argc, .bytes_argv = 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)
|
_Py_PreInitializeFromWideArgs(const _PyPreConfig *src_config, int argc, wchar_t **argv)
|
||||||
{
|
{
|
||||||
_PyArgv args = {.use_bytes_argv = 0, .argc = argc, .wchar_argv = argv};
|
_PyArgv args = {.use_bytes_argv = 0, .argc = argc, .wchar_argv = argv};
|
||||||
return preinit(src_config, &args);
|
return _Py_PreInitializeFromPyArgv(src_config, &args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_PyInitError
|
_PyInitError
|
||||||
_Py_PreInitialize(const _PyPreConfig *src_config)
|
_Py_PreInitialize(const _PyPreConfig *src_config)
|
||||||
{
|
{
|
||||||
return preinit(src_config, NULL);
|
return _Py_PreInitializeFromPyArgv(src_config, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_PyInitError
|
_PyInitError
|
||||||
_Py_PreInitializeFromCoreConfig(const _PyCoreConfig *coreconfig)
|
_Py_PreInitializeFromCoreConfig(const _PyCoreConfig *coreconfig,
|
||||||
|
const _PyArgv *args)
|
||||||
{
|
{
|
||||||
assert(coreconfig != NULL);
|
|
||||||
_PyPreConfig config = _PyPreConfig_INIT;
|
_PyPreConfig config = _PyPreConfig_INIT;
|
||||||
_PyCoreConfig_GetCoreConfig(&config, coreconfig);
|
if (coreconfig != NULL) {
|
||||||
return _Py_PreInitialize(&config);
|
_PyCoreConfig_GetCoreConfig(&config, coreconfig);
|
||||||
|
}
|
||||||
|
return _Py_PreInitializeFromPyArgv(&config, args);
|
||||||
/* No need to clear config:
|
/* No need to clear config:
|
||||||
_PyCoreConfig_GetCoreConfig() doesn't allocate memory */
|
_PyCoreConfig_GetCoreConfig() doesn't allocate memory */
|
||||||
}
|
}
|
||||||
|
@ -823,12 +826,7 @@ _Py_InitializeCore(_PyRuntimeState *runtime,
|
||||||
{
|
{
|
||||||
_PyInitError err;
|
_PyInitError err;
|
||||||
|
|
||||||
if (src_config) {
|
err = _Py_PreInitializeFromCoreConfig(src_config, args);
|
||||||
err = _Py_PreInitializeFromCoreConfig(src_config);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
err = _Py_PreInitialize(NULL);
|
|
||||||
}
|
|
||||||
if (_Py_INIT_FAILED(err)) {
|
if (_Py_INIT_FAILED(err)) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue