Skip to content

Commit bbc3174

Browse files
committed
refactor: a helper for getting Popen subprocesses
1 parent d2a16d5 commit bbc3174

File tree

1 file changed

+27
-13
lines changed

1 file changed

+27
-13
lines changed

tests/helpers.py

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,23 @@
3434
from coverage.types import TArc
3535

3636

37-
def run_command(cmd: str) -> tuple[int, str]:
37+
def _correct_encoding() -> str:
38+
"""Determine the right encoding to use for subprocesses."""
39+
# Type checking trick due to "unreachable" being set
40+
_locale_type_erased: Any = locale
41+
42+
encoding = os.device_encoding(1) or (
43+
_locale_type_erased.getpreferredencoding()
44+
if sys.version_info < (3, 11)
45+
else _locale_type_erased.getencoding()
46+
)
47+
return encoding
48+
49+
50+
def subprocess_popen(cmd: str) -> subprocess.Popen[bytes]:
3851
"""Run a command in a subprocess.
3952
40-
Returns the exit status code and the combined stdout and stderr.
53+
Returns the Popen object.
4154
4255
"""
4356
# Subprocesses are expensive, but convenient, and so may be over-used in
@@ -47,20 +60,11 @@ def run_command(cmd: str) -> tuple[int, str]:
4760
with open(pth, "a", encoding="utf-8") as proctxt:
4861
print(os.getenv("PYTEST_CURRENT_TEST", "unknown"), file=proctxt, flush=True)
4962

50-
# Type checking trick due to "unreachable" being set
51-
_locale_type_erased: Any = locale
52-
53-
encoding = os.device_encoding(1) or (
54-
_locale_type_erased.getpreferredencoding()
55-
if sys.version_info < (3, 11)
56-
else _locale_type_erased.getencoding()
57-
)
58-
5963
# In some strange cases (PyPy3 in a virtualenv!?) the stdout encoding of
6064
# the subprocess is set incorrectly to ascii. Use an environment variable
6165
# to force the encoding to be the same as ours.
6266
sub_env = dict(os.environ)
63-
sub_env['PYTHONIOENCODING'] = encoding
67+
sub_env["PYTHONIOENCODING"] = _correct_encoding()
6468

6569
proc = subprocess.Popen(
6670
cmd,
@@ -70,11 +74,21 @@ def run_command(cmd: str) -> tuple[int, str]:
7074
stdout=subprocess.PIPE,
7175
stderr=subprocess.STDOUT,
7276
)
77+
return proc
78+
79+
80+
def run_command(cmd: str) -> tuple[int, str]:
81+
"""Run a command in a subprocess.
82+
83+
Returns the exit status code and the combined stdout and stderr.
84+
85+
"""
86+
proc = subprocess_popen(cmd)
7387
output, _ = proc.communicate()
7488
status = proc.returncode
7589

7690
# Get the output, and canonicalize it to strings with newlines.
77-
output_str = output.decode(encoding).replace("\r", "")
91+
output_str = output.decode(_correct_encoding()).replace("\r", "")
7892
return status, output_str
7993

8094

0 commit comments

Comments
 (0)