Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 26 additions & 2 deletions Lib/test/test_c_locale_coercion.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# Tests the attempted automatic coercion of the C locale to a UTF-8 locale

import unittest
import locale
import os
import shutil
import subprocess
import sys
import sysconfig
import shutil
import unittest
from collections import namedtuple

from test import support
Expand All @@ -25,6 +26,8 @@
# Set our expectation for the default locale used when none is specified
EXPECT_COERCION_IN_DEFAULT_LOCALE = True

TARGET_LOCALES = ["C.UTF-8", "C.utf8", "UTF-8"]

# Apply some platform dependent overrides
if sys.platform.startswith("linux"):
if support.is_android:
Expand Down Expand Up @@ -413,6 +416,27 @@ def test_LC_ALL_set_to_C(self):
expected_warnings=[LEGACY_LOCALE_WARNING],
coercion_expected=False)

def test_PYTHONCOERCECLOCALE_set_to_one(self):
# skip the test if the LC_CTYPE locale is C or coerced
old_loc = locale.setlocale(locale.LC_CTYPE, None)
self.addCleanup(locale.setlocale, locale.LC_CTYPE, old_loc)
loc = locale.setlocale(locale.LC_CTYPE, "")
if loc == "C":
self.skipTest("test requires LC_CTYPE locale different than C")
if loc in TARGET_LOCALES :
self.skipTest("coerced LC_CTYPE locale: %s" % loc)

# bpo-35336: PYTHONCOERCECLOCALE=1 must not coerce the LC_CTYPE locale
# if it's not equal to "C"
code = 'import locale; print(locale.setlocale(locale.LC_CTYPE, None))'
env = dict(os.environ, PYTHONCOERCECLOCALE='1')
cmd = subprocess.run([sys.executable, '-c', code],
stdout=subprocess.PIPE,
env=env,
text=True)
self.assertEqual(cmd.stdout.rstrip(), loc)


def test_main():
support.run_unittest(
LocaleConfigurationTests,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix PYTHONCOERCECLOCALE=1 environment variable: only coerce the C locale
if the LC_CTYPE locale is "C".
10 changes: 8 additions & 2 deletions Python/coreconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -1061,11 +1061,17 @@ config_read_complex_options(_PyCoreConfig *config)
static void
config_init_locale(_PyCoreConfig *config)
{
if (config->coerce_c_locale < 0) {
/* Test also if coerce_c_locale equals 1: PYTHONCOERCECLOCALE=1 doesn't
imply that the C locale is always coerced. It is only coerced if
if the LC_CTYPE locale is "C". */
if (config->coerce_c_locale != 0) {
/* The C locale enables the C locale coercion (PEP 538) */
if (_Py_LegacyLocaleDetected()) {
config->coerce_c_locale = 1;
}
else {
config->coerce_c_locale = 0;
}
}

#ifndef MS_WINDOWS
Expand Down Expand Up @@ -1394,7 +1400,7 @@ _PyCoreConfig_Read(_PyCoreConfig *config)
}
}

if (config->utf8_mode < 0 || config->coerce_c_locale < 0) {
if (config->coerce_c_locale != 0 || config->utf8_mode < 0) {
config_init_locale(config);
}

Expand Down