diff -r 04e5dfbd3f3d -r 3586ebd9fac8 DebugClients/Python3/coverage/cmdline.py --- a/DebugClients/Python3/coverage/cmdline.py Sat Jul 23 13:33:54 2016 +0200 +++ b/DebugClients/Python3/coverage/cmdline.py Sun Jul 24 12:01:01 2016 +0200 @@ -7,9 +7,11 @@ import optparse import os.path import sys +import textwrap import traceback from coverage import env +from coverage.collector import CTracer from coverage.execfile import run_python_file, run_python_module from coverage.misc import CoverageException, ExceptionDuringRun, NoSource from coverage.debug import info_formatter, info_header @@ -20,105 +22,117 @@ append = optparse.make_option( '-a', '--append', action='store_true', - help="Append coverage data to .coverage, otherwise it is started " - "clean with each run." - ) + help="Append coverage data to .coverage, otherwise it is started clean with each run.", + ) branch = optparse.make_option( '', '--branch', action='store_true', - help="Measure branch coverage in addition to statement coverage." - ) + help="Measure branch coverage in addition to statement coverage.", + ) CONCURRENCY_CHOICES = [ "thread", "gevent", "greenlet", "eventlet", "multiprocessing", ] concurrency = optparse.make_option( '', '--concurrency', action='store', metavar="LIB", choices=CONCURRENCY_CHOICES, - help="Properly measure code using a concurrency library. " - "Valid values are: %s." % ", ".join(CONCURRENCY_CHOICES) - ) + help=( + "Properly measure code using a concurrency library. " + "Valid values are: %s." + ) % ", ".join(CONCURRENCY_CHOICES), + ) debug = optparse.make_option( '', '--debug', action='store', metavar="OPTS", - help="Debug options, separated by commas" - ) + help="Debug options, separated by commas", + ) directory = optparse.make_option( '-d', '--directory', action='store', metavar="DIR", - help="Write the output files to DIR." - ) + help="Write the output files to DIR.", + ) fail_under = optparse.make_option( '', '--fail-under', action='store', metavar="MIN", type="int", - help="Exit with a status of 2 if the total coverage is less than MIN." - ) + help="Exit with a status of 2 if the total coverage is less than MIN.", + ) help = optparse.make_option( '-h', '--help', action='store_true', - help="Get help on this command." - ) + help="Get help on this command.", + ) ignore_errors = optparse.make_option( '-i', '--ignore-errors', action='store_true', - help="Ignore errors while reading source files." - ) + help="Ignore errors while reading source files.", + ) include = optparse.make_option( '', '--include', action='store', metavar="PAT1,PAT2,...", - help="Include only files whose paths match one of these patterns. " - "Accepts shell-style wildcards, which must be quoted." - ) + help=( + "Include only files whose paths match one of these patterns. " + "Accepts shell-style wildcards, which must be quoted." + ), + ) pylib = optparse.make_option( '-L', '--pylib', action='store_true', - help="Measure coverage even inside the Python installed library, " - "which isn't done by default." - ) + help=( + "Measure coverage even inside the Python installed library, " + "which isn't done by default." + ), + ) show_missing = optparse.make_option( '-m', '--show-missing', action='store_true', - help="Show line numbers of statements in each module that weren't " - "executed." - ) + help="Show line numbers of statements in each module that weren't executed.", + ) skip_covered = optparse.make_option( '--skip-covered', action='store_true', - help="Skip files with 100% coverage." - ) + help="Skip files with 100% coverage.", + ) omit = optparse.make_option( '', '--omit', action='store', metavar="PAT1,PAT2,...", - help="Omit files whose paths match one of these patterns. " - "Accepts shell-style wildcards, which must be quoted." - ) + help=( + "Omit files whose paths match one of these patterns. " + "Accepts shell-style wildcards, which must be quoted." + ), + ) output_xml = optparse.make_option( '-o', '', action='store', dest="outfile", metavar="OUTFILE", - help="Write the XML report to this file. Defaults to 'coverage.xml'" - ) + help="Write the XML report to this file. Defaults to 'coverage.xml'", + ) parallel_mode = optparse.make_option( '-p', '--parallel-mode', action='store_true', - help="Append the machine name, process id and random number to the " - ".coverage data file name to simplify collecting data from " - "many processes." - ) + help=( + "Append the machine name, process id and random number to the " + ".coverage data file name to simplify collecting data from " + "many processes." + ), + ) module = optparse.make_option( '-m', '--module', action='store_true', - help="<pyfile> is an importable Python module, not a script path, " - "to be run as 'python -m' would run it." - ) + help=( + "<pyfile> is an importable Python module, not a script path, " + "to be run as 'python -m' would run it." + ), + ) rcfile = optparse.make_option( '', '--rcfile', action='store', - help="Specify configuration file. Defaults to '.coveragerc'" - ) + help="Specify configuration file. Defaults to '.coveragerc'", + ) source = optparse.make_option( '', '--source', action='store', metavar="SRC1,SRC2,...", - help="A list of packages or directories of code to be measured." - ) + help="A list of packages or directories of code to be measured.", + ) timid = optparse.make_option( '', '--timid', action='store_true', - help="Use a simpler but slower trace method. Try this if you get " - "seemingly impossible results!" - ) + help=( + "Use a simpler but slower trace method. Try this if you get " + "seemingly impossible results!" + ), + ) title = optparse.make_option( '', '--title', action='store', metavar="TITLE", - help="A text string to use as the title on the HTML." - ) + help="A text string to use as the title on the HTML.", + ) version = optparse.make_option( '', '--version', action='store_true', - help="Display version information and exit." - ) + help="Display version information and exit.", + ) class CoverageOptionParser(optparse.OptionParser, object): @@ -202,9 +216,7 @@ class CmdOptionParser(CoverageOptionParser): """Parse one of the new-style commands for coverage.py.""" - def __init__(self, action, options=None, defaults=None, usage=None, - description=None - ): + def __init__(self, action, options=None, defaults=None, usage=None, description=None): """Create an OptionParser for a coverage.py command. `action` is the slug to put into `options.action`. @@ -217,7 +229,6 @@ if usage: usage = "%prog " + usage super(CmdOptionParser, self).__init__( - prog="coverage %s" % action, usage=usage, description=description, ) @@ -231,6 +242,14 @@ # results, and they will compare equal to objects. return (other == "<CmdOptionParser:%s>" % self.cmd) + def get_prog_name(self): + """Override of an undocumented function in optparse.OptionParser.""" + program_name = super(CmdOptionParser, self).get_prog_name() + + # Include the sub-command for this parser as part of the command. + return "%(command)s %(subcommand)s" % {'command': program_name, 'subcommand': self.cmd} + + GLOBAL_ARGS = [ Opts.debug, Opts.help, @@ -238,48 +257,60 @@ ] CMDS = { - 'annotate': CmdOptionParser("annotate", + 'annotate': CmdOptionParser( + "annotate", [ Opts.directory, Opts.ignore_errors, Opts.include, Opts.omit, ] + GLOBAL_ARGS, - usage = "[options] [modules]", - description = "Make annotated copies of the given files, marking " - "statements that are executed with > and statements that are " - "missed with !." + usage="[options] [modules]", + description=( + "Make annotated copies of the given files, marking statements that are executed " + "with > and statements that are missed with !." ), + ), - 'combine': CmdOptionParser("combine", GLOBAL_ARGS, - usage = "<path1> <path2> ... <pathN>", - description = "Combine data from multiple coverage files collected " + 'combine': CmdOptionParser( + "combine", + GLOBAL_ARGS, + usage="<path1> <path2> ... <pathN>", + description=( + "Combine data from multiple coverage files collected " "with 'run -p'. The combined results are written to a single " "file representing the union of the data. The positional " "arguments are data files or directories containing data files. " "If no paths are provided, data files in the default data file's " "directory are combined." ), + ), - 'debug': CmdOptionParser("debug", GLOBAL_ARGS, - usage = "<topic>", - description = "Display information on the internals of coverage.py, " + 'debug': CmdOptionParser( + "debug", GLOBAL_ARGS, + usage="<topic>", + description=( + "Display information on the internals of coverage.py, " "for diagnosing problems. " "Topics are 'data' to show a summary of the collected data, " "or 'sys' to show installation information." ), + ), - 'erase': CmdOptionParser("erase", GLOBAL_ARGS, - usage = " ", - description = "Erase previously collected coverage data." - ), + 'erase': CmdOptionParser( + "erase", GLOBAL_ARGS, + usage=" ", + description="Erase previously collected coverage data.", + ), - 'help': CmdOptionParser("help", GLOBAL_ARGS, - usage = "[command]", - description = "Describe how to use coverage.py" - ), + 'help': CmdOptionParser( + "help", GLOBAL_ARGS, + usage="[command]", + description="Describe how to use coverage.py", + ), - 'html': CmdOptionParser("html", + 'html': CmdOptionParser( + "html", [ Opts.directory, Opts.fail_under, @@ -288,13 +319,16 @@ Opts.omit, Opts.title, ] + GLOBAL_ARGS, - usage = "[options] [modules]", - description = "Create an HTML report of the coverage of the files. " + usage="[options] [modules]", + description=( + "Create an HTML report of the coverage of the files. " "Each file gets its own page, with the source decorated to show " "executed, excluded, and missed lines." ), + ), - 'report': CmdOptionParser("report", + 'report': CmdOptionParser( + "report", [ Opts.fail_under, Opts.ignore_errors, @@ -303,11 +337,12 @@ Opts.show_missing, Opts.skip_covered, ] + GLOBAL_ARGS, - usage = "[options] [modules]", - description = "Report coverage statistics on modules." - ), + usage="[options] [modules]", + description="Report coverage statistics on modules." + ), - 'run': CmdOptionParser("run", + 'run': CmdOptionParser( + "run", [ Opts.append, Opts.branch, @@ -320,11 +355,12 @@ Opts.source, Opts.timid, ] + GLOBAL_ARGS, - usage = "[options] <pyfile> [program options]", - description = "Run a Python program, measuring code execution." - ), + usage="[options] <pyfile> [program options]", + description="Run a Python program, measuring code execution." + ), - 'xml': CmdOptionParser("xml", + 'xml': CmdOptionParser( + "xml", [ Opts.fail_under, Opts.ignore_errors, @@ -332,10 +368,10 @@ Opts.omit, Opts.output_xml, ] + GLOBAL_ARGS, - usage = "[options] [modules]", - description = "Generate an XML report of coverage results." - ), - } + usage="[options] [modules]", + description="Generate an XML report of coverage results." + ), +} OK, ERR, FAIL_UNDER = 0, 1, 2 @@ -362,6 +398,17 @@ self.coverage = None + self.program_name = os.path.basename(sys.argv[0]) + if env.WINDOWS: + # entry_points={'console_scripts':...} on Windows makes files + # called coverage.exe, coverage3.exe, and coverage-3.5.exe. These + # invoke coverage-script.py, coverage3-script.py, and + # coverage-3.5-script.py. argv[0] is the .py file, but we want to + # get back to the original form. + auto_suffix = "-script.py" + if self.program_name.endswith(auto_suffix): + self.program_name = self.program_name[:-len(auto_suffix)] + def command_line(self, argv): """The bulk of the command line interface to coverage.py. @@ -412,16 +459,16 @@ # Do something. self.coverage = self.covpkg.coverage( - data_suffix = options.parallel_mode, - cover_pylib = options.pylib, - timid = options.timid, - branch = options.branch, - config_file = options.rcfile, - source = source, - omit = omit, - include = include, - debug = debug, - concurrency = options.concurrency, + data_suffix=options.parallel_mode, + cover_pylib=options.pylib, + timid=options.timid, + branch=options.branch, + config_file=options.rcfile, + source=source, + omit=omit, + include=include, + debug=debug, + concurrency=options.concurrency, ) if options.action == "debug": @@ -443,10 +490,10 @@ # Remaining actions are reporting, with some common options. report_args = dict( - morfs = unglob_args(args), - ignore_errors = options.ignore_errors, - omit = omit, - include = include, + morfs=unglob_args(args), + ignore_errors=options.ignore_errors, + omit=omit, + include=include, ) self.coverage.load() @@ -495,13 +542,19 @@ assert error or topic or parser if error: print(error) - print("Use 'coverage help' for help.") + print("Use '%s help' for help." % (self.program_name,)) elif parser: print(parser.format_help().strip()) else: - help_msg = HELP_TOPICS.get(topic, '').strip() + help_params = dict(self.covpkg.__dict__) + help_params['program_name'] = self.program_name + if CTracer is not None: + help_params['extension_modifier'] = 'with C extension' + else: + help_params['extension_modifier'] = 'without C extension' + help_msg = textwrap.dedent(HELP_TOPICS.get(topic, '')).strip() if help_msg: - print(help_msg % self.covpkg.__dict__) + print(help_msg.format(**help_params)) else: print("Don't know topic %r" % topic) @@ -650,35 +703,34 @@ HELP_TOPICS = { -# ------------------------- -'help': """\ -Coverage.py, version %(__version__)s -Measure, collect, and report on code coverage in Python programs. + 'help': """\ + Coverage.py, version {__version__} {extension_modifier} + Measure, collect, and report on code coverage in Python programs. -usage: coverage <command> [options] [args] + usage: {program_name} <command> [options] [args] -Commands: - annotate Annotate source files with execution information. - combine Combine a number of data files. - erase Erase previously collected coverage data. - help Get help on using coverage.py. - html Create an HTML report. - report Report coverage stats on modules. - run Run a Python program and measure code execution. - xml Create an XML report of coverage results. + Commands: + annotate Annotate source files with execution information. + combine Combine a number of data files. + erase Erase previously collected coverage data. + help Get help on using coverage.py. + html Create an HTML report. + report Report coverage stats on modules. + run Run a Python program and measure code execution. + xml Create an XML report of coverage results. -Use "coverage help <command>" for detailed help on any command. -For full documentation, see %(__url__)s -""", -# ------------------------- -'minimum_help': """\ -Code coverage for Python. Use 'coverage help' for help. -""", -# ------------------------- -'version': """\ -Coverage.py, version %(__version__)s. -Documentation at %(__url__)s -""", + Use "{program_name} help <command>" for detailed help on any command. + For full documentation, see {__url__} + """, + + 'minimum_help': """\ + Code coverage for Python. Use '{program_name} help' for help. + """, + + 'version': """\ + Coverage.py, version {__version__} {extension_modifier} + Documentation at {__url__} + """, }