]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-154582: Fix test_invalid_utf8_arg in non-UTF-8 multibyte locales (GH-154584)
authorSerhiy Storchaka <storchaka@gmail.com>
Fri, 24 Jul 2026 12:22:45 +0000 (15:22 +0300)
committerGitHub <noreply@github.com>
Fri, 24 Jul 2026 12:22:45 +0000 (15:22 +0300)
Arbitrary bytes round-trip through surrogateescape only in UTF-8 and
single-byte encodings, not in a stateful multibyte encoding such as EUC-JP.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Lib/test/test_cmd_line.py

index 7640e50f19b7839c4c0b7c7df8ef76157ea1c46f..25d6d1a248b45774bb58602b99001903f6313fa6 100644 (file)
@@ -2,6 +2,7 @@
 # Most tests are executed with environment variables ignored
 # See test_cmd_line_script.py for testing of script execution
 
+import locale
 import os
 import re
 import subprocess
@@ -369,9 +370,27 @@ class CmdLineTest(unittest.TestCase):
         )
         test_args = [valid_utf8, invalid_utf8]
 
-        for run_cmd in (run_default, run_c_locale, run_utf8_mode,
-                        run_no_utf8_mode):
-            with self.subTest(run_cmd=run_cmd):
+        for run_cmd, encoding in (
+            (run_default, sys.getfilesystemencoding()),
+            (run_c_locale, None),
+            (run_utf8_mode, None),
+            (run_no_utf8_mode, locale.getencoding())
+        ):
+            with self.subTest(run_cmd=run_cmd.__name__):
+                # Arbitrary bytes round-trip through surrogateescape only in
+                # UTF-8 and single-byte encodings, not in a multibyte encoding
+                # such as EUC-JP.
+                if encoding is not None:
+                    try:
+                        lossless = len(bytes(range(256)).decode(
+                            encoding, 'surrogateescape')) == 256
+                    except UnicodeError:
+                        lossless = False
+                else:
+                    lossless = True
+                if not lossless:
+                    self.skipTest(f'{encoding} cannot losslessly '
+                                  f'round-trip arbitrary bytes')
                 for arg in test_args:
                     proc = run_cmd(arg)
                     self.assertEqual(proc.stdout.rstrip(), ascii(arg))