@@ -62,8 +62,8 @@ def stat_proxy(path: str) -> os.stat_result:
6262def  main (
6363    * ,
6464    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 ,
6767    clean_exit : bool  =  False ,
6868) ->  None :
6969    """Main entry point to the type checker. 
@@ -74,6 +74,15 @@ def main(
7474        clean_exit: Don't hard kill the process on exit. This allows catching 
7575            SystemExit. 
7676    """ 
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+ 
7786    util .check_python_version ("mypy" )
7887    t0  =  time .time ()
7988    # To log stat() calls: os.stat = stat_proxy 
@@ -150,11 +159,10 @@ def main(
150159            summary  =  formatter .format_error (
151160                n_errors , n_files , len (sources ), blockers = blockers , use_color = options .color_output 
152161            )
153-             stdout . write (summary   +   " \n "  )
162+             print (summary ,  file = stdout ,  flush = True )
154163        # Only notes should also output success 
155164        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 )
158166
159167    if  options .install_types  and  not  options .non_interactive :
160168        result  =  install_types (formatter , options , after_run = True , non_interactive = False )
@@ -180,13 +188,14 @@ def run_build(
180188    options : Options ,
181189    fscache : FileSystemCache ,
182190    t0 : float ,
183-     stdout : TextIO ,
184-     stderr : TextIO ,
191+     stdout : TextIO   |   None   =   None ,
192+     stderr : TextIO   |   None   =   None ,
185193) ->  tuple [build .BuildResult  |  None , list [str ], bool ]:
186194    formatter  =  util .FancyFormatter (
187195        stdout , stderr , options .hide_error_codes , hide_success = bool (options .output )
188196    )
189- 
197+     stdout  =  stdout  if  stdout  is  not   None  else  sys .stdout 
198+     stderr  =  stderr  if  stderr  is  not   None  else  sys .stderr 
190199    messages  =  []
191200    messages_by_file  =  defaultdict (list )
192201
@@ -238,14 +247,12 @@ def flush_errors(filename: str | None, new_messages: list[str], serious: bool) -
238247
239248
240249def  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 
242251) ->  None :
243252    for  msg  in  messages :
244253        if  options .color_output :
245254            msg  =  formatter .colorize (msg )
246-         f .write (msg  +  "\n " )
247-     f .flush ()
248- 
255+         print (msg , file = f , flush = True )
249256
250257# Make the help output a little less jarring. 
251258class  AugmentedHelpFormatter (argparse .RawDescriptionHelpFormatter ):
@@ -399,7 +406,7 @@ def _print_message(self, message: str, file: SupportsWrite[str] | None = None) -
399406        if  message :
400407            if  file  is  None :
401408                file  =  self .stderr 
402-             file . write (message )
409+             print (message ,  file = file )
403410
404411    # =============== 
405412    # Exiting methods 
@@ -465,8 +472,8 @@ def __call__(
465472def  define_options (
466473    program : str  =  "mypy" ,
467474    header : str  =  HEADER ,
468-     stdout : TextIO  |  None ,
469-     stderr : TextIO  |  None ,
475+     stdout : TextIO  |  None   =   None ,
476+     stderr : TextIO  |  None   =   None ,
470477    server_options : bool  =  False ,
471478) ->  tuple [CapturableArgumentParser , list [str ], list [tuple [str , bool ]]]:
472479    """Define the options in the parser (by calling a bunch of methods that express/build our desired command-line flags). 
0 commit comments