eric7/DebugClients/Python/coverage/cmdline.py

branch
eric7
changeset 8991
2fc945191992
parent 8929
fcca2fa618bf
child 9099
0e511e0e94a3
equal deleted inserted replaced
8990:ca8e477c590c 8991:2fc945191992
1 # Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 1 # Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
2 # For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt 2 # For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt
3 3
4 """Command-line support for coverage.py.""" 4 """Command-line support for coverage.py."""
5
6 5
7 import glob 6 import glob
8 import optparse # pylint: disable=deprecated-module 7 import optparse # pylint: disable=deprecated-module
9 import os 8 import os
10 import os.path 9 import os.path
16 import coverage 15 import coverage
17 from coverage import Coverage 16 from coverage import Coverage
18 from coverage import env 17 from coverage import env
19 from coverage.collector import CTracer 18 from coverage.collector import CTracer
20 from coverage.config import CoverageConfig 19 from coverage.config import CoverageConfig
20 from coverage.control import DEFAULT_DATAFILE
21 from coverage.data import combinable_files, debug_data_file 21 from coverage.data import combinable_files, debug_data_file
22 from coverage.debug import info_formatter, info_header, short_stack 22 from coverage.debug import info_header, short_stack, write_formatted_info
23 from coverage.exceptions import _BaseCoverageException, _ExceptionDuringRun, NoSource 23 from coverage.exceptions import _BaseCoverageException, _ExceptionDuringRun, NoSource
24 from coverage.execfile import PyRunner 24 from coverage.execfile import PyRunner
25 from coverage.results import Numbers, should_fail_under 25 from coverage.results import Numbers, should_fail_under
26 26
27 # When adding to this file, alphabetization is important. Look for
28 # "alphabetize" comments throughout.
27 29
28 class Opts: 30 class Opts:
29 """A namespace class for individual options we'll build parsers from.""" 31 """A namespace class for individual options we'll build parsers from."""
32
33 # Keep these entries alphabetized (roughly) by the option name as it
34 # appears on the command line.
30 35
31 append = optparse.make_option( 36 append = optparse.make_option(
32 '-a', '--append', action='store_true', 37 '-a', '--append', action='store_true',
33 help="Append coverage data to .coverage, otherwise it starts clean each time.", 38 help="Append coverage data to .coverage, otherwise it starts clean each time.",
34 ) 39 )
50 context = optparse.make_option( 55 context = optparse.make_option(
51 '', '--context', action='store', metavar="LABEL", 56 '', '--context', action='store', metavar="LABEL",
52 help="The context label to record for this coverage run.", 57 help="The context label to record for this coverage run.",
53 ) 58 )
54 contexts = optparse.make_option( 59 contexts = optparse.make_option(
55 '', '--contexts', action='store', 60 '', '--contexts', action='store', metavar="REGEX1,REGEX2,...",
56 metavar="REGEX1,REGEX2,...",
57 help=( 61 help=(
58 "Only display data from lines covered in the given contexts. " + 62 "Only display data from lines covered in the given contexts. " +
59 "Accepts Python regexes, which must be quoted." 63 "Accepts Python regexes, which must be quoted."
64 ),
65 )
66 combine_datafile = optparse.make_option(
67 '', '--data-file', action='store', metavar="DATAFILE",
68 help=(
69 "Base name of the data files to operate on. " +
70 "Defaults to '.coverage'. [env: COVERAGE_FILE]"
71 ),
72 )
73 input_datafile = optparse.make_option(
74 '', '--data-file', action='store', metavar="INFILE",
75 help=(
76 "Read coverage data for report generation from this file. " +
77 "Defaults to '.coverage'. [env: COVERAGE_FILE]"
78 ),
79 )
80 output_datafile = optparse.make_option(
81 '', '--data-file', action='store', metavar="OUTFILE",
82 help=(
83 "Write the recorded coverage data to this file. " +
84 "Defaults to '.coverage'. [env: COVERAGE_FILE]"
60 ), 85 ),
61 ) 86 )
62 debug = optparse.make_option( 87 debug = optparse.make_option(
63 '', '--debug', action='store', metavar="OPTS", 88 '', '--debug', action='store', metavar="OPTS",
64 help="Debug options, separated by commas. [env: COVERAGE_DEBUG]", 89 help="Debug options, separated by commas. [env: COVERAGE_DEBUG]",
78 ignore_errors = optparse.make_option( 103 ignore_errors = optparse.make_option(
79 '-i', '--ignore-errors', action='store_true', 104 '-i', '--ignore-errors', action='store_true',
80 help="Ignore errors while reading source files.", 105 help="Ignore errors while reading source files.",
81 ) 106 )
82 include = optparse.make_option( 107 include = optparse.make_option(
83 '', '--include', action='store', 108 '', '--include', action='store', metavar="PAT1,PAT2,...",
84 metavar="PAT1,PAT2,...",
85 help=( 109 help=(
86 "Include only files whose paths match one of these patterns. " + 110 "Include only files whose paths match one of these patterns. " +
87 "Accepts shell-style wildcards, which must be quoted." 111 "Accepts shell-style wildcards, which must be quoted."
88 ), 112 ),
89 ) 113 )
104 "<pyfile> is an importable Python module, not a script path, " + 128 "<pyfile> is an importable Python module, not a script path, " +
105 "to be run as 'python -m' would run it." 129 "to be run as 'python -m' would run it."
106 ), 130 ),
107 ) 131 )
108 omit = optparse.make_option( 132 omit = optparse.make_option(
109 '', '--omit', action='store', 133 '', '--omit', action='store', metavar="PAT1,PAT2,...",
110 metavar="PAT1,PAT2,...",
111 help=( 134 help=(
112 "Omit files whose paths match one of these patterns. " + 135 "Omit files whose paths match one of these patterns. " +
113 "Accepts shell-style wildcards, which must be quoted." 136 "Accepts shell-style wildcards, which must be quoted."
114 ), 137 ),
115 ) 138 )
116 output_xml = optparse.make_option( 139 output_xml = optparse.make_option(
117 '-o', '', action='store', dest="outfile", 140 '-o', '', action='store', dest="outfile", metavar="OUTFILE",
118 metavar="OUTFILE",
119 help="Write the XML report to this file. Defaults to 'coverage.xml'", 141 help="Write the XML report to this file. Defaults to 'coverage.xml'",
120 ) 142 )
121 output_json = optparse.make_option( 143 output_json = optparse.make_option(
122 '-o', '', action='store', dest="outfile", 144 '-o', '', action='store', dest="outfile", metavar="OUTFILE",
123 metavar="OUTFILE",
124 help="Write the JSON report to this file. Defaults to 'coverage.json'", 145 help="Write the JSON report to this file. Defaults to 'coverage.json'",
146 )
147 output_lcov = optparse.make_option(
148 '-o', '', action='store', dest='outfile', metavar="OUTFILE",
149 help="Write the LCOV report to this file. Defaults to 'coverage.lcov'",
125 ) 150 )
126 json_pretty_print = optparse.make_option( 151 json_pretty_print = optparse.make_option(
127 '', '--pretty-print', action='store_true', 152 '', '--pretty-print', action='store_true',
128 help="Format the JSON for human readers.", 153 help="Format the JSON for human readers.",
129 ) 154 )
130 parallel_mode = optparse.make_option( 155 parallel_mode = optparse.make_option(
131 '-p', '--parallel-mode', action='store_true', 156 '-p', '--parallel-mode', action='store_true',
132 help=( 157 help=(
133 "Append the machine name, process id and random number to the " + 158 "Append the machine name, process id and random number to the " +
134 ".coverage data file name to simplify collecting data from " + 159 "data file name to simplify collecting data from " +
135 "many processes." 160 "many processes."
136 ), 161 ),
137 ) 162 )
138 precision = optparse.make_option( 163 precision = optparse.make_option(
139 '', '--precision', action='store', metavar='N', type=int, 164 '', '--precision', action='store', metavar='N', type=int,
170 '--skip-empty', action='store_true', 195 '--skip-empty', action='store_true',
171 help="Skip files with no code.", 196 help="Skip files with no code.",
172 ) 197 )
173 sort = optparse.make_option( 198 sort = optparse.make_option(
174 '--sort', action='store', metavar='COLUMN', 199 '--sort', action='store', metavar='COLUMN',
175 help="Sort the report by the named column: name, stmts, miss, branch, brpart, or cover. " + 200 help=(
201 "Sort the report by the named column: name, stmts, miss, branch, brpart, or cover. " +
176 "Default is name." 202 "Default is name."
203 ),
177 ) 204 )
178 source = optparse.make_option( 205 source = optparse.make_option(
179 '', '--source', action='store', metavar="SRC1,SRC2,...", 206 '', '--source', action='store', metavar="SRC1,SRC2,...",
180 help="A list of directories or importable names of code to measure.", 207 help="A list of directories or importable names of code to measure.",
181 ) 208 )
207 def __init__(self, *args, **kwargs): 234 def __init__(self, *args, **kwargs):
208 super().__init__( 235 super().__init__(
209 add_help_option=False, *args, **kwargs 236 add_help_option=False, *args, **kwargs
210 ) 237 )
211 self.set_defaults( 238 self.set_defaults(
239 # Keep these arguments alphabetized by their names.
212 action=None, 240 action=None,
213 append=None, 241 append=None,
214 branch=None, 242 branch=None,
215 concurrency=None, 243 concurrency=None,
216 context=None, 244 context=None,
217 contexts=None, 245 contexts=None,
246 data_file=None,
218 debug=None, 247 debug=None,
219 directory=None, 248 directory=None,
220 fail_under=None, 249 fail_under=None,
221 help=None, 250 help=None,
222 ignore_errors=None, 251 ignore_errors=None,
311 program_name = super().get_prog_name() 340 program_name = super().get_prog_name()
312 341
313 # Include the sub-command for this parser as part of the command. 342 # Include the sub-command for this parser as part of the command.
314 return f"{program_name} {self.cmd}" 343 return f"{program_name} {self.cmd}"
315 344
345 # In lists of Opts, keep them alphabetized by the option names as they appear
346 # on the command line, since these lists determine the order of the options in
347 # the help output.
348 #
349 # In COMMANDS, keep the keys (command names) alphabetized.
316 350
317 GLOBAL_ARGS = [ 351 GLOBAL_ARGS = [
318 Opts.debug, 352 Opts.debug,
319 Opts.help, 353 Opts.help,
320 Opts.rcfile, 354 Opts.rcfile,
321 ] 355 ]
322 356
323 CMDS = { 357 COMMANDS = {
324 'annotate': CmdOptionParser( 358 'annotate': CmdOptionParser(
325 "annotate", 359 "annotate",
326 [ 360 [
327 Opts.directory, 361 Opts.directory,
362 Opts.input_datafile,
328 Opts.ignore_errors, 363 Opts.ignore_errors,
329 Opts.include, 364 Opts.include,
330 Opts.omit, 365 Opts.omit,
331 ] + GLOBAL_ARGS, 366 ] + GLOBAL_ARGS,
332 usage="[options] [modules]", 367 usage="[options] [modules]",
338 373
339 'combine': CmdOptionParser( 374 'combine': CmdOptionParser(
340 "combine", 375 "combine",
341 [ 376 [
342 Opts.append, 377 Opts.append,
378 Opts.combine_datafile,
343 Opts.keep, 379 Opts.keep,
344 Opts.quiet, 380 Opts.quiet,
345 ] + GLOBAL_ARGS, 381 ] + GLOBAL_ARGS,
346 usage="[options] <path1> <path2> ... <pathN>", 382 usage="[options] <path1> <path2> ... <pathN>",
347 description=( 383 description=(
362 "for diagnosing problems. " + 398 "for diagnosing problems. " +
363 "Topics are: " + 399 "Topics are: " +
364 "'data' to show a summary of the collected data; " + 400 "'data' to show a summary of the collected data; " +
365 "'sys' to show installation information; " + 401 "'sys' to show installation information; " +
366 "'config' to show the configuration; " + 402 "'config' to show the configuration; " +
367 "'premain' to show what is calling coverage." 403 "'premain' to show what is calling coverage; " +
404 "'pybehave' to show internal flags describing Python behavior."
368 ), 405 ),
369 ), 406 ),
370 407
371 'erase': CmdOptionParser( 408 'erase': CmdOptionParser(
372 "erase", GLOBAL_ARGS, 409 "erase",
410 [
411 Opts.combine_datafile
412 ] + GLOBAL_ARGS,
373 description="Erase previously collected coverage data.", 413 description="Erase previously collected coverage data.",
374 ), 414 ),
375 415
376 'help': CmdOptionParser( 416 'help': CmdOptionParser(
377 "help", GLOBAL_ARGS, 417 "help", GLOBAL_ARGS,
382 'html': CmdOptionParser( 422 'html': CmdOptionParser(
383 "html", 423 "html",
384 [ 424 [
385 Opts.contexts, 425 Opts.contexts,
386 Opts.directory, 426 Opts.directory,
427 Opts.input_datafile,
387 Opts.fail_under, 428 Opts.fail_under,
388 Opts.ignore_errors, 429 Opts.ignore_errors,
389 Opts.include, 430 Opts.include,
390 Opts.omit, 431 Opts.omit,
391 Opts.precision, 432 Opts.precision,
406 447
407 'json': CmdOptionParser( 448 'json': CmdOptionParser(
408 "json", 449 "json",
409 [ 450 [
410 Opts.contexts, 451 Opts.contexts,
452 Opts.input_datafile,
411 Opts.fail_under, 453 Opts.fail_under,
412 Opts.ignore_errors, 454 Opts.ignore_errors,
413 Opts.include, 455 Opts.include,
414 Opts.omit, 456 Opts.omit,
415 Opts.output_json, 457 Opts.output_json,
416 Opts.json_pretty_print, 458 Opts.json_pretty_print,
417 Opts.quiet, 459 Opts.quiet,
418 Opts.show_contexts, 460 Opts.show_contexts,
419 ] + GLOBAL_ARGS, 461 ] + GLOBAL_ARGS,
420 usage="[options] [modules]", 462 usage="[options] [modules]",
421 description="Generate a JSON report of coverage results." 463 description="Generate a JSON report of coverage results.",
464 ),
465
466 'lcov': CmdOptionParser(
467 "lcov",
468 [
469 Opts.input_datafile,
470 Opts.fail_under,
471 Opts.ignore_errors,
472 Opts.include,
473 Opts.output_lcov,
474 Opts.omit,
475 Opts.quiet,
476 ] + GLOBAL_ARGS,
477 usage="[options] [modules]",
478 description="Generate an LCOV report of coverage results.",
422 ), 479 ),
423 480
424 'report': CmdOptionParser( 481 'report': CmdOptionParser(
425 "report", 482 "report",
426 [ 483 [
427 Opts.contexts, 484 Opts.contexts,
485 Opts.input_datafile,
428 Opts.fail_under, 486 Opts.fail_under,
429 Opts.ignore_errors, 487 Opts.ignore_errors,
430 Opts.include, 488 Opts.include,
431 Opts.omit, 489 Opts.omit,
432 Opts.precision, 490 Opts.precision,
435 Opts.skip_covered, 493 Opts.skip_covered,
436 Opts.no_skip_covered, 494 Opts.no_skip_covered,
437 Opts.skip_empty, 495 Opts.skip_empty,
438 ] + GLOBAL_ARGS, 496 ] + GLOBAL_ARGS,
439 usage="[options] [modules]", 497 usage="[options] [modules]",
440 description="Report coverage statistics on modules." 498 description="Report coverage statistics on modules.",
441 ), 499 ),
442 500
443 'run': CmdOptionParser( 501 'run': CmdOptionParser(
444 "run", 502 "run",
445 [ 503 [
446 Opts.append, 504 Opts.append,
447 Opts.branch, 505 Opts.branch,
448 Opts.concurrency, 506 Opts.concurrency,
449 Opts.context, 507 Opts.context,
508 Opts.output_datafile,
450 Opts.include, 509 Opts.include,
451 Opts.module, 510 Opts.module,
452 Opts.omit, 511 Opts.omit,
453 Opts.pylib, 512 Opts.pylib,
454 Opts.parallel_mode, 513 Opts.parallel_mode,
455 Opts.source, 514 Opts.source,
456 Opts.timid, 515 Opts.timid,
457 ] + GLOBAL_ARGS, 516 ] + GLOBAL_ARGS,
458 usage="[options] <pyfile> [program options]", 517 usage="[options] <pyfile> [program options]",
459 description="Run a Python program, measuring code execution." 518 description="Run a Python program, measuring code execution.",
460 ), 519 ),
461 520
462 'xml': CmdOptionParser( 521 'xml': CmdOptionParser(
463 "xml", 522 "xml",
464 [ 523 [
524 Opts.input_datafile,
465 Opts.fail_under, 525 Opts.fail_under,
466 Opts.ignore_errors, 526 Opts.ignore_errors,
467 Opts.include, 527 Opts.include,
468 Opts.omit, 528 Opts.omit,
469 Opts.output_xml, 529 Opts.output_xml,
470 Opts.quiet, 530 Opts.quiet,
471 Opts.skip_empty, 531 Opts.skip_empty,
472 ] + GLOBAL_ARGS, 532 ] + GLOBAL_ARGS,
473 usage="[options] [modules]", 533 usage="[options] [modules]",
474 description="Generate an XML report of coverage results." 534 description="Generate an XML report of coverage results.",
475 ), 535 ),
476 } 536 }
477 537
478 538
479 def show_help(error=None, topic=None, parser=None): 539 def show_help(error=None, topic=None, parser=None):
544 # switch syntax always starts with an option. 604 # switch syntax always starts with an option.
545 self.global_option = argv[0].startswith('-') 605 self.global_option = argv[0].startswith('-')
546 if self.global_option: 606 if self.global_option:
547 parser = GlobalOptionParser() 607 parser = GlobalOptionParser()
548 else: 608 else:
549 parser = CMDS.get(argv[0]) 609 parser = COMMANDS.get(argv[0])
550 if not parser: 610 if not parser:
551 show_help(f"Unknown command: {argv[0]!r}") 611 show_help(f"Unknown command: {argv[0]!r}")
552 return ERR 612 return ERR
553 argv = argv[1:] 613 argv = argv[1:]
554 614
572 else: 632 else:
573 concurrency = None 633 concurrency = None
574 634
575 # Do something. 635 # Do something.
576 self.coverage = Coverage( 636 self.coverage = Coverage(
637 data_file=options.data_file or DEFAULT_DATAFILE,
577 data_suffix=options.parallel_mode, 638 data_suffix=options.parallel_mode,
578 cover_pylib=options.pylib, 639 cover_pylib=options.pylib,
579 timid=options.timid, 640 timid=options.timid,
580 branch=options.branch, 641 branch=options.branch,
581 config_file=options.rcfile, 642 config_file=options.rcfile,
623 self.coverage.load() 684 self.coverage.load()
624 685
625 total = None 686 total = None
626 if options.action == "report": 687 if options.action == "report":
627 total = self.coverage.report( 688 total = self.coverage.report(
689 precision=options.precision,
628 show_missing=options.show_missing, 690 show_missing=options.show_missing,
629 skip_covered=options.skip_covered, 691 skip_covered=options.skip_covered,
630 skip_empty=options.skip_empty, 692 skip_empty=options.skip_empty,
631 precision=options.precision,
632 sort=options.sort, 693 sort=options.sort,
633 **report_args 694 **report_args
634 ) 695 )
635 elif options.action == "annotate": 696 elif options.action == "annotate":
636 self.coverage.annotate(directory=options.directory, **report_args) 697 self.coverage.annotate(directory=options.directory, **report_args)
637 elif options.action == "html": 698 elif options.action == "html":
638 total = self.coverage.html_report( 699 total = self.coverage.html_report(
639 directory=options.directory, 700 directory=options.directory,
640 title=options.title, 701 precision=options.precision,
641 skip_covered=options.skip_covered, 702 skip_covered=options.skip_covered,
642 skip_empty=options.skip_empty, 703 skip_empty=options.skip_empty,
643 show_contexts=options.show_contexts, 704 show_contexts=options.show_contexts,
644 precision=options.precision, 705 title=options.title,
645 **report_args 706 **report_args
646 ) 707 )
647 elif options.action == "xml": 708 elif options.action == "xml":
648 outfile = options.outfile
649 total = self.coverage.xml_report( 709 total = self.coverage.xml_report(
650 outfile=outfile, skip_empty=options.skip_empty, 710 outfile=options.outfile,
711 skip_empty=options.skip_empty,
651 **report_args 712 **report_args
652 ) 713 )
653 elif options.action == "json": 714 elif options.action == "json":
654 outfile = options.outfile
655 total = self.coverage.json_report( 715 total = self.coverage.json_report(
656 outfile=outfile, 716 outfile=options.outfile,
657 pretty_print=options.pretty_print, 717 pretty_print=options.pretty_print,
658 show_contexts=options.show_contexts, 718 show_contexts=options.show_contexts,
659 **report_args 719 **report_args
660 ) 720 )
721 elif options.action == "lcov":
722 total = self.coverage.lcov_report(
723 outfile=options.outfile,
724 **report_args
725 )
661 else: 726 else:
662 # There are no other possible actions. 727 # There are no other possible actions.
663 raise AssertionError 728 raise AssertionError
664 729
665 if total is not None: 730 if total is not None:
666 # Apply the command line fail-under options, and then use the config 731 # Apply the command line fail-under options, and then use the config
667 # value, so we can get fail_under from the config file. 732 # value, so we can get fail_under from the config file.
668 if options.fail_under is not None: 733 if options.fail_under is not None:
669 self.coverage.set_option("report:fail_under", options.fail_under) 734 self.coverage.set_option("report:fail_under", options.fail_under)
735 if options.precision is not None:
736 self.coverage.set_option("report:precision", options.precision)
670 737
671 fail_under = self.coverage.get_option("report:fail_under") 738 fail_under = self.coverage.get_option("report:fail_under")
672 precision = self.coverage.get_option("report:precision") 739 precision = self.coverage.get_option("report:precision")
673 if should_fail_under(total, fail_under, precision): 740 if should_fail_under(total, fail_under, precision):
674 msg = "total of {total} is less than fail-under={fail_under:.{p}f}".format( 741 msg = "total of {total} is less than fail-under={fail_under:.{p}f}".format(
696 return True 763 return True
697 764
698 if options.action == "help": 765 if options.action == "help":
699 if args: 766 if args:
700 for a in args: 767 for a in args:
701 parser = CMDS.get(a) 768 parser = COMMANDS.get(a)
702 if parser: 769 if parser:
703 show_help(parser=parser) 770 show_help(parser=parser)
704 else: 771 else:
705 show_help(topic=a) 772 show_help(topic=a)
706 else: 773 else:
775 842
776 def do_debug(self, args): 843 def do_debug(self, args):
777 """Implementation of 'coverage debug'.""" 844 """Implementation of 'coverage debug'."""
778 845
779 if not args: 846 if not args:
780 show_help("What information would you like: config, data, sys, premain?") 847 show_help("What information would you like: config, data, sys, premain, pybehave?")
781 return ERR 848 return ERR
782 if args[1:]: 849 if args[1:]:
783 show_help("Only one topic at a time, please") 850 show_help("Only one topic at a time, please")
784 return ERR 851 return ERR
785 852
786 if args[0] == 'sys': 853 if args[0] == "sys":
787 sys_info = self.coverage.sys_info() 854 write_formatted_info(print, "sys", self.coverage.sys_info())
788 print(info_header("sys")) 855 elif args[0] == "data":
789 for line in info_formatter(sys_info):
790 print(f" {line}")
791 elif args[0] == 'data':
792 print(info_header("data")) 856 print(info_header("data"))
793 data_file = self.coverage.config.data_file 857 data_file = self.coverage.config.data_file
794 debug_data_file(data_file) 858 debug_data_file(data_file)
795 for filename in combinable_files(data_file): 859 for filename in combinable_files(data_file):
796 print("-----") 860 print("-----")
797 debug_data_file(filename) 861 debug_data_file(filename)
798 elif args[0] == 'config': 862 elif args[0] == "config":
799 print(info_header("config")) 863 write_formatted_info(print, "config", self.coverage.config.debug_info())
800 config_info = sorted(self.coverage.config.__dict__.items())
801 for line in info_formatter(config_info):
802 print(f" {line}")
803 elif args[0] == "premain": 864 elif args[0] == "premain":
804 print(info_header("premain")) 865 print(info_header("premain"))
805 print(short_stack()) 866 print(short_stack())
867 elif args[0] == "pybehave":
868 write_formatted_info(print, "pybehave", env.debug_info())
806 else: 869 else:
807 show_help(f"Don't know what you mean by {args[0]!r}") 870 show_help(f"Don't know what you mean by {args[0]!r}")
808 return ERR 871 return ERR
809 872
810 return OK 873 return OK
850 debug Display information about the internals of coverage.py 913 debug Display information about the internals of coverage.py
851 erase Erase previously collected coverage data. 914 erase Erase previously collected coverage data.
852 help Get help on using coverage.py. 915 help Get help on using coverage.py.
853 html Create an HTML report. 916 html Create an HTML report.
854 json Create a JSON report of coverage results. 917 json Create a JSON report of coverage results.
918 lcov Create an LCOV report of coverage results.
855 report Report coverage stats on modules. 919 report Report coverage stats on modules.
856 run Run a Python program and measure code execution. 920 run Run a Python program and measure code execution.
857 xml Create an XML report of coverage results. 921 xml Create an XML report of coverage results.
858 922
859 Use "{program_name} help <command>" for detailed help on any command. 923 Use "{program_name} help <command>" for detailed help on any command.

eric ide

mercurial