Skip to content

Commit

Permalink
pythongh-109989: Fix test_c_locale_coercion when PYTHONIOENCODING is …
Browse files Browse the repository at this point in the history
…set (python#113378)

* pythongh-109989: Fix test_c_locale_coercion when PYTHONIOENCODING is set

This fixes the existing tests when PYTHONIOENCODING is
set by unsetting PYTHONIOENCODING.

Also add a test that explicitly checks what happens
when PYTHONIOENCODING is set.

Co-authored-by: Nikita Sobolev <[email protected]>
  • Loading branch information
ronaldoussoren and sobolevn authored Dec 22, 2023
1 parent bee627c commit 5f665e9
Showing 1 changed file with 49 additions and 5 deletions.
54 changes: 49 additions & 5 deletions Lib/test/test_c_locale_coercion.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,16 @@ class EncodingDetails(_EncodingDetails):
])

@classmethod
def get_expected_details(cls, coercion_expected, fs_encoding, stream_encoding, env_vars):
def get_expected_details(cls, coercion_expected, fs_encoding, stream_encoding, stream_errors, env_vars):
"""Returns expected child process details for a given encoding"""
_stream = stream_encoding + ":{}"
# stdin and stdout should use surrogateescape either because the
# coercion triggered, or because the C locale was detected
stream_info = 2*[_stream.format("surrogateescape")]
if stream_errors is None:
# stdin and stdout should use surrogateescape either because the
# coercion triggered, or because the C locale was detected
stream_errors = "surrogateescape"

stream_info = [_stream.format(stream_errors)] * 2

# stderr should always use backslashreplace
stream_info.append(_stream.format("backslashreplace"))
expected_lang = env_vars.get("LANG", "not set")
Expand Down Expand Up @@ -210,6 +214,7 @@ def _check_child_encoding_details(self,
env_vars,
expected_fs_encoding,
expected_stream_encoding,
expected_stream_errors,
expected_warnings,
coercion_expected):
"""Check the C locale handling for the given process environment
Expand All @@ -225,6 +230,7 @@ def _check_child_encoding_details(self,
coercion_expected,
expected_fs_encoding,
expected_stream_encoding,
expected_stream_errors,
env_vars
)
self.assertEqual(encoding_details, expected_details)
Expand Down Expand Up @@ -257,6 +263,7 @@ def test_external_target_locale_configuration(self):
"LC_CTYPE": "",
"LC_ALL": "",
"PYTHONCOERCECLOCALE": "",
"PYTHONIOENCODING": "",
}
for env_var in ("LANG", "LC_CTYPE"):
for locale_to_set in AVAILABLE_TARGETS:
Expand All @@ -273,10 +280,43 @@ def test_external_target_locale_configuration(self):
self._check_child_encoding_details(var_dict,
expected_fs_encoding,
expected_stream_encoding,
expected_stream_errors=None,
expected_warnings=None,
coercion_expected=False)

def test_with_ioencoding(self):
# Explicitly setting a target locale should give the same behaviour as
# is seen when implicitly coercing to that target locale
self.maxDiff = None

expected_fs_encoding = "utf-8"
expected_stream_encoding = "utf-8"

base_var_dict = {
"LANG": "",
"LC_CTYPE": "",
"LC_ALL": "",
"PYTHONCOERCECLOCALE": "",
"PYTHONIOENCODING": "UTF-8",
}
for env_var in ("LANG", "LC_CTYPE"):
for locale_to_set in AVAILABLE_TARGETS:
# XXX (ncoghlan): LANG=UTF-8 doesn't appear to work as
# expected, so skip that combination for now
# See https://bugs.python.org/issue30672 for discussion
if env_var == "LANG" and locale_to_set == "UTF-8":
continue

with self.subTest(env_var=env_var,
configured_locale=locale_to_set):
var_dict = base_var_dict.copy()
var_dict[env_var] = locale_to_set
self._check_child_encoding_details(var_dict,
expected_fs_encoding,
expected_stream_encoding,
expected_stream_errors="strict",
expected_warnings=None,
coercion_expected=False)

@support.cpython_only
@unittest.skipUnless(sysconfig.get_config_var("PY_COERCE_C_LOCALE"),
Expand Down Expand Up @@ -316,6 +356,7 @@ def _check_c_locale_coercion(self,
"LC_CTYPE": "",
"LC_ALL": "",
"PYTHONCOERCECLOCALE": "",
"PYTHONIOENCODING": "",
}
base_var_dict.update(extra_vars)
if coerce_c_locale is not None:
Expand All @@ -340,6 +381,7 @@ def _check_c_locale_coercion(self,
self._check_child_encoding_details(base_var_dict,
fs_encoding,
stream_encoding,
None,
_expected_warnings,
_coercion_expected)

Expand All @@ -348,13 +390,15 @@ def _check_c_locale_coercion(self,
for env_var in ("LANG", "LC_CTYPE"):
with self.subTest(env_var=env_var,
nominal_locale=locale_to_set,
PYTHONCOERCECLOCALE=coerce_c_locale):
PYTHONCOERCECLOCALE=coerce_c_locale,
PYTHONIOENCODING=""):
var_dict = base_var_dict.copy()
var_dict[env_var] = locale_to_set
# Check behaviour on successful coercion
self._check_child_encoding_details(var_dict,
fs_encoding,
stream_encoding,
None,
expected_warnings,
coercion_expected)

Expand Down

0 comments on commit 5f665e9

Please sign in to comment.