Skip to content

Commit 0c03690

Browse files
authored
Make mypy.api.run_dmypy actually capture the output (#8375)
When the main run API was made threadsafe this broke output capturing from run_dmypy. I don't really care about the threadsafety of run_dmypy but I do care about output capture ever working, so I am restoring the old sys.stdout swapping behavior for run_dmypy. I'd take a patch to thread stdout through the client if anybody really cares.
1 parent 5887d38 commit 0c03690

File tree

1 file changed

+21
-2
lines changed

1 file changed

+21
-2
lines changed

mypy/api.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
Any pretty formatting is left to the caller.
1919
2020
The 'run_dmypy' function is similar, but instead mimics invocation of
21-
dmypy.
21+
dmypy. Note that run_dmypy is not thread-safe and modifies sys.stdout
22+
and sys.stderr during its invocation.
2223
2324
Note that these APIs don't support incremental generation of error
2425
messages.
@@ -42,6 +43,8 @@
4243
4344
"""
4445

46+
import sys
47+
4548
from io import StringIO
4649
from typing import List, Tuple, TextIO, Callable
4750

@@ -69,4 +72,20 @@ def run(args: List[str]) -> Tuple[str, str, int]:
6972

7073
def run_dmypy(args: List[str]) -> Tuple[str, str, int]:
7174
from mypy.dmypy.client import main
72-
return _run(lambda stdout, stderr: main(args))
75+
76+
# A bunch of effort has been put into threading stdout and stderr
77+
# through the main API to avoid the threadsafety problems of
78+
# modifying sys.stdout/sys.stderr, but that hasn't been done for
79+
# the dmypy client, so we just do the non-threadsafe thing.
80+
def f(stdout: TextIO, stderr: TextIO) -> None:
81+
old_stdout = sys.stdout
82+
old_stderr = sys.stderr
83+
try:
84+
sys.stdout = stdout
85+
sys.stderr = stderr
86+
main(args)
87+
finally:
88+
sys.stdout = old_stdout
89+
sys.stderr = old_stderr
90+
91+
return _run(f)

0 commit comments

Comments
 (0)