From 842076d3b91e7f0d193485eb5227e3a7a2f6b01d Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 11 May 2025 10:05:36 +0300 Subject: [PATCH 1/2] gh-133677: Fix tests when running in non-UTF-8 locale --- Lib/test/support/strace_helper.py | 2 +- Lib/test/test_argparse.py | 4 ++-- Lib/test/test_asyncio/test_tools.py | 8 ++++---- Lib/test/test_pathlib/test_pathlib.py | 12 ++++++++---- Lib/test/test_urllib.py | 2 +- Lib/test/test_zipfile/test_core.py | 2 +- 6 files changed, 17 insertions(+), 13 deletions(-) diff --git a/Lib/test/support/strace_helper.py b/Lib/test/support/strace_helper.py index 1a9d2b520b7b23..cf95f7bdc7d2ca 100644 --- a/Lib/test/support/strace_helper.py +++ b/Lib/test/support/strace_helper.py @@ -38,7 +38,7 @@ def events(self): This assumes the program under inspection doesn't print any non-utf8 strings which would mix into the strace output.""" - decoded_events = self.event_bytes.decode('utf-8') + decoded_events = self.event_bytes.decode('utf-8', 'surrogateescape') matches = [ _syscall_regex.match(event) for event in decoded_events.splitlines() diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 5a6be1180c1a3e..8a7b61cc52a2db 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -6972,8 +6972,8 @@ def make_zip_script(self, script_name, name_in_zip=None): return zip_name def check_usage(self, expected, *args, **kwargs): - res = script_helper.assert_python_ok('-Xutf8', *args, '-h', **kwargs) - self.assertEqual(res.out.splitlines()[0].decode(), + res = script_helper.assert_python_ok(*args, '-h', **kwargs) + self.assertEqual(os.fsdecode(res.out.splitlines()[0]), f'usage: {expected} [-h]') def test_script(self, compiled=False): diff --git a/Lib/test/test_asyncio/test_tools.py b/Lib/test/test_asyncio/test_tools.py index 0413e236c27dfa..ba36e759ccdd61 100644 --- a/Lib/test/test_asyncio/test_tools.py +++ b/Lib/test/test_asyncio/test_tools.py @@ -791,21 +791,21 @@ def test_table_output_format(self): class TestAsyncioToolsEdgeCases(unittest.TestCase): def test_task_awaits_self(self): - """A task directly awaits itself – should raise a cycle.""" + """A task directly awaits itself - should raise a cycle.""" input_ = [(1, [(1, "Self-Awaiter", [[["loopback"], 1]])])] with self.assertRaises(tools.CycleFoundException) as ctx: tools.build_async_tree(input_) self.assertIn([1, 1], ctx.exception.cycles) def test_task_with_missing_awaiter_id(self): - """Awaiter ID not in task list – should not crash, just show 'Unknown'.""" + """Awaiter ID not in task list - should not crash, just show 'Unknown'.""" input_ = [(1, [(1, "Task-A", [[["coro"], 999]])])] # 999 not defined table = tools.build_task_table(input_) self.assertEqual(len(table), 1) self.assertEqual(table[0][4], "Unknown") def test_duplicate_coroutine_frames(self): - """Same coroutine frame repeated under a parent – should deduplicate.""" + """Same coroutine frame repeated under a parent - should deduplicate.""" input_ = [ ( 1, @@ -829,7 +829,7 @@ def test_duplicate_coroutine_frames(self): self.assertIn("Task-1", flat) def test_task_with_no_name(self): - """Task with no name in id2name – should still render with fallback.""" + """Task with no name in id2name - should still render with fallback.""" input_ = [(1, [(1, "root", [[["f1"], 2]]), (2, None, [])])] # If name is None, fallback to string should not crash tree = tools.build_async_tree(input_) diff --git a/Lib/test/test_pathlib/test_pathlib.py b/Lib/test/test_pathlib/test_pathlib.py index 8a313cc4292574..37ef9fa1946376 100644 --- a/Lib/test/test_pathlib/test_pathlib.py +++ b/Lib/test/test_pathlib/test_pathlib.py @@ -20,7 +20,7 @@ from test.support import is_emscripten, is_wasi from test.support import infinite_recursion from test.support import os_helper -from test.support.os_helper import TESTFN, FakePath +from test.support.os_helper import TESTFN, FS_NONASCII, FakePath try: import fcntl except ImportError: @@ -770,12 +770,16 @@ def test_as_uri_windows(self): self.assertEqual(self.make_uri(P('c:/')), 'file:///c:/') self.assertEqual(self.make_uri(P('c:/a/b.c')), 'file:///c:/a/b.c') self.assertEqual(self.make_uri(P('c:/a/b%#c')), 'file:///c:/a/b%25%23c') - self.assertEqual(self.make_uri(P('c:/a/b\xe9')), 'file:///c:/a/b%C3%A9') self.assertEqual(self.make_uri(P('//some/share/')), 'file://some/share/') self.assertEqual(self.make_uri(P('//some/share/a/b.c')), 'file://some/share/a/b.c') - self.assertEqual(self.make_uri(P('//some/share/a/b%#c\xe9')), - 'file://some/share/a/b%25%23c%C3%A9') + + from urllib.parse import quote_from_bytes + QUOTED_FS_NONASCII = quote_from_bytes(os.fsencode(FS_NONASCII)) + self.assertEqual(self.make_uri(P('c:/a/b' + FS_NONASCII)), + 'file:///c:/a/b' + QUOTED_FS_NONASCII) + self.assertEqual(self.make_uri(P('//some/share/a/b%#c' + FS_NONASCII)), + 'file://some/share/a/b%25%23c' + QUOTED_FS_NONASCII) @needs_windows def test_ordering_windows(self): diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py index c965860fbb10ef..bc1030eea60c35 100644 --- a/Lib/test/test_urllib.py +++ b/Lib/test/test_urllib.py @@ -109,7 +109,7 @@ def setUp(self): finally: f.close() self.pathname = os_helper.TESTFN - self.quoted_pathname = urllib.parse.quote(self.pathname) + self.quoted_pathname = urllib.parse.quote(os.fsencode(self.pathname)) self.returned_obj = urllib.request.urlopen("file:%s" % self.quoted_pathname) def tearDown(self): diff --git a/Lib/test/test_zipfile/test_core.py b/Lib/test/test_zipfile/test_core.py index ae898150658565..43056978848c03 100644 --- a/Lib/test/test_zipfile/test_core.py +++ b/Lib/test/test_zipfile/test_core.py @@ -3642,7 +3642,7 @@ def test_cli_with_metadata_encoding_extract(self): except OSError: pass except UnicodeEncodeError: - self.skipTest(f'cannot encode file name {fn!r}') + self.skipTest(f'cannot encode file name {fn!a}') zipfile.main(["--metadata-encoding=shift_jis", "-e", TESTFN, TESTFN2]) listing = os.listdir(TESTFN2) From 68d3b2447abb4dc3ba653f9c37762a25961ef441 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 11 May 2025 11:47:09 +0300 Subject: [PATCH 2/2] Try to fix test_argparse on Windows. --- Lib/test/test_argparse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 8a7b61cc52a2db..8a264b101bc3ba 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -6972,7 +6972,7 @@ def make_zip_script(self, script_name, name_in_zip=None): return zip_name def check_usage(self, expected, *args, **kwargs): - res = script_helper.assert_python_ok(*args, '-h', **kwargs) + res = script_helper.assert_python_ok('-Xutf8', *args, '-h', **kwargs) self.assertEqual(os.fsdecode(res.out.splitlines()[0]), f'usage: {expected} [-h]')