Skip to content

Commit ad97d93

Browse files
ronaldoussorenmcepl
authored andcommitted
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.
1 parent 6616512 commit ad97d93

File tree

1 file changed

+79
-12
lines changed

1 file changed

+79
-12
lines changed

Lib/test/test_c_locale_coercion.py

Lines changed: 79 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,16 @@ class EncodingDetails(_EncodingDetails):
8585
])
8686

8787
@classmethod
88-
def get_expected_details(cls, coercion_expected, fs_encoding, stream_encoding, env_vars):
88+
def get_expected_details(cls, coercion_expected, fs_encoding, stream_encoding, stream_errors, env_vars):
8989
"""Returns expected child process details for a given encoding"""
9090
_stream = stream_encoding + ":{}"
91-
# stdin and stdout should use surrogateescape either because the
92-
# coercion triggered, or because the C locale was detected
93-
stream_info = 2*[_stream.format("surrogateescape")]
91+
if stream_errors is None:
92+
# stdin and stdout should use surrogateescape either because the
93+
# coercion triggered, or because the C locale was detected
94+
stream_errors = "surrogateescape"
95+
96+
stream_info = [_stream.format(stream_errors)] * 2
97+
9498
# stderr should always use backslashreplace
9599
stream_info.append(_stream.format("backslashreplace"))
96100
expected_lang = env_vars.get("LANG", "not set").lower()
@@ -189,6 +193,7 @@ def _check_child_encoding_details(self,
189193
env_vars,
190194
expected_fs_encoding,
191195
expected_stream_encoding,
196+
expected_stream_errors,
192197
expected_warnings,
193198
coercion_expected):
194199
"""Check the C locale handling for the given process environment
@@ -204,6 +209,7 @@ def _check_child_encoding_details(self,
204209
coercion_expected,
205210
expected_fs_encoding,
206211
expected_stream_encoding,
212+
expected_stream_errors,
207213
env_vars
208214
)
209215
self.assertEqual(encoding_details, expected_details)
@@ -234,6 +240,8 @@ def test_external_target_locale_configuration(self):
234240
"LANG": "",
235241
"LC_CTYPE": "",
236242
"LC_ALL": "",
243+
"PYTHONCOERCECLOCALE": "",
244+
"PYTHONIOENCODING": "",
237245
}
238246
for env_var in ("LANG", "LC_CTYPE"):
239247
for locale_to_set in AVAILABLE_TARGETS:
@@ -250,10 +258,43 @@ def test_external_target_locale_configuration(self):
250258
self._check_child_encoding_details(var_dict,
251259
expected_fs_encoding,
252260
expected_stream_encoding,
261+
expected_stream_errors=None,
253262
expected_warnings=None,
254263
coercion_expected=False)
255264

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

270+
expected_fs_encoding = "utf-8"
271+
expected_stream_encoding = "utf-8"
272+
273+
base_var_dict = {
274+
"LANG": "",
275+
"LC_CTYPE": "",
276+
"LC_ALL": "",
277+
"PYTHONCOERCECLOCALE": "",
278+
"PYTHONIOENCODING": "UTF-8",
279+
}
280+
for env_var in ("LANG", "LC_CTYPE"):
281+
for locale_to_set in AVAILABLE_TARGETS:
282+
# XXX (ncoghlan): LANG=UTF-8 doesn't appear to work as
283+
# expected, so skip that combination for now
284+
# See https://bugs.python.org/issue30672 for discussion
285+
if env_var == "LANG" and locale_to_set == "UTF-8":
286+
continue
287+
288+
with self.subTest(env_var=env_var,
289+
configured_locale=locale_to_set):
290+
var_dict = base_var_dict.copy()
291+
var_dict[env_var] = locale_to_set
292+
self._check_child_encoding_details(var_dict,
293+
expected_fs_encoding,
294+
expected_stream_encoding,
295+
expected_stream_errors="strict",
296+
expected_warnings=None,
297+
coercion_expected=False)
257298

258299
@test.support.cpython_only
259300
@unittest.skipUnless(sysconfig.get_config_var("PY_COERCE_C_LOCALE"),
@@ -292,18 +333,43 @@ def _check_c_locale_coercion(self,
292333
"LANG": "",
293334
"LC_CTYPE": "",
294335
"LC_ALL": "",
336+
"PYTHONCOERCECLOCALE": "",
337+
"PYTHONIOENCODING": "",
295338
}
296339
base_var_dict.update(extra_vars)
297-
for env_var in ("LANG", "LC_CTYPE"):
298-
for locale_to_set in ("", "C", "POSIX", "invalid.ascii"):
299-
# XXX (ncoghlan): *BSD platforms don't behave as expected in the
300-
# POSIX locale, so we skip that for now
301-
# See https://bugs.python.org/issue30672 for discussion
302-
if locale_to_set == "POSIX":
303-
continue
340+
if coerce_c_locale is not None:
341+
base_var_dict["PYTHONCOERCECLOCALE"] = coerce_c_locale
342+
343+
# Check behaviour for the default locale
344+
with self.subTest(default_locale=True,
345+
PYTHONCOERCECLOCALE=coerce_c_locale):
346+
if EXPECT_COERCION_IN_DEFAULT_LOCALE:
347+
_expected_warnings = expected_warnings
348+
_coercion_expected = coercion_expected
349+
else:
350+
_expected_warnings = None
351+
_coercion_expected = False
352+
# On Android CLI_COERCION_WARNING is not printed when all the
353+
# locale environment variables are undefined or empty. When
354+
# this code path is run with environ['LC_ALL'] == 'C', then
355+
# LEGACY_LOCALE_WARNING is printed.
356+
if (support.is_android and
357+
_expected_warnings == [CLI_COERCION_WARNING]):
358+
_expected_warnings = None
359+
self._check_child_encoding_details(base_var_dict,
360+
fs_encoding,
361+
stream_encoding,
362+
None,
363+
_expected_warnings,
364+
_coercion_expected)
365+
366+
# Check behaviour for explicitly configured locales
367+
for locale_to_set in EXPECTED_C_LOCALE_EQUIVALENTS:
368+
for env_var in ("LANG", "LC_CTYPE"):
304369
with self.subTest(env_var=env_var,
305370
nominal_locale=locale_to_set,
306-
PYTHONCOERCECLOCALE=coerce_c_locale):
371+
PYTHONCOERCECLOCALE=coerce_c_locale,
372+
PYTHONIOENCODING=""):
307373
var_dict = base_var_dict.copy()
308374
var_dict[env_var] = locale_to_set
309375
if coerce_c_locale is not None:
@@ -312,6 +378,7 @@ def _check_c_locale_coercion(self,
312378
self._check_child_encoding_details(var_dict,
313379
fs_encoding,
314380
stream_encoding,
381+
None,
315382
expected_warnings,
316383
coercion_expected)
317384

0 commit comments

Comments
 (0)