Commit 1a9f0d8e authored by Victor Stinner's avatar Victor Stinner Committed by GitHub

bpo-36763: Add _PyCoreConfig_SetString() (GH-13035)

Add 3 new config methods:

* _PyCoreConfig_SetString()
* _PyCoreConfig_SetWideString()
* _PyCoreConfig_SetWideStringFromString()

Changes:

* _PyCoreConfig_Copy() returns _PyInitError.
* Add CONFIG_GET_ENV_DUP().
parent 2fc936ed
...@@ -102,16 +102,24 @@ PyAPI_FUNC(_PyInitError) _PyPreConfig_Write(_PyPreConfig *config); ...@@ -102,16 +102,24 @@ PyAPI_FUNC(_PyInitError) _PyPreConfig_Write(_PyPreConfig *config);
/* --- _PyCoreConfig ---------------------------------------------- */ /* --- _PyCoreConfig ---------------------------------------------- */
PyAPI_FUNC(void) _PyCoreConfig_Clear(_PyCoreConfig *); PyAPI_FUNC(void) _PyCoreConfig_Clear(_PyCoreConfig *);
PyAPI_FUNC(int) _PyCoreConfig_Copy( PyAPI_FUNC(_PyInitError) _PyCoreConfig_Copy(
_PyCoreConfig *config, _PyCoreConfig *config,
const _PyCoreConfig *config2); const _PyCoreConfig *config2);
PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetString(
char **config_str,
const char *str);
PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetWideString(
wchar_t **config_str,
const wchar_t *str);
PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetWideStringFromString(
wchar_t **config_str,
const char *str);
PyAPI_FUNC(_PyInitError) _PyCoreConfig_InitPathConfig(_PyCoreConfig *config); PyAPI_FUNC(_PyInitError) _PyCoreConfig_InitPathConfig(_PyCoreConfig *config);
PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetPathConfig( PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetPathConfig(
const _PyCoreConfig *config); const _PyCoreConfig *config);
PyAPI_FUNC(_PyInitError) _PyCoreConfig_Read(_PyCoreConfig *config); PyAPI_FUNC(_PyInitError) _PyCoreConfig_Read(_PyCoreConfig *config);
PyAPI_FUNC(void) _PyCoreConfig_Write(const _PyCoreConfig *config, PyAPI_FUNC(void) _PyCoreConfig_Write(const _PyCoreConfig *config,
_PyRuntimeState *runtime); _PyRuntimeState *runtime);
PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetPyArgv( PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetPyArgv(
_PyCoreConfig *config, _PyCoreConfig *config,
const _PyArgv *args); const _PyArgv *args);
......
...@@ -520,34 +520,111 @@ _PyCoreConfig_Clear(_PyCoreConfig *config) ...@@ -520,34 +520,111 @@ _PyCoreConfig_Clear(_PyCoreConfig *config)
} }
int /* Copy str into *config_str (duplicate the string) */
_PyInitError
_PyCoreConfig_SetString(char **config_str, const char *str)
{
char *str2;
if (str != NULL) {
str2 = _PyMem_RawStrdup(str);
if (str2 == NULL) {
return _Py_INIT_NO_MEMORY();
}
}
else {
str2 = NULL;
}
PyMem_RawFree(*config_str);
*config_str = str2;
return _Py_INIT_OK();
}
/* Copy str into *config_str (duplicate the string) */
_PyInitError
_PyCoreConfig_SetWideString(wchar_t **config_str, const wchar_t *str)
{
wchar_t *str2;
if (str != NULL) {
str2 = _PyMem_RawWcsdup(str);
if (str2 == NULL) {
return _Py_INIT_NO_MEMORY();
}
}
else {
str2 = NULL;
}
PyMem_RawFree(*config_str);
*config_str = str2;
return _Py_INIT_OK();
}
/* Decode str using Py_DecodeLocale() and set the result into *config_str */
static _PyInitError
_PyCoreConfig_SetWideStringFromStringErr(wchar_t **config_str, const char *str,
const char *decode_err_msg)
{
wchar_t *str2;
if (str != NULL) {
size_t len;
str2 = Py_DecodeLocale(str, &len);
if (str2 == NULL) {
if (len == (size_t)-2) {
return _Py_INIT_ERR(decode_err_msg);
}
else {
return _Py_INIT_NO_MEMORY();
}
}
}
else {
str2 = NULL;
}
PyMem_RawFree(*config_str);
*config_str = str2;
return _Py_INIT_OK();
}
_PyInitError
_PyCoreConfig_SetWideStringFromString(wchar_t **config_str, const char *str)
{
return _PyCoreConfig_SetWideStringFromStringErr(
config_str, str, "cannot decode string");
}
#define CONFIG_DECODE_LOCALE(config_str, str, NAME) \
_PyCoreConfig_SetWideStringFromStringErr(config_str, str, \
"cannot decode " NAME)
_PyInitError
_PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2) _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
{ {
_PyInitError err;
_PyCoreConfig_Clear(config); _PyCoreConfig_Clear(config);
#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR #define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
#define COPY_STR_ATTR(ATTR) \ #define COPY_STR_ATTR(ATTR) \
do { \ do { \
if (config2->ATTR != NULL) { \ err = _PyCoreConfig_SetString(&config->ATTR, config2->ATTR); \
config->ATTR = _PyMem_RawStrdup(config2->ATTR); \ if (_Py_INIT_FAILED(err)) { \
if (config->ATTR == NULL) { \ return err; \
return -1; \
} \
} \ } \
} while (0) } while (0)
#define COPY_WSTR_ATTR(ATTR) \ #define COPY_WSTR_ATTR(ATTR) \
do { \ do { \
if (config2->ATTR != NULL) { \ err = _PyCoreConfig_SetWideString(&config->ATTR, config2->ATTR); \
config->ATTR = _PyMem_RawWcsdup(config2->ATTR); \ if (_Py_INIT_FAILED(err)) { \
if (config->ATTR == NULL) { \ return err; \
return -1; \
} \
} \ } \
} while (0) } while (0)
#define COPY_WSTRLIST(LIST) \ #define COPY_WSTRLIST(LIST) \
do { \ do { \
if (_PyWstrList_Copy(&config->LIST, &config2->LIST) < 0 ) { \ if (_PyWstrList_Copy(&config->LIST, &config2->LIST) < 0 ) { \
return -1; \ return _Py_INIT_NO_MEMORY(); \
} \ } \
} while (0) } while (0)
...@@ -617,7 +694,7 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2) ...@@ -617,7 +694,7 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
#undef COPY_STR_ATTR #undef COPY_STR_ATTR
#undef COPY_WSTR_ATTR #undef COPY_WSTR_ATTR
#undef COPY_WSTRLIST #undef COPY_WSTRLIST
return 0; return _Py_INIT_OK();
} }
...@@ -746,54 +823,44 @@ _PyCoreConfig_GetEnv(const _PyCoreConfig *config, const char *name) ...@@ -746,54 +823,44 @@ _PyCoreConfig_GetEnv(const _PyCoreConfig *config, const char *name)
/* Get a copy of the environment variable as wchar_t*. /* Get a copy of the environment variable as wchar_t*.
Return 0 on success, but *dest can be NULL. Return 0 on success, but *dest can be NULL.
Return -1 on memory allocation failure. Return -2 on decoding error. */ Return -1 on memory allocation failure. Return -2 on decoding error. */
static int static _PyInitError
_PyCoreConfig_GetEnvDup(const _PyCoreConfig *config, _PyCoreConfig_GetEnvDup(const _PyCoreConfig *config,
wchar_t **dest, wchar_t **dest,
wchar_t *wname, char *name) wchar_t *wname, char *name,
const char *decode_err_msg)
{ {
assert(*dest == NULL);
assert(config->use_environment >= 0); assert(config->use_environment >= 0);
if (!config->use_environment) { if (!config->use_environment) {
*dest = NULL; *dest = NULL;
return 0; return _Py_INIT_OK();
} }
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
const wchar_t *var = _wgetenv(wname); const wchar_t *var = _wgetenv(wname);
if (!var || var[0] == '\0') { if (!var || var[0] == '\0') {
*dest = NULL; *dest = NULL;
return 0; return _Py_INIT_OK();
}
wchar_t *copy = _PyMem_RawWcsdup(var);
if (copy == NULL) {
return -1;
} }
*dest = copy; return _PyCoreConfig_SetWideString(dest, var);
#else #else
const char *var = getenv(name); const char *var = getenv(name);
if (!var || var[0] == '\0') { if (!var || var[0] == '\0') {
*dest = NULL; *dest = NULL;
return 0; return _Py_INIT_OK();
} }
size_t len; return _PyCoreConfig_SetWideStringFromStringErr(dest, var, decode_err_msg);
wchar_t *wvar = Py_DecodeLocale(var, &len);
if (!wvar) {
if (len == (size_t)-2) {
return -2;
}
else {
return -1;
}
}
*dest = wvar;
#endif #endif
return 0;
} }
#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
_PyCoreConfig_GetEnvDup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
static void static void
_PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config) _PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config)
{ {
...@@ -876,6 +943,7 @@ _PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config) ...@@ -876,6 +943,7 @@ _PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config)
static _PyInitError static _PyInitError
config_init_program_name(_PyCoreConfig *config) config_init_program_name(_PyCoreConfig *config)
{ {
_PyInitError err;
assert(config->program_name == NULL); assert(config->program_name == NULL);
/* If Py_SetProgramName() was called, use its value */ /* If Py_SetProgramName() was called, use its value */
...@@ -900,13 +968,11 @@ config_init_program_name(_PyCoreConfig *config) ...@@ -900,13 +968,11 @@ config_init_program_name(_PyCoreConfig *config)
script. */ script. */
const char *p = _PyCoreConfig_GetEnv(config, "PYTHONEXECUTABLE"); const char *p = _PyCoreConfig_GetEnv(config, "PYTHONEXECUTABLE");
if (p != NULL) { if (p != NULL) {
size_t len; err = CONFIG_DECODE_LOCALE(&config->program_name, p,
wchar_t* program_name = Py_DecodeLocale(p, &len); "PYTHONEXECUTABLE environment variable");
if (program_name == NULL) { if (_Py_INIT_FAILED(err)) {
return DECODE_LOCALE_ERR("PYTHONEXECUTABLE environment " return err;
"variable", (Py_ssize_t)len);
} }
config->program_name = program_name;
return _Py_INIT_OK(); return _Py_INIT_OK();
} }
#ifdef WITH_NEXT_FRAMEWORK #ifdef WITH_NEXT_FRAMEWORK
...@@ -916,13 +982,11 @@ config_init_program_name(_PyCoreConfig *config) ...@@ -916,13 +982,11 @@ config_init_program_name(_PyCoreConfig *config)
/* Used by Mac/Tools/pythonw.c to forward /* Used by Mac/Tools/pythonw.c to forward
* the argv0 of the stub executable * the argv0 of the stub executable
*/ */
size_t len; err = CONFIG_DECODE_LOCALE(&config->program_name, pyvenv_launcher,
wchar_t* program_name = Py_DecodeLocale(pyvenv_launcher, &len); "__PYVENV_LAUNCHER__ environment variable");
if (program_name == NULL) { if (_Py_INIT_FAILED(err)) {
return DECODE_LOCALE_ERR("__PYVENV_LAUNCHER__ environment " return err;
"variable", (Py_ssize_t)len);
} }
config->program_name = program_name;
return _Py_INIT_OK(); return _Py_INIT_OK();
} }
} }
...@@ -931,9 +995,10 @@ config_init_program_name(_PyCoreConfig *config) ...@@ -931,9 +995,10 @@ config_init_program_name(_PyCoreConfig *config)
/* Use argv[0] by default, if available */ /* Use argv[0] by default, if available */
if (config->program != NULL) { if (config->program != NULL) {
config->program_name = _PyMem_RawWcsdup(config->program); err = _PyCoreConfig_SetWideString(&config->program_name,
if (config->program_name == NULL) { config->program);
return _Py_INIT_NO_MEMORY(); if (_Py_INIT_FAILED(err)) {
return err;
} }
return _Py_INIT_OK(); return _Py_INIT_OK();
} }
...@@ -944,9 +1009,9 @@ config_init_program_name(_PyCoreConfig *config) ...@@ -944,9 +1009,9 @@ config_init_program_name(_PyCoreConfig *config)
#else #else
const wchar_t *default_program_name = L"python3"; const wchar_t *default_program_name = L"python3";
#endif #endif
config->program_name = _PyMem_RawWcsdup(default_program_name); err = _PyCoreConfig_SetWideString(&config->program_name, default_program_name);
if (config->program_name == NULL) { if (_Py_INIT_FAILED(err)) {
return _Py_INIT_NO_MEMORY(); return err;
} }
return _Py_INIT_OK(); return _Py_INIT_OK();
} }
...@@ -959,13 +1024,13 @@ config_init_executable(_PyCoreConfig *config) ...@@ -959,13 +1024,13 @@ config_init_executable(_PyCoreConfig *config)
/* If Py_SetProgramFullPath() was called, use its value */ /* If Py_SetProgramFullPath() was called, use its value */
const wchar_t *program_full_path = _Py_path_config.program_full_path; const wchar_t *program_full_path = _Py_path_config.program_full_path;
if (program_full_path != NULL) { if (program_full_path != NULL) {
config->executable = _PyMem_RawWcsdup(program_full_path); _PyInitError err = _PyCoreConfig_SetWideString(&config->executable,
if (config->executable == NULL) { program_full_path);
return _Py_INIT_NO_MEMORY(); if (_Py_INIT_FAILED(err)) {
return err;
} }
return _Py_INIT_OK(); return _Py_INIT_OK();
} }
return _Py_INIT_OK(); return _Py_INIT_OK();
} }
...@@ -985,20 +1050,15 @@ config_init_home(_PyCoreConfig *config) ...@@ -985,20 +1050,15 @@ config_init_home(_PyCoreConfig *config)
/* If Py_SetPythonHome() was called, use its value */ /* If Py_SetPythonHome() was called, use its value */
wchar_t *home = _Py_path_config.home; wchar_t *home = _Py_path_config.home;
if (home) { if (home) {
config->home = _PyMem_RawWcsdup(home); _PyInitError err = _PyCoreConfig_SetWideString(&config->home, home);
if (config->home == NULL) { if (_Py_INIT_FAILED(err)) {
return _Py_INIT_NO_MEMORY(); return err;
} }
return _Py_INIT_OK(); return _Py_INIT_OK();
} }
int res = _PyCoreConfig_GetEnvDup(config, &home, return CONFIG_GET_ENV_DUP(config, &config->home,
L"PYTHONHOME", "PYTHONHOME"); L"PYTHONHOME", "PYTHONHOME");
if (res < 0) {
return DECODE_LOCALE_ERR("PYTHONHOME", res);
}
config->home = home;
return _Py_INIT_OK();
} }
...@@ -1055,6 +1115,7 @@ config_wstr_to_int(const wchar_t *wstr, int *result) ...@@ -1055,6 +1115,7 @@ config_wstr_to_int(const wchar_t *wstr, int *result)
static _PyInitError static _PyInitError
config_read_env_vars(_PyCoreConfig *config) config_read_env_vars(_PyCoreConfig *config)
{ {
_PyInitError err;
int use_env = config->use_environment; int use_env = config->use_environment;
/* Get environment variables */ /* Get environment variables */
...@@ -1094,17 +1155,15 @@ config_read_env_vars(_PyCoreConfig *config) ...@@ -1094,17 +1155,15 @@ config_read_env_vars(_PyCoreConfig *config)
} }
if (config->module_search_path_env == NULL) { if (config->module_search_path_env == NULL) {
wchar_t *path; err = CONFIG_GET_ENV_DUP(config, &config->module_search_path_env,
int res = _PyCoreConfig_GetEnvDup(config, &path, L"PYTHONPATH", "PYTHONPATH");
L"PYTHONPATH", "PYTHONPATH"); if (_Py_INIT_FAILED(err)) {
if (res < 0) { return err;
return DECODE_LOCALE_ERR("PYTHONPATH", res);
} }
config->module_search_path_env = path;
} }
if (config->use_hash_seed < 0) { if (config->use_hash_seed < 0) {
_PyInitError err = config_init_hash_seed(config); err = config_init_hash_seed(config);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
return err; return err;
} }
...@@ -1174,24 +1233,16 @@ config_init_pycache_prefix(_PyCoreConfig *config) ...@@ -1174,24 +1233,16 @@ config_init_pycache_prefix(_PyCoreConfig *config)
} }
} }
else { else {
// -X pycache_prefix= can cancel the env var // PYTHONPYCACHEPREFIX env var ignored
// if "-X pycache_prefix=" option is used
config->pycache_prefix = NULL; config->pycache_prefix = NULL;
} }
return _Py_INIT_OK();
} }
else {
wchar_t *env;
int res = _PyCoreConfig_GetEnvDup(config, &env,
L"PYTHONPYCACHEPREFIX",
"PYTHONPYCACHEPREFIX");
if (res < 0) {
return DECODE_LOCALE_ERR("PYTHONPYCACHEPREFIX", res);
}
if (env) { return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
config->pycache_prefix = env; L"PYTHONPYCACHEPREFIX",
} "PYTHONPYCACHEPREFIX");
}
return _Py_INIT_OK();
} }
...@@ -1270,11 +1321,9 @@ config_get_locale_encoding(char **locale_encoding) ...@@ -1270,11 +1321,9 @@ config_get_locale_encoding(char **locale_encoding)
"nl_langinfo(CODESET) failed"); "nl_langinfo(CODESET) failed");
} }
#endif #endif
*locale_encoding = _PyMem_RawStrdup(encoding);
if (*locale_encoding == NULL) { assert(*locale_encoding == NULL);
return _Py_INIT_NO_MEMORY(); return _PyCoreConfig_SetString(locale_encoding, encoding);
}
return _Py_INIT_OK();
} }
...@@ -1282,19 +1331,23 @@ static _PyInitError ...@@ -1282,19 +1331,23 @@ static _PyInitError
config_init_stdio_encoding(_PyCoreConfig *config, config_init_stdio_encoding(_PyCoreConfig *config,
const _PyPreConfig *preconfig) const _PyPreConfig *preconfig)
{ {
_PyInitError err;
/* If Py_SetStandardStreamEncoding() have been called, use these /* If Py_SetStandardStreamEncoding() have been called, use these
parameters. */ parameters. */
if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) { if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
config->stdio_encoding = _PyMem_RawStrdup(_Py_StandardStreamEncoding); err = _PyCoreConfig_SetString(&config->stdio_encoding,
if (config->stdio_encoding == NULL) { _Py_StandardStreamEncoding);
return _Py_INIT_NO_MEMORY(); if (_Py_INIT_FAILED(err)) {
return err;
} }
} }
if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) { if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
config->stdio_errors = _PyMem_RawStrdup(_Py_StandardStreamErrors); err = _PyCoreConfig_SetString(&config->stdio_errors,
if (config->stdio_errors == NULL) { _Py_StandardStreamErrors);
return _Py_INIT_NO_MEMORY(); if (_Py_INIT_FAILED(err)) {
return err;
} }
} }
...@@ -1305,27 +1358,30 @@ config_init_stdio_encoding(_PyCoreConfig *config, ...@@ -1305,27 +1358,30 @@ config_init_stdio_encoding(_PyCoreConfig *config,
/* PYTHONIOENCODING environment variable */ /* PYTHONIOENCODING environment variable */
const char *opt = _PyCoreConfig_GetEnv(config, "PYTHONIOENCODING"); const char *opt = _PyCoreConfig_GetEnv(config, "PYTHONIOENCODING");
if (opt) { if (opt) {
char *pythonioencoding = _PyMem_RawStrdup(opt); /* _PyCoreConfig_SetString() requires dest to be initialized to NULL */
if (pythonioencoding == NULL) { char *pythonioencoding = NULL;
return _Py_INIT_NO_MEMORY(); err = _PyCoreConfig_SetString(&pythonioencoding, opt);
if (_Py_INIT_FAILED(err)) {
return err;
} }
char *err = strchr(pythonioencoding, ':'); char *errors = strchr(pythonioencoding, ':');
if (err) { if (errors) {
*err = '\0'; *errors = '\0';
err++; errors++;
if (!err[0]) { if (!errors[0]) {
err = NULL; errors = NULL;
} }
} }
/* Does PYTHONIOENCODING contain an encoding? */ /* Does PYTHONIOENCODING contain an encoding? */
if (pythonioencoding[0]) { if (pythonioencoding[0]) {
if (config->stdio_encoding == NULL) { if (config->stdio_encoding == NULL) {
config->stdio_encoding = _PyMem_RawStrdup(pythonioencoding); err = _PyCoreConfig_SetString(&config->stdio_encoding,
if (config->stdio_encoding == NULL) { pythonioencoding);
if (_Py_INIT_FAILED(err)) {
PyMem_RawFree(pythonioencoding); PyMem_RawFree(pythonioencoding);
return _Py_INIT_NO_MEMORY(); return err;
} }
} }
...@@ -1333,16 +1389,16 @@ config_init_stdio_encoding(_PyCoreConfig *config, ...@@ -1333,16 +1389,16 @@ config_init_stdio_encoding(_PyCoreConfig *config,
use "strict" error handler by default. use "strict" error handler by default.
PYTHONIOENCODING=latin1 behaves as PYTHONIOENCODING=latin1 behaves as
PYTHONIOENCODING=latin1:strict. */ PYTHONIOENCODING=latin1:strict. */
if (!err) { if (!errors) {
err = "strict"; errors = "strict";
} }
} }
if (config->stdio_errors == NULL && err != NULL) { if (config->stdio_errors == NULL && errors != NULL) {
config->stdio_errors = _PyMem_RawStrdup(err); err = _PyCoreConfig_SetString(&config->stdio_errors, errors);
if (config->stdio_errors == NULL) { if (_Py_INIT_FAILED(err)) {
PyMem_RawFree(pythonioencoding); PyMem_RawFree(pythonioencoding);
return _Py_INIT_NO_MEMORY(); return err;
} }
} }
...@@ -1352,31 +1408,35 @@ config_init_stdio_encoding(_PyCoreConfig *config, ...@@ -1352,31 +1408,35 @@ config_init_stdio_encoding(_PyCoreConfig *config,
/* UTF-8 Mode uses UTF-8/surrogateescape */ /* UTF-8 Mode uses UTF-8/surrogateescape */
if (preconfig->utf8_mode) { if (preconfig->utf8_mode) {
if (config->stdio_encoding == NULL) { if (config->stdio_encoding == NULL) {
config->stdio_encoding = _PyMem_RawStrdup("utf-8"); err = _PyCoreConfig_SetString(&config->stdio_encoding,
if (config->stdio_encoding == NULL) { "utf-8");
return _Py_INIT_NO_MEMORY(); if (_Py_INIT_FAILED(err)) {
return err;
} }
} }
if (config->stdio_errors == NULL) { if (config->stdio_errors == NULL) {
config->stdio_errors = _PyMem_RawStrdup("surrogateescape"); err = _PyCoreConfig_SetString(&config->stdio_errors,
if (config->stdio_errors == NULL) { "surrogateescape");
return _Py_INIT_NO_MEMORY(); if (_Py_INIT_FAILED(err)) {
return err;
} }
} }
} }
/* Choose the default error handler based on the current locale. */ /* Choose the default error handler based on the current locale. */
if (config->stdio_encoding == NULL) { if (config->stdio_encoding == NULL) {
_PyInitError err = config_get_locale_encoding(&config->stdio_encoding); err = config_get_locale_encoding(&config->stdio_encoding);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
return err; return err;
} }
} }
if (config->stdio_errors == NULL) { if (config->stdio_errors == NULL) {
const char *errors = config_get_stdio_errors(config); const char *errors = config_get_stdio_errors(config);
config->stdio_errors = _PyMem_RawStrdup(errors); assert(errors != NULL);
if (config->stdio_errors == NULL) {
return _Py_INIT_NO_MEMORY(); err = _PyCoreConfig_SetString(&config->stdio_errors, errors);
if (_Py_INIT_FAILED(err)) {
return err;
} }
} }
...@@ -1387,19 +1447,23 @@ config_init_stdio_encoding(_PyCoreConfig *config, ...@@ -1387,19 +1447,23 @@ config_init_stdio_encoding(_PyCoreConfig *config,
static _PyInitError static _PyInitError
config_init_fs_encoding(_PyCoreConfig *config, const _PyPreConfig *preconfig) config_init_fs_encoding(_PyCoreConfig *config, const _PyPreConfig *preconfig)
{ {
_PyInitError err;
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
if (preconfig->legacy_windows_fs_encoding) { if (preconfig->legacy_windows_fs_encoding) {
/* Legacy Windows filesystem encoding: mbcs/replace */ /* Legacy Windows filesystem encoding: mbcs/replace */
if (config->filesystem_encoding == NULL) { if (config->filesystem_encoding == NULL) {
config->filesystem_encoding = _PyMem_RawStrdup("mbcs"); err = _PyCoreConfig_SetString(&config->filesystem_encoding,
if (config->filesystem_encoding == NULL) { "mbcs");
return _Py_INIT_NO_MEMORY(); if (_Py_INIT_FAILED(err)) {
return err;
} }
} }
if (config->filesystem_errors == NULL) { if (config->filesystem_errors == NULL) {
config->filesystem_errors = _PyMem_RawStrdup("replace"); err = _PyCoreConfig_SetString(&config->filesystem_errors,
if (config->filesystem_errors == NULL) { "replace");
return _Py_INIT_NO_MEMORY(); if (_Py_INIT_FAILED(err)) {
return err;
} }
} }
} }
...@@ -1409,51 +1473,54 @@ config_init_fs_encoding(_PyCoreConfig *config, const _PyPreConfig *preconfig) ...@@ -1409,51 +1473,54 @@ config_init_fs_encoding(_PyCoreConfig *config, const _PyPreConfig *preconfig)
Note: UTF-8 Mode takes the same code path and the Legacy Windows FS Note: UTF-8 Mode takes the same code path and the Legacy Windows FS
encoding has the priortiy over UTF-8 Mode. */ encoding has the priortiy over UTF-8 Mode. */
if (config->filesystem_encoding == NULL) { if (config->filesystem_encoding == NULL) {
config->filesystem_encoding = _PyMem_RawStrdup("utf-8"); err = _PyCoreConfig_SetString(&config->filesystem_encoding,
if (config->filesystem_encoding == NULL) { "utf-8");
return _Py_INIT_NO_MEMORY(); if (_Py_INIT_FAILED(err)) {
return err;
} }
} }
if (config->filesystem_errors == NULL) { if (config->filesystem_errors == NULL) {
config->filesystem_errors = _PyMem_RawStrdup("surrogatepass"); err = _PyCoreConfig_SetString(&config->filesystem_errors,
if (config->filesystem_errors == NULL) { "surrogatepass");
return _Py_INIT_NO_MEMORY(); if (_Py_INIT_FAILED(err)) {
return err;
} }
} }
#else #else
if (config->filesystem_encoding == NULL) { if (config->filesystem_encoding == NULL) {
if (preconfig->utf8_mode) { if (preconfig->utf8_mode) {
/* UTF-8 Mode use: utf-8/surrogateescape */ /* UTF-8 Mode use: utf-8/surrogateescape */
config->filesystem_encoding = _PyMem_RawStrdup("utf-8"); err = _PyCoreConfig_SetString(&config->filesystem_encoding,
"utf-8");
/* errors defaults to surrogateescape above */ /* errors defaults to surrogateescape above */
} }
else if (_Py_GetForceASCII()) { else if (_Py_GetForceASCII()) {
config->filesystem_encoding = _PyMem_RawStrdup("ascii"); err = _PyCoreConfig_SetString(&config->filesystem_encoding,
"ascii");
} }
else { else {
/* macOS and Android use UTF-8, /* macOS and Android use UTF-8,
other platforms use the locale encoding. */ other platforms use the locale encoding. */
#if defined(__APPLE__) || defined(__ANDROID__) #if defined(__APPLE__) || defined(__ANDROID__)
config->filesystem_encoding = _PyMem_RawStrdup("utf-8"); err = _PyCoreConfig_SetString(&config->filesystem_encoding,
"utf-8");
#else #else
_PyInitError err = config_get_locale_encoding(&config->filesystem_encoding); err = config_get_locale_encoding(&config->filesystem_encoding);
if (_Py_INIT_FAILED(err)) {
return err;
}
#endif #endif
} }
if (config->filesystem_encoding == NULL) { if (_Py_INIT_FAILED(err)) {
return _Py_INIT_NO_MEMORY(); return err;
} }
} }
if (config->filesystem_errors == NULL) { if (config->filesystem_errors == NULL) {
/* by default, use the "surrogateescape" error handler */ /* by default, use the "surrogateescape" error handler */
config->filesystem_errors = _PyMem_RawStrdup("surrogateescape"); err = _PyCoreConfig_SetString(&config->filesystem_errors,
if (config->filesystem_errors == NULL) { "surrogateescape");
return _Py_INIT_NO_MEMORY(); if (_Py_INIT_FAILED(err)) {
return err;
} }
} }
#endif #endif
...@@ -1828,13 +1895,16 @@ config_parse_cmdline(_PyCoreConfig *config, _PyPreCmdline *precmdline, ...@@ -1828,13 +1895,16 @@ config_parse_cmdline(_PyCoreConfig *config, _PyPreCmdline *precmdline,
static _PyInitError static _PyInitError
config_init_env_warnoptions(const _PyCoreConfig *config, _PyWstrList *warnoptions) config_init_env_warnoptions(const _PyCoreConfig *config, _PyWstrList *warnoptions)
{ {
wchar_t *env; _PyInitError err;
int res = _PyCoreConfig_GetEnvDup(config, &env, /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
L"PYTHONWARNINGS", "PYTHONWARNINGS"); wchar_t *env = NULL;
if (res < 0) { err = CONFIG_GET_ENV_DUP(config, &env,
return DECODE_LOCALE_ERR("PYTHONWARNINGS", res); L"PYTHONWARNINGS", "PYTHONWARNINGS");
if (_Py_INIT_FAILED(err)) {
return err;
} }
/* env var is not set or is empty */
if (env == NULL) { if (env == NULL) {
return _Py_INIT_OK(); return _Py_INIT_OK();
} }
......
...@@ -472,6 +472,7 @@ _Py_Initialize_ReconfigureCore(_PyRuntimeState *runtime, ...@@ -472,6 +472,7 @@ _Py_Initialize_ReconfigureCore(_PyRuntimeState *runtime,
PyInterpreterState **interp_p, PyInterpreterState **interp_p,
const _PyCoreConfig *core_config) const _PyCoreConfig *core_config)
{ {
_PyInitError err;
PyThreadState *tstate = _PyThreadState_GET(); PyThreadState *tstate = _PyThreadState_GET();
if (!tstate) { if (!tstate) {
return _Py_INIT_ERR("failed to read thread state"); return _Py_INIT_ERR("failed to read thread state");
...@@ -485,13 +486,14 @@ _Py_Initialize_ReconfigureCore(_PyRuntimeState *runtime, ...@@ -485,13 +486,14 @@ _Py_Initialize_ReconfigureCore(_PyRuntimeState *runtime,
_PyCoreConfig_Write(core_config, runtime); _PyCoreConfig_Write(core_config, runtime);
if (_PyCoreConfig_Copy(&interp->core_config, core_config) < 0) { err = _PyCoreConfig_Copy(&interp->core_config, core_config);
return _Py_INIT_NO_MEMORY(); if (_Py_INIT_FAILED(err)) {
return err;
} }
core_config = &interp->core_config; core_config = &interp->core_config;
if (core_config->_install_importlib) { if (core_config->_install_importlib) {
_PyInitError err = _PyCoreConfig_SetPathConfig(core_config); err = _PyCoreConfig_SetPathConfig(core_config);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
return err; return err;
} }
...@@ -545,8 +547,9 @@ pycore_create_interpreter(_PyRuntimeState *runtime, ...@@ -545,8 +547,9 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
} }
*interp_p = interp; *interp_p = interp;
if (_PyCoreConfig_Copy(&interp->core_config, core_config) < 0) { _PyInitError err = _PyCoreConfig_Copy(&interp->core_config, core_config);
return _Py_INIT_NO_MEMORY(); if (_Py_INIT_FAILED(err)) {
return err;
} }
core_config = &interp->core_config; core_config = &interp->core_config;
...@@ -804,8 +807,9 @@ pyinit_coreconfig(_PyRuntimeState *runtime, ...@@ -804,8 +807,9 @@ pyinit_coreconfig(_PyRuntimeState *runtime,
_PyInitError err; _PyInitError err;
if (src_config) { if (src_config) {
if (_PyCoreConfig_Copy(config, src_config) < 0) { err = _PyCoreConfig_Copy(config, src_config);
return _Py_INIT_NO_MEMORY(); if (_Py_INIT_FAILED(err)) {
return err;
} }
} }
...@@ -1433,8 +1437,9 @@ new_interpreter(PyThreadState **tstate_p) ...@@ -1433,8 +1437,9 @@ new_interpreter(PyThreadState **tstate_p)
core_config = &main_interp->core_config; core_config = &main_interp->core_config;
} }
if (_PyCoreConfig_Copy(&interp->core_config, core_config) < 0) { err = _PyCoreConfig_Copy(&interp->core_config, core_config);
return _Py_INIT_NO_MEMORY(); if (_Py_INIT_FAILED(err)) {
return err;
} }
core_config = &interp->core_config; core_config = &interp->core_config;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment