From e991645c461f1565ab478a3d84cf9d66ae143270 Mon Sep 17 00:00:00 2001 From: Rujul Talekar <113801876+Roojool@users.noreply.github.com> Date: Mon, 12 Oct 2026 12:56:25 +0530 Subject: [PATCH] fix(tools): simulate cp1252 default encoding on Python 3.10 in pr_overlap tests command_output patched subprocess._text_encoding, which does not exist on Python 3.10, so all eight tests errored before their assertions. Use subprocess._text_encoding where available and map io.TextIOWrapper locale to cp1252 on older interpreters, so a subprocess with no explicit encoding decodes as cp1252 on both. Add a behavioral check that default decodes as cp1252 while explicit utf-8 stays correct. Authored by Rujul Talekar, with Muse Spark 1.3 assistance. --- tools/tests/test_pr_overlap_encoding.py | 28 ++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/tools/tests/test_pr_overlap_encoding.py b/tools/tests/test_pr_overlap_encoding.py index 2d2b92c42..73082080d 100644 --- a/tools/tests/test_pr_overlap_encoding.py +++ b/tools/tests/test_pr_overlap_encoding.py @@ -1,4 +1,5 @@ from contextlib import contextmanager +import io import json import os from pathlib import Path @@ -16,6 +17,23 @@ UNICODE = "Quoted \u201cmetadata\u201d, Y\u014dtei and \U0001f3ae" TREE = "a" * 40 +@contextmanager +def simulated_cp1252(): + if hasattr(subprocess, "_text_encoding"): + with patch.object(subprocess, "_text_encoding", return_value="cp1252"): + yield + else: + wrapper = io.TextIOWrapper + + def fake_wrapper(buffer, encoding=None, *args, **kwargs): + if encoding == "locale": + encoding = "cp1252" + return wrapper(buffer, encoding=encoding, *args, **kwargs) + + with patch.object(io, "TextIOWrapper", new=fake_wrapper): + yield + + @contextmanager def command_output(stdout, stderr="", returncode=0): code = ("import os, sys\n" @@ -26,7 +44,7 @@ def command_output(stdout, stderr="", returncode=0): def run(command, **kwargs): return RUN([sys.executable, "-c", code], **kwargs) - with patch.object(subprocess, "_text_encoding", return_value="cp1252"), \ + with simulated_cp1252(), \ patch.object(subprocess, "run", side_effect=run): yield @@ -75,6 +93,14 @@ class EncodingTests(unittest.TestCase): with self.assertRaisesRegex(RuntimeError, UNICODE): pr_overlap.merge("main", "topic") + def test_default_encoding_uses_simulated_cp1252(self): + code = "import os;os.write(1," + repr(UNICODE.encode("utf-8")) + ")" + with simulated_cp1252(): + default = RUN([sys.executable, "-c", code], capture_output=True, text=True, errors="replace") + self.assertEqual(default.stdout, UNICODE.encode("utf-8").decode("cp1252", errors="replace")) + explicit = RUN([sys.executable, "-c", code], capture_output=True, text=True, encoding="utf-8") + self.assertEqual(explicit.stdout, UNICODE) + def test_git_diff_survives_invalid_utf8(self): with TemporaryDirectory() as directory: repo = Path(directory)