Skip to content

Commit

Permalink
bpo-35336: Fix PYTHONCOERCECLOCALE=1 (GH-10806) (GH-10813)
Browse files Browse the repository at this point in the history
Fix PYTHONCOERCECLOCALE=1 environment variable: only coerce the C
locale if the LC_CTYPE locale is "C".

(cherry picked from commit 55e4980)
  • Loading branch information
vstinner committed Nov 30, 2018
1 parent 0df1f45 commit df738d5
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 4 deletions.
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

import test.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 test.support.is_android:
Expand Down Expand Up @@ -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,
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 Modules/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
}

Expand Down

0 comments on commit df738d5

Please sign in to comment.