@@ -62,8 +62,8 @@ def stat_proxy(path: str) -> os.stat_result:
62
62
def main (
63
63
* ,
64
64
args : list [str ] | None = None ,
65
- stdout : TextIO = sys . stdout ,
66
- stderr : TextIO = sys . stderr ,
65
+ stdout : TextIO | None = None ,
66
+ stderr : TextIO | None = None ,
67
67
clean_exit : bool = False ,
68
68
) -> None :
69
69
"""Main entry point to the type checker.
@@ -74,6 +74,15 @@ def main(
74
74
clean_exit: Don't hard kill the process on exit. This allows catching
75
75
SystemExit.
76
76
"""
77
+ # As a common pattern around the codebase, we tend to do this instead of
78
+ # using default arguments that are mutable objects (due to Python's
79
+ # famously counterintuitive behavior about those): use a sentinel, then
80
+ # set.
81
+ stdout = stdout if stdout is not None else sys .stdout
82
+ stderr = stderr if stderr is not None else sys .stderr
83
+ # sys.stdout and sys.stderr might technically be None, but this fact isn't
84
+ # currently enforced by the stubs (they are marked as MaybeNone (=Any)).
85
+
77
86
util .check_python_version ("mypy" )
78
87
t0 = time .time ()
79
88
# To log stat() calls: os.stat = stat_proxy
@@ -150,11 +159,10 @@ def main(
150
159
summary = formatter .format_error (
151
160
n_errors , n_files , len (sources ), blockers = blockers , use_color = options .color_output
152
161
)
153
- stdout . write (summary + " \n " )
162
+ print (summary , file = stdout , flush = True )
154
163
# Only notes should also output success
155
164
elif not messages or n_notes == len (messages ):
156
- stdout .write (formatter .format_success (len (sources ), options .color_output ) + "\n " )
157
- stdout .flush ()
165
+ print (formatter .format_success (len (sources ), options .color_output ), file = stdout , flush = True )
158
166
159
167
if options .install_types and not options .non_interactive :
160
168
result = install_types (formatter , options , after_run = True , non_interactive = False )
@@ -180,13 +188,14 @@ def run_build(
180
188
options : Options ,
181
189
fscache : FileSystemCache ,
182
190
t0 : float ,
183
- stdout : TextIO ,
184
- stderr : TextIO ,
191
+ stdout : TextIO | None = None ,
192
+ stderr : TextIO | None = None ,
185
193
) -> tuple [build .BuildResult | None , list [str ], bool ]:
186
194
formatter = util .FancyFormatter (
187
195
stdout , stderr , options .hide_error_codes , hide_success = bool (options .output )
188
196
)
189
-
197
+ stdout = stdout if stdout is not None else sys .stdout
198
+ stderr = stderr if stderr is not None else sys .stderr
190
199
messages = []
191
200
messages_by_file = defaultdict (list )
192
201
@@ -238,14 +247,12 @@ def flush_errors(filename: str | None, new_messages: list[str], serious: bool) -
238
247
239
248
240
249
def show_messages (
241
- messages : list [str ], f : TextIO , formatter : util .FancyFormatter , options : Options
250
+ messages : list [str ], f : TextIO | None , formatter : util .FancyFormatter , options : Options
242
251
) -> None :
243
252
for msg in messages :
244
253
if options .color_output :
245
254
msg = formatter .colorize (msg )
246
- f .write (msg + "\n " )
247
- f .flush ()
248
-
255
+ print (msg , file = f , flush = True )
249
256
250
257
# Make the help output a little less jarring.
251
258
class AugmentedHelpFormatter (argparse .RawDescriptionHelpFormatter ):
@@ -399,7 +406,7 @@ def _print_message(self, message: str, file: SupportsWrite[str] | None = None) -
399
406
if message :
400
407
if file is None :
401
408
file = self .stderr
402
- file . write (message )
409
+ print (message , file = file )
403
410
404
411
# ===============
405
412
# Exiting methods
@@ -465,8 +472,8 @@ def __call__(
465
472
def define_options (
466
473
program : str = "mypy" ,
467
474
header : str = HEADER ,
468
- stdout : TextIO | None ,
469
- stderr : TextIO | None ,
475
+ stdout : TextIO | None = None ,
476
+ stderr : TextIO | None = None ,
470
477
server_options : bool = False ,
471
478
) -> tuple [CapturableArgumentParser , list [str ], list [tuple [str , bool ]]]:
472
479
"""Define the options in the parser (by calling a bunch of methods that express/build our desired command-line flags).
0 commit comments