mirror of
https://github.com/python/cpython.git
synced 2025-07-24 11:44:31 +00:00
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().
This commit is contained in:
parent
2fc936ed24
commit
1a9f0d8efd
3 changed files with 251 additions and 168 deletions
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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)
|
||||||
#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)
|
||||||
/* 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);
|
return _PyCoreConfig_SetWideString(dest, var);
|
||||||
if (copy == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*dest = copy;
|
|
||||||
#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)
|
||||||
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)
|
||||||
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)
|
||||||
/* 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)
|
||||||
|
|
||||||
/* 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)
|
||||||
#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)
|
||||||
/* 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)
|
||||||
/* 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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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)
|
||||||
"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
|
||||||
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,
|
||||||
/* 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,
|
||||||
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,
|
||||||
/* 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,
|
||||||
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)
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
|
|
||||||
_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,
|
||||||
}
|
}
|
||||||
*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,
|
||||||
_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)
|
||||||
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;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue