Skip to content

Commit 5f665e9

Browse files
gh-109989: Fix test_c_locale_coercion when PYTHONIOENCODING is set (#113378)
* gh-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]>
1 parent bee627c commit 5f665e9

File tree

1 file changed

+49
-5
lines changed

1 file changed

+49
-5
lines changed

Lib/test/test_c_locale_coercion.py

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,16 @@ class EncodingDetails(_EncodingDetails):
112112
])
113113

114114
@classmethod
115-
def get_expected_details(cls, coercion_expected, fs_encoding, stream_encoding, env_vars):
115+
def get_expected_details(cls, coercion_expected, fs_encoding, stream_encoding, stream_errors, env_vars):
116116
"""Returns expected child process details for a given encoding"""
117117
_stream = stream_encoding + ":{}"
118-
# stdin and stdout should use surrogateescape either because the
119-
# coercion triggered, or because the C locale was detected
120-
stream_info = 2*[_stream.format("surrogateescape")]
118+
if stream_errors is None:
119+
# stdin and stdout should use surrogateescape either because the
120+
# coercion triggered, or because the C locale was detected
121+
stream_errors = "surrogateescape"
122+
123+
stream_info = [_stream.format(stream_errors)] * 2
124+
121125
# stderr should always use backslashreplace
122126
stream_info.append(_stream.format("backslashreplace"))
123127
expected_lang = env_vars.get("LANG", "not set")
@@ -210,6 +214,7 @@ def _check_child_encoding_details(self,
210214
env_vars,
211215
expected_fs_encoding,
212216
expected_stream_encoding,
217+
expected_stream_errors,
213218
expected_warnings,
214219
coercion_expected):
215220
"""Check the C locale handling for the given process environment
@@ -225,6 +230,7 @@ def _check_child_encoding_details(self,
225230
coercion_expected,
226231
expected_fs_encoding,
227232
expected_stream_encoding,
233+
expected_stream_errors,
228234
env_vars
229235
)
230236
self.assertEqual(encoding_details, expected_details)
@@ -257,6 +263,7 @@ def test_external_target_locale_configuration(self):
257263
"LC_CTYPE": "",
258264
"LC_ALL": "",
259265
"PYTHONCOERCECLOCALE": "",
266+
"PYTHONIOENCODING": "",
260267
}
261268
for env_var in ("LANG", "LC_CTYPE"):
262269
for locale_to_set in AVAILABLE_TARGETS:
@@ -273,10 +280,43 @@ def test_external_target_locale_configuration(self):
273280
self._check_child_encoding_details(var_dict,
274281
expected_fs_encoding,
275282
expected_stream_encoding,
283+
expected_stream_errors=None,
276284
expected_warnings=None,
277285
coercion_expected=False)
278286

287+
def test_with_ioencoding(self):
288+
# Explicitly setting a target locale should give the same behaviour as
289+
# is seen when implicitly coercing to that target locale
290+
self.maxDiff = None
291+
292+
expected_fs_encoding = "utf-8"
293+
expected_stream_encoding = "utf-8"
279294

295+
base_var_dict = {
296+
"LANG": "",
297+
"LC_CTYPE": "",
298+
"LC_ALL": "",
299+
"PYTHONCOERCECLOCALE": "",
300+
"PYTHONIOENCODING": "UTF-8",
301+
}
302+
for env_var in ("LANG", "LC_CTYPE"):
303+
for locale_to_set in AVAILABLE_TARGETS:
304+
# XXX (ncoghlan): LANG=UTF-8 doesn't appear to work as
305+
# expected, so skip that combination for now
306+
# See https://bugs.python.org/issue30672 for discussion
307+
if env_var == "LANG" and locale_to_set == "UTF-8":
308+
continue
309+
310+
with self.subTest(env_var=env_var,
311+
configured_locale=locale_to_set):
312+
var_dict = base_var_dict.copy()
313+
var_dict[env_var] = locale_to_set
314+
self._check_child_encoding_details(var_dict,
315+
expected_fs_encoding,
316+
expected_stream_encoding,
317+
expected_stream_errors="strict",
318+
expected_warnings=None,
319+
coercion_expected=False)
280320

281321
@support.cpython_only
282322
@unittest.skipUnless(sysconfig.get_config_var("PY_COERCE_C_LOCALE"),
@@ -316,6 +356,7 @@ def _check_c_locale_coercion(self,
316356
"LC_CTYPE": "",
317357
"LC_ALL": "",
318358
"PYTHONCOERCECLOCALE": "",
359+
"PYTHONIOENCODING": "",
319360
}
320361
base_var_dict.update(extra_vars)
321362
if coerce_c_locale is not None:
@@ -340,6 +381,7 @@ def _check_c_locale_coercion(self,
340381
self._check_child_encoding_details(base_var_dict,
341382
fs_encoding,
342383
stream_encoding,
384+
None,
343385
_expected_warnings,
344386
_coercion_expected)
345387

@@ -348,13 +390,15 @@ def _check_c_locale_coercion(self,
348390
for env_var in ("LANG", "LC_CTYPE"):
349391
with self.subTest(env_var=env_var,
350392
nominal_locale=locale_to_set,
351-
PYTHONCOERCECLOCALE=coerce_c_locale):
393+
PYTHONCOERCECLOCALE=coerce_c_locale,
394+
PYTHONIOENCODING=""):
352395
var_dict = base_var_dict.copy()
353396
var_dict[env_var] = locale_to_set
354397
# Check behaviour on successful coercion
355398
self._check_child_encoding_details(var_dict,
356399
fs_encoding,
357400
stream_encoding,
401+
None,
358402
expected_warnings,
359403
coercion_expected)
360404

0 commit comments

Comments
 (0)