34
34
from coverage .types import TArc
35
35
36
36
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 ]:
38
51
"""Run a command in a subprocess.
39
52
40
- Returns the exit status code and the combined stdout and stderr .
53
+ Returns the Popen object .
41
54
42
55
"""
43
56
# Subprocesses are expensive, but convenient, and so may be over-used in
@@ -47,20 +60,11 @@ def run_command(cmd: str) -> tuple[int, str]:
47
60
with open (pth , "a" , encoding = "utf-8" ) as proctxt :
48
61
print (os .getenv ("PYTEST_CURRENT_TEST" , "unknown" ), file = proctxt , flush = True )
49
62
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
-
59
63
# In some strange cases (PyPy3 in a virtualenv!?) the stdout encoding of
60
64
# the subprocess is set incorrectly to ascii. Use an environment variable
61
65
# to force the encoding to be the same as ours.
62
66
sub_env = dict (os .environ )
63
- sub_env [' PYTHONIOENCODING' ] = encoding
67
+ sub_env [" PYTHONIOENCODING" ] = _correct_encoding ()
64
68
65
69
proc = subprocess .Popen (
66
70
cmd ,
@@ -70,11 +74,21 @@ def run_command(cmd: str) -> tuple[int, str]:
70
74
stdout = subprocess .PIPE ,
71
75
stderr = subprocess .STDOUT ,
72
76
)
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 )
73
87
output , _ = proc .communicate ()
74
88
status = proc .returncode
75
89
76
90
# 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 " , "" )
78
92
return status , output_str
79
93
80
94
0 commit comments