Skip to content

Commit bcdac03

Browse files
authored
gh-90548: Allow Alpine/MUSL to pass test_c_locale_coercion. (GH-134454)
Like cygwin, MUSL defaults to utf-8 if no variables are set. I have no idea if the existing tests pass on cygwin, but I made the modifications such that I shouldn't break it if is. The additional checks needed for MUSL are guarded by DEFAULT_LOCALE_IS_C being False. Based on this flag, we expect utf-8 for the encodings and no coercion message, as long as LC_ALL is not set to C. (That looks like a bit of an issue with the test structure, but I'm not going to attempt to "fix" that.) DEFAULT_ENCODING is intentionally not given a default since it is only used when DEFAULT_LOCALE_IS_C is False, and if you use the flag you'll need to set it. After reading through issue 30672, looking at the source, and running a test on Android, I *think* the current situation is that coercion will be done if the local is set to POSIX regardless of platform. However, if the platform doesn't make POSIX equivalent to C, the encodings when coercion is disabled will not be the same as for C (it is utf-8 on android, for example). This means the tests would fail if POSIX were added unconditionally to the EXPECTED_C_LOCALE_EQUIVALENTS as envisioned in the issue. This *could* be fixed with another flag, but I'm not sure it is worth the effort. I'm not even sure Python is behaving optimally in this case (assuming my analysis is correct). So I just altered the comment and add POSIX if and only if the platform is linux.
1 parent 2f5ace7 commit bcdac03

File tree

1 file changed

+23
-10
lines changed

1 file changed

+23
-10
lines changed

Lib/test/test_c_locale_coercion.py

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
from test.support.script_helper import run_python_until_end
1313

1414

15-
# Set the list of ways we expect to be able to ask for the "C" locale
15+
# Set the list of ways we expect to be able to ask for the "C" locale.
16+
# 'invalid.ascii' is an invalid LOCALE name and so should get turned in to the
17+
# default locale, which is traditionally C.
1618
EXPECTED_C_LOCALE_EQUIVALENTS = ["C", "invalid.ascii"]
1719

1820
# Set our expectation for the default encoding used in the C locale
@@ -21,6 +23,7 @@
2123
EXPECTED_C_LOCALE_FS_ENCODING = "ascii"
2224

2325
# Set our expectation for the default locale used when none is specified
26+
DEFAULT_LOCALE_IS_C = True
2427
EXPECT_COERCION_IN_DEFAULT_LOCALE = True
2528

2629
TARGET_LOCALES = ["C.UTF-8", "C.utf8", "UTF-8"]
@@ -30,12 +33,12 @@
3033
# Android defaults to using UTF-8 for all system interfaces
3134
EXPECTED_C_LOCALE_STREAM_ENCODING = "utf-8"
3235
EXPECTED_C_LOCALE_FS_ENCODING = "utf-8"
33-
elif sys.platform.startswith("linux"):
34-
# Linux distros typically alias the POSIX locale directly to the C
35-
# locale.
36-
# TODO: Once https://bugs.python.org/issue30672 is addressed, we'll be
37-
# able to check this case unconditionally
38-
EXPECTED_C_LOCALE_EQUIVALENTS.append("POSIX")
36+
elif support.linked_to_musl():
37+
# MUSL defaults to utf-8 unless the C locale is set explicitly.
38+
EXPECTED_C_LOCALE_EQUIVALENTS = ["C"]
39+
DEFAULT_LOCALE_IS_C = False
40+
DEFAULT_ENCODING = 'utf-8'
41+
EXPECT_COERCION_IN_DEFAULT_LOCALE = False
3942
elif sys.platform.startswith("aix"):
4043
# AIX uses iso8859-1 in the C locale, other *nix platforms use ASCII
4144
EXPECTED_C_LOCALE_STREAM_ENCODING = "iso8859-1"
@@ -52,6 +55,11 @@
5255
# VxWorks defaults to using UTF-8 for all system interfaces
5356
EXPECTED_C_LOCALE_STREAM_ENCODING = "utf-8"
5457
EXPECTED_C_LOCALE_FS_ENCODING = "utf-8"
58+
if sys.platform.startswith("linux"):
59+
# Linux recognizes POSIX as a synonym for C. Python will always coerce
60+
# if the locale is set to POSIX, but not all platforms will use the
61+
# C locale encodings if POSIX is set, so we'll only test it on linux.
62+
EXPECTED_C_LOCALE_EQUIVALENTS.append("POSIX")
5563

5664
# Note that the above expectations are still wrong in some cases, such as:
5765
# * Windows when PYTHONLEGACYWINDOWSFSENCODING is set
@@ -362,9 +370,14 @@ def _check_c_locale_coercion(self,
362370
base_var_dict["PYTHONCOERCECLOCALE"] = coerce_c_locale
363371

364372
# Check behaviour for the default locale
373+
_fs_encoding = fs_encoding
374+
_stream_encoding = stream_encoding
375+
if not DEFAULT_LOCALE_IS_C and 'LC_ALL' not in extra_vars:
376+
_fs_encoding = _stream_encoding = DEFAULT_ENCODING
365377
with self.subTest(default_locale=True,
366378
PYTHONCOERCECLOCALE=coerce_c_locale):
367-
if EXPECT_COERCION_IN_DEFAULT_LOCALE:
379+
if (EXPECT_COERCION_IN_DEFAULT_LOCALE
380+
or (not DEFAULT_LOCALE_IS_C and 'LC_ALL' in extra_vars)):
368381
_expected_warnings = expected_warnings
369382
_coercion_expected = coercion_expected
370383
else:
@@ -378,8 +391,8 @@ def _check_c_locale_coercion(self,
378391
_expected_warnings == [CLI_COERCION_WARNING]):
379392
_expected_warnings = None
380393
self._check_child_encoding_details(base_var_dict,
381-
fs_encoding,
382-
stream_encoding,
394+
_fs_encoding,
395+
_stream_encoding,
383396
None,
384397
_expected_warnings,
385398
_coercion_expected)

0 commit comments

Comments
 (0)