[Python-checkins] bpo-35336: Fix PYTHONCOERCECLOCALE=1 (GH-10806) (GH-10813)

Victor Stinner webhook-mailer at python.org
Fri Nov 30 06:19:51 EST 2018


https://github.com/python/cpython/commit/df738d56fe798b3586ed71775df25bf127789cf6
commit: df738d56fe798b3586ed71775df25bf127789cf6
branch: 3.7
author: Victor Stinner <vstinner at redhat.com>
committer: GitHub <noreply at github.com>
date: 2018-11-30T12:19:48+01:00
summary:

bpo-35336: Fix PYTHONCOERCECLOCALE=1 (GH-10806) (GH-10813)

Fix PYTHONCOERCECLOCALE=1 environment variable: only coerce the C
locale if the LC_CTYPE locale is "C".

(cherry picked from commit 55e498058faf8c97840556f6d791c2c392732dc3)

files:
A Misc/NEWS.d/next/Core and Builtins/2018-11-29-23-59-52.bpo-35336.8LOz4F.rst
M Lib/test/test_c_locale_coercion.py
M Modules/main.c

diff --git a/Lib/test/test_c_locale_coercion.py b/Lib/test/test_c_locale_coercion.py
index 1db293b9c373..134f07a17ec1 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
 
 import test.support
@@ -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 test.support.is_android:
@@ -404,6 +407,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():
     test.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 000000000000..28f8f9bd4db7
--- /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/Modules/main.c b/Modules/main.c
index 6dbe6a30786b..af2c191b9b9b 100644
--- a/Modules/main.c
+++ b/Modules/main.c
@@ -2191,11 +2191,17 @@ pymain_read_conf(_PyMain *pymain, _PyCoreConfig *config, _PyCmdline *cmdline)
 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
@@ -2376,7 +2382,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);
     }
 



More information about the Python-checkins mailing list