Skip to content

Commit 2c8ddcf

Browse files
authored
bpo-34485: Fix _Py_InitializeCore() for C locale coercion (GH-8979)
* _Py_InitializeCore() now sets the LC_CTYPE locale to the user preferred locale before checking if the C locale should be coerced or not in _PyCoreConfig_Read(). * Fix pymain_read_conf(): remember if the C locale has been coerced when the configuration should be read again if the encoding has changed.
1 parent 9e4994d commit 2c8ddcf

File tree

3 files changed

+19
-13
lines changed

3 files changed

+19
-13
lines changed

Modules/main.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1344,7 +1344,7 @@ pymain_read_conf(_PyMain *pymain, _PyCoreConfig *config,
13441344
* See the documentation of the PYTHONCOERCECLOCALE setting for more
13451345
* details.
13461346
*/
1347-
if (config->coerce_c_locale == 1 && !locale_coerced) {
1347+
if (config->coerce_c_locale && !locale_coerced) {
13481348
locale_coerced = 1;
13491349
_Py_CoerceLegacyLocale(config);
13501350
encoding_changed = 1;
@@ -1369,13 +1369,15 @@ pymain_read_conf(_PyMain *pymain, _PyCoreConfig *config,
13691369
/* Reset the configuration before reading again the configuration,
13701370
just keep UTF-8 Mode value. */
13711371
int new_utf8_mode = config->utf8_mode;
1372+
int new_coerce_c_locale = config->coerce_c_locale;
13721373
if (_PyCoreConfig_Copy(config, &save_config) < 0) {
13731374
pymain->err = _Py_INIT_NO_MEMORY();
13741375
goto done;
13751376
}
13761377
pymain_clear_cmdline(pymain, cmdline);
13771378
memset(cmdline, 0, sizeof(*cmdline));
13781379
config->utf8_mode = new_utf8_mode;
1380+
config->coerce_c_locale = new_coerce_c_locale;
13791381

13801382
/* The encoding changed: read again the configuration
13811383
with the new encoding */

Python/coreconfig.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -671,16 +671,18 @@ config_read_env_vars(_PyCoreConfig *config)
671671
config->malloc_stats = 1;
672672
}
673673

674-
if (config->coerce_c_locale < 0) {
675-
const char *env = _PyCoreConfig_GetEnv(config, "PYTHONCOERCECLOCALE");
676-
if (env) {
677-
if (strcmp(env, "0") == 0) {
674+
const char *env = _PyCoreConfig_GetEnv(config, "PYTHONCOERCECLOCALE");
675+
if (env) {
676+
if (strcmp(env, "0") == 0) {
677+
if (config->coerce_c_locale < 0) {
678678
config->coerce_c_locale = 0;
679679
}
680-
else if (strcmp(env, "warn") == 0) {
681-
config->coerce_c_locale_warn = 1;
682-
}
683-
else {
680+
}
681+
else if (strcmp(env, "warn") == 0) {
682+
config->coerce_c_locale_warn = 1;
683+
}
684+
else {
685+
if (config->coerce_c_locale < 0) {
684686
config->coerce_c_locale = 1;
685687
}
686688
}

Python/pylifecycle.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -659,10 +659,6 @@ _Py_InitializeCore_impl(PyInterpreterState **interp_p,
659659
_PyRuntime.finalizing = NULL;
660660

661661
#ifndef MS_WINDOWS
662-
/* Set up the LC_CTYPE locale, so we can obtain
663-
the locale's charset without having to switch
664-
locales. */
665-
_Py_SetLocaleFromEnv(LC_CTYPE);
666662
_emit_stderr_warning_for_legacy_locale(core_config);
667663
#endif
668664

@@ -815,6 +811,12 @@ _Py_InitializeCore(PyInterpreterState **interp_p,
815811
(and the input configuration is read only). */
816812
_PyCoreConfig config = _PyCoreConfig_INIT;
817813

814+
#ifndef MS_WINDOWS
815+
/* Set up the LC_CTYPE locale, so we can obtain the locale's charset
816+
without having to switch locales. */
817+
_Py_SetLocaleFromEnv(LC_CTYPE);
818+
#endif
819+
818820
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
819821
if (_PyCoreConfig_Copy(&config, src_config) >= 0) {
820822
err = _PyCoreConfig_Read(&config);

0 commit comments

Comments
 (0)