From 63c7676f668d8f71a3f6d6ea6795ce650e98681a Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Sat, 11 Nov 2017 16:26:40 +1000 Subject: [PATCH 01/12] bpo-32002: Refactor C locale coercion tests Exactly which locale requests will end up giving you the "C" locale is actually platform dependent. A blank locale and "POSIX" will translate to "C" on most Linux distros, but may not do so on other platforms, so this adjusts the way the tests are structured accordingly. This may also prove sufficient to fix a current test failure on Cygwin (hence the issue reference) --- Lib/test/test_c_locale_coercion.py | 89 +++++++++++++----------------- 1 file changed, 39 insertions(+), 50 deletions(-) diff --git a/Lib/test/test_c_locale_coercion.py b/Lib/test/test_c_locale_coercion.py index 2a22739fb0f069..af237e54ade4cd 100644 --- a/Lib/test/test_c_locale_coercion.py +++ b/Lib/test/test_c_locale_coercion.py @@ -14,30 +14,36 @@ interpreter_requires_environment, ) +# Set the list of ways we expect to be able to ask for the "C" locale +EXPECTED_C_LOCALE_EQUIVALENTS = ["C", "invalid.ascii"] + # Set our expectation for the default encoding used in the C locale # for the filesystem encoding and the standard streams - -# While most *nix platforms default to ASCII in the C locale, some use a -# different encoding. -if sys.platform.startswith("aix"): - C_LOCALE_STREAM_ENCODING = "iso8859-1" -elif test.support.is_android: - C_LOCALE_STREAM_ENCODING = "utf-8" -else: - C_LOCALE_STREAM_ENCODING = "ascii" - -# FS encoding is UTF-8 on macOS, other *nix platforms use the locale encoding -if sys.platform == "darwin": - C_LOCALE_FS_ENCODING = "utf-8" -else: - C_LOCALE_FS_ENCODING = C_LOCALE_STREAM_ENCODING - -# Note that the above is probably still wrong in some cases, such as: +EXPECTED_C_LOCALE_STREAM_ENCODING = "ascii" +EXPECTED_C_LOCALE_FS_ENCODING = "ascii" + +# Apply some platform dependent overrides +if sys.platform.startswith("linux"): + # Linux distros typically use the C locale as their default, + # and alias the POSIX locale directly to the C locale + EXPECTED_C_LOCALE_EQUIVALENTS.extend(("", "POSIX")) +elif sys.platform.startswith("aix"): + # AIX uses iso8859-1 in the C locale, other *nix platforms use ASCII + EXPECTED_C_LOCALE_STREAM_ENCODING = "iso8859-1" + EXPECTED_C_LOCALE_FS_ENCODING = "iso8859-1" +elif sys.platform == "darwin": + # FS encoding is UTF-8 on macOS + EXPECTED_C_LOCALE_FS_ENCODING = "utf-8" + +# Note that the above expectations are still wrong in some cases, such as: # * Windows when PYTHONLEGACYWINDOWSFSENCODING is set -# * AIX and any other platforms that use latin-1 in the C locale +# * Any platform other than AIX that uses latin-1 in the C locale +# * Any Linux distro where POSIX isn't a simple alias for the C locale +# * Any Linux distro where the default locale is something other than "C" # # Options for dealing with this: -# * Don't set PYTHON_COERCE_C_LOCALE on such platforms (e.g. Windows doesn't) +# * Don't set the PYTHON_COERCE_C_LOCALE preprocessor definition on +# such platforms (e.g. it isn't set on Windows) # * Fix the test expectations to match the actual platform behaviour # In order to get the warning messages to match up as expected, the candidate @@ -47,7 +53,7 @@ # There's no reliable cross-platform way of checking locale alias # lists, so the only way of knowing which of these locales will work # is to try them with locale.setlocale(). We do that in a subprocess -# to avoid altering the locale of the test runner. +# in setupModule() below to avoid altering the locale of the test runner. # # If the relevant locale module attributes exist, and we're not on a platform # where we expect it to always succeed, we also check that @@ -217,7 +223,8 @@ def _check_child_encoding_details(self, class LocaleConfigurationTests(_LocaleHandlingTestCase): # Test explicit external configuration via the process environment - def setUpClass(): + @classmethod + def setUpClass(cls): # This relies on setupModule() having been run, so it can't be # handled via the @unittest.skipUnless decorator if not AVAILABLE_TARGETS: @@ -284,8 +291,8 @@ def _check_c_locale_coercion(self, if not AVAILABLE_TARGETS: # Locale coercion is disabled when there aren't any target locales - fs_encoding = C_LOCALE_FS_ENCODING - stream_encoding = C_LOCALE_STREAM_ENCODING + fs_encoding = EXPECTED_C_LOCALE_FS_ENCODING + stream_encoding = EXPECTED_C_LOCALE_STREAM_ENCODING coercion_expected = False if expected_warnings: expected_warnings = [LEGACY_LOCALE_WARNING] @@ -297,25 +304,7 @@ def _check_c_locale_coercion(self, } base_var_dict.update(extra_vars) for env_var in ("LANG", "LC_CTYPE"): - for locale_to_set in ("", "C", "POSIX", "invalid.ascii"): - # XXX (ncoghlan): *BSD platforms don't behave as expected in the - # POSIX locale, so we skip that for now - # See https://bugs.python.org/issue30672 for discussion - if locale_to_set == "POSIX": - continue - - # Platforms using UTF-8 in the C locale do not print - # CLI_COERCION_WARNING when all the locale envt variables are - # not set or set to the empty string. - _expected_warnings = expected_warnings - for _env_var in base_var_dict: - if base_var_dict[_env_var]: - break - else: - if (C_LOCALE_STREAM_ENCODING == "utf-8" and - locale_to_set == "" and coerce_c_locale == "warn"): - _expected_warnings = None - + for locale_to_set in EXPECTED_C_LOCALE_EQUIVALENTS: with self.subTest(env_var=env_var, nominal_locale=locale_to_set, PYTHONCOERCECLOCALE=coerce_c_locale): @@ -349,27 +338,27 @@ def test_PYTHONCOERCECLOCALE_set_to_warn(self): def test_PYTHONCOERCECLOCALE_set_to_zero(self): # The setting "0" should result in the locale coercion being disabled - self._check_c_locale_coercion(C_LOCALE_FS_ENCODING, - C_LOCALE_STREAM_ENCODING, + self._check_c_locale_coercion(EXPECTED_C_LOCALE_FS_ENCODING, + EXPECTED_C_LOCALE_STREAM_ENCODING, coerce_c_locale="0", coercion_expected=False) # Setting LC_ALL=C shouldn't make any difference to the behaviour - self._check_c_locale_coercion(C_LOCALE_FS_ENCODING, - C_LOCALE_STREAM_ENCODING, + self._check_c_locale_coercion(EXPECTED_C_LOCALE_FS_ENCODING, + EXPECTED_C_LOCALE_STREAM_ENCODING, coerce_c_locale="0", LC_ALL="C", coercion_expected=False) def test_LC_ALL_set_to_C(self): # Setting LC_ALL should render the locale coercion ineffective - self._check_c_locale_coercion(C_LOCALE_FS_ENCODING, - C_LOCALE_STREAM_ENCODING, + self._check_c_locale_coercion(EXPECTED_C_LOCALE_FS_ENCODING, + EXPECTED_C_LOCALE_STREAM_ENCODING, coerce_c_locale=None, LC_ALL="C", coercion_expected=False) # And result in a warning about a lack of locale compatibility - self._check_c_locale_coercion(C_LOCALE_FS_ENCODING, - C_LOCALE_STREAM_ENCODING, + self._check_c_locale_coercion(EXPECTED_C_LOCALE_FS_ENCODING, + EXPECTED_C_LOCALE_STREAM_ENCODING, coerce_c_locale="warn", LC_ALL="C", expected_warnings=[LEGACY_LOCALE_WARNING], From 8d4f70480b94f9a0d69f2ffbd41703a92eb0f291 Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Sat, 11 Nov 2017 16:36:52 +1000 Subject: [PATCH 02/12] Add NEWS entry --- .../NEWS.d/next/Tests/2017-11-11-16-35-18.bpo-32002.itDxIo.rst | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Misc/NEWS.d/next/Tests/2017-11-11-16-35-18.bpo-32002.itDxIo.rst diff --git a/Misc/NEWS.d/next/Tests/2017-11-11-16-35-18.bpo-32002.itDxIo.rst b/Misc/NEWS.d/next/Tests/2017-11-11-16-35-18.bpo-32002.itDxIo.rst new file mode 100644 index 00000000000000..a503bb74aefb3c --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2017-11-11-16-35-18.bpo-32002.itDxIo.rst @@ -0,0 +1,3 @@ +Restrict C locale coercion testing for the empty locale and POSIX locale +cases to Linux until we better understand the expected behaviour on non- +Linux platforms. From 9f8d9f8215bf8c82fa15d7699ec9d71928c79738 Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Sun, 12 Nov 2017 20:59:25 +1000 Subject: [PATCH 03/12] Make the default locale its own subtest --- Lib/test/test_c_locale_coercion.py | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_c_locale_coercion.py b/Lib/test/test_c_locale_coercion.py index af237e54ade4cd..8ba1a5b9f47b39 100644 --- a/Lib/test/test_c_locale_coercion.py +++ b/Lib/test/test_c_locale_coercion.py @@ -24,9 +24,8 @@ # Apply some platform dependent overrides if sys.platform.startswith("linux"): - # Linux distros typically use the C locale as their default, - # and alias the POSIX locale directly to the C locale - EXPECTED_C_LOCALE_EQUIVALENTS.extend(("", "POSIX")) + # Linux distros typically alias the POSIX locale directly to the C locale + EXPECTED_C_LOCALE_EQUIVALENTS.append("POSIX") elif sys.platform.startswith("aix"): # AIX uses iso8859-1 in the C locale, other *nix platforms use ASCII EXPECTED_C_LOCALE_STREAM_ENCODING = "iso8859-1" @@ -303,8 +302,23 @@ def _check_c_locale_coercion(self, "LC_ALL": "", } base_var_dict.update(extra_vars) - for env_var in ("LANG", "LC_CTYPE"): - for locale_to_set in EXPECTED_C_LOCALE_EQUIVALENTS: + + # Check behaviour for the default locale + with self.subTest(default_locale=True, + PYTHONCOERCECLOCALE=coerce_c_locale): + var_dict = base_var_dict.copy() + if coerce_c_locale is not None: + var_dict["PYTHONCOERCECLOCALE"] = coerce_c_locale + # Check behaviour on successful coercion + self._check_child_encoding_details(var_dict, + fs_encoding, + stream_encoding, + expected_warnings, + coercion_expected) + + # Check behaviour for explicitly configured locales + for locale_to_set in EXPECTED_C_LOCALE_EQUIVALENTS: + for env_var in ("LANG", "LC_CTYPE"): with self.subTest(env_var=env_var, nominal_locale=locale_to_set, PYTHONCOERCECLOCALE=coerce_c_locale): From e282db70be309e848ff55d82282e1a67e99399ac Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Sun, 12 Nov 2017 22:12:51 +1000 Subject: [PATCH 04/12] Fix method name in comments --- Lib/test/test_c_locale_coercion.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_c_locale_coercion.py b/Lib/test/test_c_locale_coercion.py index 8ba1a5b9f47b39..ca2e13683747a1 100644 --- a/Lib/test/test_c_locale_coercion.py +++ b/Lib/test/test_c_locale_coercion.py @@ -52,7 +52,7 @@ # There's no reliable cross-platform way of checking locale alias # lists, so the only way of knowing which of these locales will work # is to try them with locale.setlocale(). We do that in a subprocess -# in setupModule() below to avoid altering the locale of the test runner. +# in setUpModule() below to avoid altering the locale of the test runner. # # If the relevant locale module attributes exist, and we're not on a platform # where we expect it to always succeed, we also check that @@ -224,7 +224,7 @@ class LocaleConfigurationTests(_LocaleHandlingTestCase): @classmethod def setUpClass(cls): - # This relies on setupModule() having been run, so it can't be + # This relies on setUpModule() having been run, so it can't be # handled via the @unittest.skipUnless decorator if not AVAILABLE_TARGETS: raise unittest.SkipTest("No C-with-UTF-8 locale available") From 8ff68a81659ea66c7f9d2d0a9c96a9cb9c6f7907 Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Sun, 12 Nov 2017 22:23:30 +1000 Subject: [PATCH 05/12] Fix merge error --- Lib/test/test_c_locale_coercion.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_c_locale_coercion.py b/Lib/test/test_c_locale_coercion.py index ca2e13683747a1..4f18603938c430 100644 --- a/Lib/test/test_c_locale_coercion.py +++ b/Lib/test/test_c_locale_coercion.py @@ -307,13 +307,16 @@ def _check_c_locale_coercion(self, with self.subTest(default_locale=True, PYTHONCOERCECLOCALE=coerce_c_locale): var_dict = base_var_dict.copy() + _expected_warnings = expected_warnings if coerce_c_locale is not None: var_dict["PYTHONCOERCECLOCALE"] = coerce_c_locale - # Check behaviour on successful coercion + if (EXPECTED_C_LOCALE_STREAM_ENCODING == "utf-8" + and coerce_c_locale == "warn"): + _expected_warnings = None self._check_child_encoding_details(var_dict, fs_encoding, stream_encoding, - expected_warnings, + _expected_warnings, coercion_expected) # Check behaviour for explicitly configured locales @@ -330,7 +333,7 @@ def _check_c_locale_coercion(self, self._check_child_encoding_details(var_dict, fs_encoding, stream_encoding, - _expected_warnings, + expected_warnings, coercion_expected) def test_test_PYTHONCOERCECLOCALE_not_set(self): From 75e585b3b51aadb1a493e0a2a05e631f4b325910 Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Sun, 12 Nov 2017 22:26:54 +1000 Subject: [PATCH 06/12] Reword NEWS entry --- .../next/Tests/2017-11-11-16-35-18.bpo-32002.itDxIo.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Misc/NEWS.d/next/Tests/2017-11-11-16-35-18.bpo-32002.itDxIo.rst b/Misc/NEWS.d/next/Tests/2017-11-11-16-35-18.bpo-32002.itDxIo.rst index a503bb74aefb3c..9cc7ec22c45798 100644 --- a/Misc/NEWS.d/next/Tests/2017-11-11-16-35-18.bpo-32002.itDxIo.rst +++ b/Misc/NEWS.d/next/Tests/2017-11-11-16-35-18.bpo-32002.itDxIo.rst @@ -1,3 +1,2 @@ -Restrict C locale coercion testing for the empty locale and POSIX locale -cases to Linux until we better understand the expected behaviour on non- -Linux platforms. +Adjust C locale coercion testing for the empty locale and POSIX locale +cases to more readily adjust to platform dependent behaviour. From af504fff69ed8792e0f356edcca4c4132561917e Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Sun, 12 Nov 2017 22:36:07 +1000 Subject: [PATCH 07/12] Fix doubled word in test method name --- Lib/test/test_c_locale_coercion.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_c_locale_coercion.py b/Lib/test/test_c_locale_coercion.py index 4f18603938c430..801eea9e493e66 100644 --- a/Lib/test/test_c_locale_coercion.py +++ b/Lib/test/test_c_locale_coercion.py @@ -336,7 +336,7 @@ def _check_c_locale_coercion(self, expected_warnings, coercion_expected) - def test_test_PYTHONCOERCECLOCALE_not_set(self): + def test_PYTHONCOERCECLOCALE_not_set(self): # This should coerce to the first available target locale by default self._check_c_locale_coercion("utf-8", "utf-8", coerce_c_locale=None) From 05abe72491d1a5e6d17f65151eaf106725c1b9f9 Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Sat, 9 Dec 2017 18:41:27 +1000 Subject: [PATCH 08/12] Avoid unneeded dict copy in tests --- Lib/test/test_c_locale_coercion.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_c_locale_coercion.py b/Lib/test/test_c_locale_coercion.py index 801eea9e493e66..cf5d84dad5a1e7 100644 --- a/Lib/test/test_c_locale_coercion.py +++ b/Lib/test/test_c_locale_coercion.py @@ -302,18 +302,17 @@ def _check_c_locale_coercion(self, "LC_ALL": "", } base_var_dict.update(extra_vars) + if coerce_c_locale is not None: + base_var_dict["PYTHONCOERCECLOCALE"] = coerce_c_locale # Check behaviour for the default locale with self.subTest(default_locale=True, PYTHONCOERCECLOCALE=coerce_c_locale): - var_dict = base_var_dict.copy() _expected_warnings = expected_warnings - if coerce_c_locale is not None: - var_dict["PYTHONCOERCECLOCALE"] = coerce_c_locale - if (EXPECTED_C_LOCALE_STREAM_ENCODING == "utf-8" - and coerce_c_locale == "warn"): - _expected_warnings = None - self._check_child_encoding_details(var_dict, + if (EXPECTED_C_LOCALE_STREAM_ENCODING == "utf-8" + and coerce_c_locale == "warn"): + _expected_warnings = None + self._check_child_encoding_details(base_var_dict, fs_encoding, stream_encoding, _expected_warnings, @@ -327,8 +326,6 @@ def _check_c_locale_coercion(self, PYTHONCOERCECLOCALE=coerce_c_locale): var_dict = base_var_dict.copy() var_dict[env_var] = locale_to_set - if coerce_c_locale is not None: - var_dict["PYTHONCOERCECLOCALE"] = coerce_c_locale # Check behaviour on successful coercion self._check_child_encoding_details(var_dict, fs_encoding, From 17364e8b2c7c2d3ff4ae248706430a0c2030e996 Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Sat, 9 Dec 2017 18:43:06 +1000 Subject: [PATCH 09/12] Fix directive name in comment --- Lib/test/test_c_locale_coercion.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_c_locale_coercion.py b/Lib/test/test_c_locale_coercion.py index cf5d84dad5a1e7..80a33b4a72fac0 100644 --- a/Lib/test/test_c_locale_coercion.py +++ b/Lib/test/test_c_locale_coercion.py @@ -41,7 +41,7 @@ # * Any Linux distro where the default locale is something other than "C" # # Options for dealing with this: -# * Don't set the PYTHON_COERCE_C_LOCALE preprocessor definition on +# * Don't set the PY_COERCE_C_LOCALE preprocessor definition on # such platforms (e.g. it isn't set on Windows) # * Fix the test expectations to match the actual platform behaviour From e61457b9f87500832766d02ea074017cdd87e657 Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Sat, 9 Dec 2017 18:47:18 +1000 Subject: [PATCH 10/12] Add issue reference in current Linux special case --- Lib/test/test_c_locale_coercion.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Lib/test/test_c_locale_coercion.py b/Lib/test/test_c_locale_coercion.py index 80a33b4a72fac0..bc4b2ed0ccb1ca 100644 --- a/Lib/test/test_c_locale_coercion.py +++ b/Lib/test/test_c_locale_coercion.py @@ -25,6 +25,8 @@ # Apply some platform dependent overrides if sys.platform.startswith("linux"): # Linux distros typically alias the POSIX locale directly to the C locale + # TODO: Once https://bugs.python.org/issue30672 is addressed, we'll be + # able to check this case unconditionally EXPECTED_C_LOCALE_EQUIVALENTS.append("POSIX") elif sys.platform.startswith("aix"): # AIX uses iso8859-1 in the C locale, other *nix platforms use ASCII From 13f06bbdac2f9b4e4f6fc1046580ec9327eb1959 Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Sat, 9 Dec 2017 19:06:56 +1000 Subject: [PATCH 11/12] Fix test expectations for Cygwin & Android --- Lib/test/test_c_locale_coercion.py | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_c_locale_coercion.py b/Lib/test/test_c_locale_coercion.py index bc4b2ed0ccb1ca..b47adcd6ae922c 100644 --- a/Lib/test/test_c_locale_coercion.py +++ b/Lib/test/test_c_locale_coercion.py @@ -22,6 +22,9 @@ EXPECTED_C_LOCALE_STREAM_ENCODING = "ascii" EXPECTED_C_LOCALE_FS_ENCODING = "ascii" +# Set our expectation for the default locale used when none is specified +EXPECT_COERCION_IN_DEFAULT_LOCALE = True + # Apply some platform dependent overrides if sys.platform.startswith("linux"): # Linux distros typically alias the POSIX locale directly to the C locale @@ -35,6 +38,16 @@ elif sys.platform == "darwin": # FS encoding is UTF-8 on macOS EXPECTED_C_LOCALE_FS_ENCODING = "utf-8" +elif sys.platform == "cygwin": + # Cygwin defaults to using C.UTF-8 + # TODO: Work out a robust dynamic test for this that doesn't rely on + # CPython's own locale handling machinery + EXPECT_COERCION_IN_DEFAULT_LOCALE = False +elif test.support.is_android: + # Android defaults to using UTF-8 for all system interfaces + EXPECTED_C_LOCALE_STREAM_ENCODING = "utf-8" + EXPECTED_C_LOCALE_FS_ENCODING = "utf-8" + EXPECT_COERCION_IN_DEFAULT_LOCALE = False # Note that the above expectations are still wrong in some cases, such as: # * Windows when PYTHONLEGACYWINDOWSFSENCODING is set @@ -310,15 +323,17 @@ def _check_c_locale_coercion(self, # Check behaviour for the default locale with self.subTest(default_locale=True, PYTHONCOERCECLOCALE=coerce_c_locale): - _expected_warnings = expected_warnings - if (EXPECTED_C_LOCALE_STREAM_ENCODING == "utf-8" - and coerce_c_locale == "warn"): + if EXPECT_COERCION_IN_DEFAULT_LOCALE: + _expected_warnings = expected_warnings + _coercion_expected = coercion_expected + else: _expected_warnings = None + _coercion_expected = False self._check_child_encoding_details(base_var_dict, fs_encoding, stream_encoding, _expected_warnings, - coercion_expected) + _coercion_expected) # Check behaviour for explicitly configured locales for locale_to_set in EXPECTED_C_LOCALE_EQUIVALENTS: From 45c1822df111a438af4597690de2a27a47ea7d2e Mon Sep 17 00:00:00 2001 From: Xavier de Gaye Date: Thu, 14 Dec 2017 12:40:27 +0100 Subject: [PATCH 12/12] Fix the tests for Android --- Lib/test/test_c_locale_coercion.py | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_c_locale_coercion.py b/Lib/test/test_c_locale_coercion.py index b47adcd6ae922c..11eec912504e81 100644 --- a/Lib/test/test_c_locale_coercion.py +++ b/Lib/test/test_c_locale_coercion.py @@ -27,10 +27,16 @@ # Apply some platform dependent overrides if sys.platform.startswith("linux"): - # Linux distros typically alias the POSIX locale directly to the C locale - # TODO: Once https://bugs.python.org/issue30672 is addressed, we'll be - # able to check this case unconditionally - EXPECTED_C_LOCALE_EQUIVALENTS.append("POSIX") + if test.support.is_android: + # Android defaults to using UTF-8 for all system interfaces + EXPECTED_C_LOCALE_STREAM_ENCODING = "utf-8" + EXPECTED_C_LOCALE_FS_ENCODING = "utf-8" + else: + # Linux distros typically alias the POSIX locale directly to the C + # locale. + # TODO: Once https://bugs.python.org/issue30672 is addressed, we'll be + # able to check this case unconditionally + EXPECTED_C_LOCALE_EQUIVALENTS.append("POSIX") elif sys.platform.startswith("aix"): # AIX uses iso8859-1 in the C locale, other *nix platforms use ASCII EXPECTED_C_LOCALE_STREAM_ENCODING = "iso8859-1" @@ -43,11 +49,6 @@ # TODO: Work out a robust dynamic test for this that doesn't rely on # CPython's own locale handling machinery EXPECT_COERCION_IN_DEFAULT_LOCALE = False -elif test.support.is_android: - # Android defaults to using UTF-8 for all system interfaces - EXPECTED_C_LOCALE_STREAM_ENCODING = "utf-8" - EXPECTED_C_LOCALE_FS_ENCODING = "utf-8" - EXPECT_COERCION_IN_DEFAULT_LOCALE = False # Note that the above expectations are still wrong in some cases, such as: # * Windows when PYTHONLEGACYWINDOWSFSENCODING is set @@ -329,6 +330,13 @@ def _check_c_locale_coercion(self, else: _expected_warnings = None _coercion_expected = False + # On Android CLI_COERCION_WARNING is not printed when all the + # locale environment variables are undefined or empty. When + # this code path is run with environ['LC_ALL'] == 'C', then + # LEGACY_LOCALE_WARNING is printed. + if (test.support.is_android and + _expected_warnings == [CLI_COERCION_WARNING]): + _expected_warnings = None self._check_child_encoding_details(base_var_dict, fs_encoding, stream_encoding,