12
12
import textwrap
13
13
import traceback
14
14
15
+ from typing import cast , Any , List , NoReturn , Optional , Tuple
16
+
15
17
import coverage
16
18
from coverage import Coverage
17
19
from coverage import env
@@ -235,8 +237,9 @@ class CoverageOptionParser(optparse.OptionParser):
235
237
236
238
"""
237
239
238
- def __init__ (self , * args , ** kwargs ):
239
- super ().__init__ (add_help_option = False , * args , ** kwargs )
240
+ def __init__ (self , * args : Any , ** kwargs : Any ) -> None :
241
+ kwargs ["add_help_option" ] = False
242
+ super ().__init__ (* args , ** kwargs )
240
243
self .set_defaults (
241
244
# Keep these arguments alphabetized by their names.
242
245
action = None ,
@@ -278,19 +281,19 @@ class OptionParserError(Exception):
278
281
"""Used to stop the optparse error handler ending the process."""
279
282
pass
280
283
281
- def parse_args_ok (self , args = None , options = None ) :
284
+ def parse_args_ok (self , args : List [ str ]) -> Tuple [ bool , Optional [ optparse . Values ], List [ str ]] :
282
285
"""Call optparse.parse_args, but return a triple:
283
286
284
287
(ok, options, args)
285
288
286
289
"""
287
290
try :
288
- options , args = super ().parse_args (args , options )
291
+ options , args = super ().parse_args (args )
289
292
except self .OptionParserError :
290
- return False , None , None
293
+ return False , None , []
291
294
return True , options , args
292
295
293
- def error (self , msg ) :
296
+ def error (self , msg : str ) -> NoReturn :
294
297
"""Override optparse.error so sys.exit doesn't get called."""
295
298
show_help (msg )
296
299
raise self .OptionParserError
@@ -299,7 +302,7 @@ def error(self, msg):
299
302
class GlobalOptionParser (CoverageOptionParser ):
300
303
"""Command-line parser for coverage.py global option arguments."""
301
304
302
- def __init__ (self ):
305
+ def __init__ (self ) -> None :
303
306
super ().__init__ ()
304
307
305
308
self .add_options ([
@@ -311,14 +314,19 @@ def __init__(self):
311
314
class CmdOptionParser (CoverageOptionParser ):
312
315
"""Parse one of the new-style commands for coverage.py."""
313
316
314
- def __init__ (self , action , options , defaults = None , usage = None , description = None ):
317
+ def __init__ (
318
+ self ,
319
+ action : str ,
320
+ options : List [optparse .Option ],
321
+ description : str ,
322
+ usage : Optional [str ]= None ,
323
+ ):
315
324
"""Create an OptionParser for a coverage.py command.
316
325
317
326
`action` is the slug to put into `options.action`.
318
327
`options` is a list of Option's for the command.
319
- `defaults` is a dict of default value for options.
320
- `usage` is the usage string to display in help.
321
328
`description` is the description of the command, for the help text.
329
+ `usage` is the usage string to display in help.
322
330
323
331
"""
324
332
if usage :
@@ -327,18 +335,18 @@ def __init__(self, action, options, defaults=None, usage=None, description=None)
327
335
usage = usage ,
328
336
description = description ,
329
337
)
330
- self .set_defaults (action = action , ** ( defaults or {}) )
338
+ self .set_defaults (action = action )
331
339
self .add_options (options )
332
340
self .cmd = action
333
341
334
- def __eq__ (self , other ):
342
+ def __eq__ (self , other : str ) -> bool : # type: ignore[override]
335
343
# A convenience equality, so that I can put strings in unit test
336
344
# results, and they will compare equal to objects.
337
345
return (other == f"<CmdOptionParser:{ self .cmd } >" )
338
346
339
- __hash__ = None # This object doesn't need to be hashed.
347
+ __hash__ = None # type: ignore[assignment]
340
348
341
- def get_prog_name (self ):
349
+ def get_prog_name (self ) -> str :
342
350
"""Override of an undocumented function in optparse.OptionParser."""
343
351
program_name = super ().get_prog_name ()
344
352
@@ -540,7 +548,11 @@ def get_prog_name(self):
540
548
}
541
549
542
550
543
- def show_help (error = None , topic = None , parser = None ):
551
+ def show_help (
552
+ error : Optional [str ]= None ,
553
+ topic : Optional [str ]= None ,
554
+ parser : Optional [optparse .OptionParser ]= None ,
555
+ ) -> None :
544
556
"""Display an error message, or the named topic."""
545
557
assert error or topic or parser
546
558
@@ -573,6 +585,7 @@ def show_help(error=None, topic=None, parser=None):
573
585
print (parser .format_help ().strip ())
574
586
print ()
575
587
else :
588
+ assert topic is not None
576
589
help_msg = textwrap .dedent (HELP_TOPICS .get (topic , '' )).strip ()
577
590
if help_msg :
578
591
print (help_msg .format (** help_params ))
@@ -587,11 +600,11 @@ def show_help(error=None, topic=None, parser=None):
587
600
class CoverageScript :
588
601
"""The command-line interface to coverage.py."""
589
602
590
- def __init__ (self ):
603
+ def __init__ (self ) -> None :
591
604
self .global_option = False
592
- self .coverage = None
605
+ self .coverage : Coverage
593
606
594
- def command_line (self , argv ) :
607
+ def command_line (self , argv : List [ str ]) -> int :
595
608
"""The bulk of the command line interface to coverage.py.
596
609
597
610
`argv` is the argument list to process.
@@ -606,6 +619,7 @@ def command_line(self, argv):
606
619
607
620
# The command syntax we parse depends on the first argument. Global
608
621
# switch syntax always starts with an option.
622
+ parser : Optional [optparse .OptionParser ]
609
623
self .global_option = argv [0 ].startswith ('-' )
610
624
if self .global_option :
611
625
parser = GlobalOptionParser ()
@@ -619,6 +633,7 @@ def command_line(self, argv):
619
633
ok , options , args = parser .parse_args_ok (argv )
620
634
if not ok :
621
635
return ERR
636
+ assert options is not None
622
637
623
638
# Handle help and version.
624
639
if self .do_help (options , args , parser ):
@@ -740,8 +755,8 @@ def command_line(self, argv):
740
755
if options .precision is not None :
741
756
self .coverage .set_option ("report:precision" , options .precision )
742
757
743
- fail_under = self .coverage .get_option ("report:fail_under" )
744
- precision = self .coverage .get_option ("report:precision" )
758
+ fail_under = cast ( float , self .coverage .get_option ("report:fail_under" ) )
759
+ precision = cast ( int , self .coverage .get_option ("report:precision" ) )
745
760
if should_fail_under (total , fail_under , precision ):
746
761
msg = "total of {total} is less than fail-under={fail_under:.{p}f}" .format (
747
762
total = Numbers (precision = precision ).display_covered (total ),
@@ -753,7 +768,12 @@ def command_line(self, argv):
753
768
754
769
return OK
755
770
756
- def do_help (self , options , args , parser ):
771
+ def do_help (
772
+ self ,
773
+ options : optparse .Values ,
774
+ args : List [str ],
775
+ parser : optparse .OptionParser ,
776
+ ) -> bool :
757
777
"""Deal with help requests.
758
778
759
779
Return True if it handled the request, False if not.
@@ -770,9 +790,9 @@ def do_help(self, options, args, parser):
770
790
if options .action == "help" :
771
791
if args :
772
792
for a in args :
773
- parser = COMMANDS .get (a )
774
- if parser :
775
- show_help (parser = parser )
793
+ parser_maybe = COMMANDS .get (a )
794
+ if parser_maybe is not None :
795
+ show_help (parser = parser_maybe )
776
796
else :
777
797
show_help (topic = a )
778
798
else :
@@ -786,15 +806,15 @@ def do_help(self, options, args, parser):
786
806
787
807
return False
788
808
789
- def do_run (self , options , args ) :
809
+ def do_run (self , options : optparse . Values , args : List [ str ]) -> int :
790
810
"""Implementation of 'coverage run'."""
791
811
792
812
if not args :
793
813
if options .module :
794
814
# Specified -m with nothing else.
795
815
show_help ("No module specified for -m" )
796
816
return ERR
797
- command_line = self .coverage .get_option ("run:command_line" )
817
+ command_line = cast ( str , self .coverage .get_option ("run:command_line" ) )
798
818
if command_line is not None :
799
819
args = shlex .split (command_line )
800
820
if args and args [0 ] in {"-m" , "--module" }:
@@ -845,7 +865,7 @@ def do_run(self, options, args):
845
865
846
866
return OK
847
867
848
- def do_debug (self , args ) :
868
+ def do_debug (self , args : List [ str ]) -> int :
849
869
"""Implementation of 'coverage debug'."""
850
870
851
871
if not args :
@@ -878,7 +898,7 @@ def do_debug(self, args):
878
898
return OK
879
899
880
900
881
- def unshell_list (s ) :
901
+ def unshell_list (s : str ) -> Optional [ List [ str ]] :
882
902
"""Turn a command-line argument into a list."""
883
903
if not s :
884
904
return None
@@ -892,7 +912,7 @@ def unshell_list(s):
892
912
return s .split (',' )
893
913
894
914
895
- def unglob_args (args ) :
915
+ def unglob_args (args : List [ str ]) -> List [ str ] :
896
916
"""Interpret shell wildcards for platforms that need it."""
897
917
if env .WINDOWS :
898
918
globbed = []
@@ -938,7 +958,7 @@ def unglob_args(args):
938
958
}
939
959
940
960
941
- def main (argv = None ):
961
+ def main (argv : Optional [ List [ str ]] = None ) -> Optional [ int ] :
942
962
"""The main entry point to coverage.py.
943
963
944
964
This is installed as the script entry point.
@@ -976,7 +996,9 @@ def main(argv=None):
976
996
from ox_profile .core .launchers import SimpleLauncher # pylint: disable=import-error
977
997
original_main = main
978
998
979
- def main (argv = None ): # pylint: disable=function-redefined
999
+ def main ( # pylint: disable=function-redefined
1000
+ argv : Optional [List [str ]]= None ,
1001
+ ) -> Optional [int ]:
980
1002
"""A wrapper around main that profiles."""
981
1003
profiler = SimpleLauncher .launch ()
982
1004
try :
0 commit comments