Skip to content

Commit 32b7bcf

Browse files
authored
gh-93103: Py_DecodeLocale() uses _PyRuntime.preconfig (#93187)
The Py_DecodeLocale() and Py_EncodeLocale() now use _PyRuntime.preconfig, rather than Py_UTF8Mode and Py_LegacyWindowsFSEncodingFlag global configuration varibles, to decide if the UTF-8 encoding is used or not. As documented, these functions must not be called before Python is preinitialized. The new PyConfig API should now be used, rather than using deprecated functions like Py_SetPath() or PySys_SetArgv().
1 parent c7667a2 commit 32b7bcf

File tree

2 files changed

+14
-22
lines changed

2 files changed

+14
-22
lines changed

Python/fileutils.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -603,9 +603,9 @@ _Py_DecodeLocaleEx(const char* arg, wchar_t **wstr, size_t *wlen,
603603
return _Py_DecodeUTF8Ex(arg, strlen(arg), wstr, wlen, reason,
604604
errors);
605605
#else
606-
int use_utf8 = (Py_UTF8Mode == 1);
606+
int use_utf8 = (_PyRuntime.preconfig.utf8_mode >= 1);
607607
#ifdef MS_WINDOWS
608-
use_utf8 |= !Py_LegacyWindowsFSEncodingFlag;
608+
use_utf8 |= (_PyRuntime.preconfig.legacy_windows_fs_encoding == 0);
609609
#endif
610610
if (use_utf8) {
611611
return _Py_DecodeUTF8Ex(arg, strlen(arg), wstr, wlen, reason,
@@ -795,9 +795,9 @@ encode_locale_ex(const wchar_t *text, char **str, size_t *error_pos,
795795
return _Py_EncodeUTF8Ex(text, str, error_pos, reason,
796796
raw_malloc, errors);
797797
#else
798-
int use_utf8 = (Py_UTF8Mode == 1);
798+
int use_utf8 = (_PyRuntime.preconfig.utf8_mode >= 1);
799799
#ifdef MS_WINDOWS
800-
use_utf8 |= !Py_LegacyWindowsFSEncodingFlag;
800+
use_utf8 |= (_PyRuntime.preconfig.legacy_windows_fs_encoding == 0);
801801
#endif
802802
if (use_utf8) {
803803
return _Py_EncodeUTF8Ex(text, str, error_pos, reason,

Python/preconfig.c

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -826,12 +826,10 @@ _PyPreConfig_Read(PyPreConfig *config, const _PyArgv *args)
826826
_Py_SetLocaleFromEnv(LC_CTYPE);
827827
}
828828

829-
_PyPreCmdline cmdline = _PyPreCmdline_INIT;
830-
int init_utf8_mode = Py_UTF8Mode;
831-
#ifdef MS_WINDOWS
832-
int init_legacy_encoding = Py_LegacyWindowsFSEncodingFlag;
833-
#endif
829+
PyPreConfig save_runtime_config;
830+
preconfig_copy(&save_runtime_config, &_PyRuntime.preconfig);
834831

832+
_PyPreCmdline cmdline = _PyPreCmdline_INIT;
835833
int locale_coerced = 0;
836834
int loops = 0;
837835

@@ -847,11 +845,9 @@ _PyPreConfig_Read(PyPreConfig *config, const _PyArgv *args)
847845
}
848846

849847
/* bpo-34207: Py_DecodeLocale() and Py_EncodeLocale() depend
850-
on Py_UTF8Mode and Py_LegacyWindowsFSEncodingFlag. */
851-
Py_UTF8Mode = config->utf8_mode;
852-
#ifdef MS_WINDOWS
853-
Py_LegacyWindowsFSEncodingFlag = config->legacy_windows_fs_encoding;
854-
#endif
848+
on the utf8_mode and legacy_windows_fs_encoding members
849+
of _PyRuntime.preconfig. */
850+
preconfig_copy(&_PyRuntime.preconfig, config);
855851

856852
if (args) {
857853
// Set command line arguments at each iteration. If they are bytes
@@ -914,14 +910,10 @@ _PyPreConfig_Read(PyPreConfig *config, const _PyArgv *args)
914910
status = _PyStatus_OK();
915911

916912
done:
917-
if (init_ctype_locale != NULL) {
918-
setlocale(LC_CTYPE, init_ctype_locale);
919-
PyMem_RawFree(init_ctype_locale);
920-
}
921-
Py_UTF8Mode = init_utf8_mode ;
922-
#ifdef MS_WINDOWS
923-
Py_LegacyWindowsFSEncodingFlag = init_legacy_encoding;
924-
#endif
913+
// Revert side effects
914+
setlocale(LC_CTYPE, init_ctype_locale);
915+
PyMem_RawFree(init_ctype_locale);
916+
preconfig_copy(&_PyRuntime.preconfig, &save_runtime_config);
925917
_PyPreCmdline_Clear(&cmdline);
926918
return status;
927919
}

0 commit comments

Comments
 (0)