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.
This commit is contained in:
Rujul Talekar 2026-10-12 12:56:25 +05:30
parent 436e310ddb
commit e991645c46
1 changed files with 27 additions and 1 deletions

View File

@ -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)