summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@redhat.com>2018-11-30 10:34:47 (GMT)
committerGitHub <noreply@github.com>2018-11-30 10:34:47 (GMT)
commit55e498058faf8c97840556f6d791c2c392732dc3 (patch)
treeac475e1ca2c6e45b9d9fb9414e86dc2a674b9473
parenta40700439195a119878150f4f0d425c42ca957ef (diff)
downloadcpython-55e498058faf8c97840556f6d791c2c392732dc3.zip
cpython-55e498058faf8c97840556f6d791c2c392732dc3.tar.gz
cpython-55e498058faf8c97840556f6d791c2c392732dc3.tar.bz2
bpo-35336: Fix PYTHONCOERCECLOCALE=1 (GH-10806)
Fix PYTHONCOERCECLOCALE=1 environment variable: only coerce the C locale if the LC_CTYPE locale is "C".
-rw-r--r--Lib/test/test_c_locale_coercion.py28
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2018-11-29-23-59-52.bpo-35336.8LOz4F.rst2
-rw-r--r--Python/coreconfig.c10
3 files changed, 36 insertions, 4 deletions
diff --git a/Lib/test/test_c_locale_coercion.py b/Lib/test/test_c_locale_coercion.py
index ce8ac4e..35272b5 100644
--- a/Lib/test/test_c_locale_coercion.py
+++ b/Lib/test/test_c_locale_coercion.py
@@ -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
@@ -25,6 +26,8 @@ EXPECTED_C_LOCALE_FS_ENCODING = "ascii"
# 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:
@@ -413,6 +416,27 @@ class LocaleCoercionTests(_LocaleHandlingTestCase):
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,
diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-11-29-23-59-52.bpo-35336.8LOz4F.rst b/Misc/NEWS.d/next/Core and Builtins/2018-11-29-23-59-52.bpo-35336.8LOz4F.rst
new file mode 100644
index 0000000..28f8f9b
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2018-11-29-23-59-52.bpo-35336.8LOz4F.rst
@@ -0,0 +1,2 @@
+Fix PYTHONCOERCECLOCALE=1 environment variable: only coerce the C locale
+if the LC_CTYPE locale is "C".
diff --git a/Python/coreconfig.c b/Python/coreconfig.c
index ad22300..2fb4e3f 100644
--- a/Python/coreconfig.c
+++ b/Python/coreconfig.c
@@ -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
@@ -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);
}