mirror of
https://github.com/pre-commit/pre-commit-hooks.git
synced 2026-04-08 20:44:18 +00:00
[pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
This commit is contained in:
parent
72ad6dc953
commit
f4cd1ba0d6
813 changed files with 66015 additions and 58839 deletions
|
|
@ -1,20 +1,18 @@
|
|||
# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
|
||||
# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt
|
||||
|
||||
"""Command-line support for coverage.py."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import glob
|
||||
import optparse # pylint: disable=deprecated-module
|
||||
import os
|
||||
import os.path
|
||||
import shlex
|
||||
import sys
|
||||
import textwrap
|
||||
import traceback
|
||||
|
||||
from typing import cast, Any, NoReturn
|
||||
from typing import Any
|
||||
from typing import cast
|
||||
from typing import NoReturn
|
||||
|
||||
import coverage
|
||||
from coverage import Coverage
|
||||
|
|
@ -22,16 +20,23 @@ from coverage import env
|
|||
from coverage.collector import HAS_CTRACER
|
||||
from coverage.config import CoverageConfig
|
||||
from coverage.control import DEFAULT_DATAFILE
|
||||
from coverage.data import combinable_files, debug_data_file
|
||||
from coverage.debug import info_header, short_stack, write_formatted_info
|
||||
from coverage.exceptions import _BaseCoverageException, _ExceptionDuringRun, NoSource
|
||||
from coverage.data import combinable_files
|
||||
from coverage.data import debug_data_file
|
||||
from coverage.debug import info_header
|
||||
from coverage.debug import short_stack
|
||||
from coverage.debug import write_formatted_info
|
||||
from coverage.exceptions import _BaseCoverageException
|
||||
from coverage.exceptions import _ExceptionDuringRun
|
||||
from coverage.exceptions import NoSource
|
||||
from coverage.execfile import PyRunner
|
||||
from coverage.results import Numbers, should_fail_under
|
||||
from coverage.results import Numbers
|
||||
from coverage.results import should_fail_under
|
||||
from coverage.version import __url__
|
||||
|
||||
# When adding to this file, alphabetization is important. Look for
|
||||
# "alphabetize" comments throughout.
|
||||
|
||||
|
||||
class Opts:
|
||||
"""A namespace class for individual options we'll build parsers from."""
|
||||
|
||||
|
|
@ -39,193 +44,193 @@ class Opts:
|
|||
# appears on the command line.
|
||||
|
||||
append = optparse.make_option(
|
||||
"-a", "--append", action="store_true",
|
||||
help="Append coverage data to .coverage, otherwise it starts clean each time.",
|
||||
'-a', '--append', action='store_true',
|
||||
help='Append coverage data to .coverage, otherwise it starts clean each time.',
|
||||
)
|
||||
branch = optparse.make_option(
|
||||
"", "--branch", action="store_true",
|
||||
help="Measure branch coverage in addition to statement coverage.",
|
||||
'', '--branch', action='store_true',
|
||||
help='Measure branch coverage in addition to statement coverage.',
|
||||
)
|
||||
concurrency = optparse.make_option(
|
||||
"", "--concurrency", action="store", metavar="LIBS",
|
||||
'', '--concurrency', action='store', metavar='LIBS',
|
||||
help=(
|
||||
"Properly measure code using a concurrency library. " +
|
||||
"Valid values are: {}, or a comma-list of them."
|
||||
).format(", ".join(sorted(CoverageConfig.CONCURRENCY_CHOICES))),
|
||||
'Properly measure code using a concurrency library. ' +
|
||||
'Valid values are: {}, or a comma-list of them.'
|
||||
).format(', '.join(sorted(CoverageConfig.CONCURRENCY_CHOICES))),
|
||||
)
|
||||
context = optparse.make_option(
|
||||
"", "--context", action="store", metavar="LABEL",
|
||||
help="The context label to record for this coverage run.",
|
||||
'', '--context', action='store', metavar='LABEL',
|
||||
help='The context label to record for this coverage run.',
|
||||
)
|
||||
contexts = optparse.make_option(
|
||||
"", "--contexts", action="store", metavar="REGEX1,REGEX2,...",
|
||||
'', '--contexts', action='store', metavar='REGEX1,REGEX2,...',
|
||||
help=(
|
||||
"Only display data from lines covered in the given contexts. " +
|
||||
"Accepts Python regexes, which must be quoted."
|
||||
'Only display data from lines covered in the given contexts. ' +
|
||||
'Accepts Python regexes, which must be quoted.'
|
||||
),
|
||||
)
|
||||
datafile = optparse.make_option(
|
||||
"", "--data-file", action="store", metavar="DATAFILE",
|
||||
'', '--data-file', action='store', metavar='DATAFILE',
|
||||
help=(
|
||||
"Base name of the data files to operate on. " +
|
||||
'Base name of the data files to operate on. ' +
|
||||
"Defaults to '.coverage'. [env: COVERAGE_FILE]"
|
||||
),
|
||||
)
|
||||
datafle_input = optparse.make_option(
|
||||
"", "--data-file", action="store", metavar="INFILE",
|
||||
'', '--data-file', action='store', metavar='INFILE',
|
||||
help=(
|
||||
"Read coverage data for report generation from this file. " +
|
||||
'Read coverage data for report generation from this file. ' +
|
||||
"Defaults to '.coverage'. [env: COVERAGE_FILE]"
|
||||
),
|
||||
)
|
||||
datafile_output = optparse.make_option(
|
||||
"", "--data-file", action="store", metavar="OUTFILE",
|
||||
'', '--data-file', action='store', metavar='OUTFILE',
|
||||
help=(
|
||||
"Write the recorded coverage data to this file. " +
|
||||
'Write the recorded coverage data to this file. ' +
|
||||
"Defaults to '.coverage'. [env: COVERAGE_FILE]"
|
||||
),
|
||||
)
|
||||
debug = optparse.make_option(
|
||||
"", "--debug", action="store", metavar="OPTS",
|
||||
help="Debug options, separated by commas. [env: COVERAGE_DEBUG]",
|
||||
'', '--debug', action='store', metavar='OPTS',
|
||||
help='Debug options, separated by commas. [env: COVERAGE_DEBUG]',
|
||||
)
|
||||
directory = optparse.make_option(
|
||||
"-d", "--directory", action="store", metavar="DIR",
|
||||
help="Write the output files to DIR.",
|
||||
'-d', '--directory', action='store', metavar='DIR',
|
||||
help='Write the output files to DIR.',
|
||||
)
|
||||
fail_under = optparse.make_option(
|
||||
"", "--fail-under", action="store", metavar="MIN", type="float",
|
||||
help="Exit with a status of 2 if the total coverage is less than MIN.",
|
||||
'', '--fail-under', action='store', metavar='MIN', type='float',
|
||||
help='Exit with a status of 2 if the total coverage is less than MIN.',
|
||||
)
|
||||
format = optparse.make_option(
|
||||
"", "--format", action="store", metavar="FORMAT",
|
||||
help="Output format, either text (default), markdown, or total.",
|
||||
'', '--format', action='store', metavar='FORMAT',
|
||||
help='Output format, either text (default), markdown, or total.',
|
||||
)
|
||||
help = optparse.make_option(
|
||||
"-h", "--help", action="store_true",
|
||||
help="Get help on this command.",
|
||||
'-h', '--help', action='store_true',
|
||||
help='Get help on this command.',
|
||||
)
|
||||
ignore_errors = optparse.make_option(
|
||||
"-i", "--ignore-errors", action="store_true",
|
||||
help="Ignore errors while reading source files.",
|
||||
'-i', '--ignore-errors', action='store_true',
|
||||
help='Ignore errors while reading source files.',
|
||||
)
|
||||
include = optparse.make_option(
|
||||
"", "--include", action="store", metavar="PAT1,PAT2,...",
|
||||
'', '--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."
|
||||
'Include only files whose paths match one of these patterns. ' +
|
||||
'Accepts shell-style wildcards, which must be quoted.'
|
||||
),
|
||||
)
|
||||
keep = optparse.make_option(
|
||||
"", "--keep", action="store_true",
|
||||
help="Keep original coverage files, otherwise they are deleted.",
|
||||
'', '--keep', action='store_true',
|
||||
help='Keep original coverage files, otherwise they are deleted.',
|
||||
)
|
||||
pylib = optparse.make_option(
|
||||
"-L", "--pylib", action="store_true",
|
||||
'-L', '--pylib', action='store_true',
|
||||
help=(
|
||||
"Measure coverage even inside the Python installed library, " +
|
||||
'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",
|
||||
'-m', '--show-missing', action='store_true',
|
||||
help="Show line numbers of statements in each module that weren't executed.",
|
||||
)
|
||||
module = optparse.make_option(
|
||||
"-m", "--module", action="store_true",
|
||||
'-m', '--module', action='store_true',
|
||||
help=(
|
||||
"<pyfile> is an importable Python module, not a script path, " +
|
||||
'<pyfile> is an importable Python module, not a script path, ' +
|
||||
"to be run as 'python -m' would run it."
|
||||
),
|
||||
)
|
||||
omit = optparse.make_option(
|
||||
"", "--omit", action="store", metavar="PAT1,PAT2,...",
|
||||
'', '--omit', action='store', metavar='PAT1,PAT2,...',
|
||||
help=(
|
||||
"Omit files whose paths match one of these patterns. " +
|
||||
"Accepts shell-style wildcards, which must be quoted."
|
||||
'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",
|
||||
'-o', '', action='store', dest='outfile', metavar='OUTFILE',
|
||||
help="Write the XML report to this file. Defaults to 'coverage.xml'",
|
||||
)
|
||||
output_json = optparse.make_option(
|
||||
"-o", "", action="store", dest="outfile", metavar="OUTFILE",
|
||||
'-o', '', action='store', dest='outfile', metavar='OUTFILE',
|
||||
help="Write the JSON report to this file. Defaults to 'coverage.json'",
|
||||
)
|
||||
output_lcov = optparse.make_option(
|
||||
"-o", "", action="store", dest="outfile", metavar="OUTFILE",
|
||||
'-o', '', action='store', dest='outfile', metavar='OUTFILE',
|
||||
help="Write the LCOV report to this file. Defaults to 'coverage.lcov'",
|
||||
)
|
||||
json_pretty_print = optparse.make_option(
|
||||
"", "--pretty-print", action="store_true",
|
||||
help="Format the JSON for human readers.",
|
||||
'', '--pretty-print', action='store_true',
|
||||
help='Format the JSON for human readers.',
|
||||
)
|
||||
parallel_mode = optparse.make_option(
|
||||
"-p", "--parallel-mode", action="store_true",
|
||||
'-p', '--parallel-mode', action='store_true',
|
||||
help=(
|
||||
"Append the machine name, process id and random number to the " +
|
||||
"data file name to simplify collecting data from " +
|
||||
"many processes."
|
||||
'Append the machine name, process id and random number to the ' +
|
||||
'data file name to simplify collecting data from ' +
|
||||
'many processes.'
|
||||
),
|
||||
)
|
||||
precision = optparse.make_option(
|
||||
"", "--precision", action="store", metavar="N", type=int,
|
||||
'', '--precision', action='store', metavar='N', type=int,
|
||||
help=(
|
||||
"Number of digits after the decimal point to display for " +
|
||||
"reported coverage percentages."
|
||||
'Number of digits after the decimal point to display for ' +
|
||||
'reported coverage percentages.'
|
||||
),
|
||||
)
|
||||
quiet = optparse.make_option(
|
||||
"-q", "--quiet", action="store_true",
|
||||
'-q', '--quiet', action='store_true',
|
||||
help="Don't print messages about what is happening.",
|
||||
)
|
||||
rcfile = optparse.make_option(
|
||||
"", "--rcfile", action="store",
|
||||
'', '--rcfile', action='store',
|
||||
help=(
|
||||
"Specify configuration file. " +
|
||||
'Specify configuration file. ' +
|
||||
"By default '.coveragerc', 'setup.cfg', 'tox.ini', and " +
|
||||
"'pyproject.toml' are tried. [env: COVERAGE_RCFILE]"
|
||||
),
|
||||
)
|
||||
show_contexts = optparse.make_option(
|
||||
"--show-contexts", action="store_true",
|
||||
help="Show contexts for covered lines.",
|
||||
'--show-contexts', action='store_true',
|
||||
help='Show contexts for covered lines.',
|
||||
)
|
||||
skip_covered = optparse.make_option(
|
||||
"--skip-covered", action="store_true",
|
||||
help="Skip files with 100% coverage.",
|
||||
'--skip-covered', action='store_true',
|
||||
help='Skip files with 100% coverage.',
|
||||
)
|
||||
no_skip_covered = optparse.make_option(
|
||||
"--no-skip-covered", action="store_false", dest="skip_covered",
|
||||
help="Disable --skip-covered.",
|
||||
'--no-skip-covered', action='store_false', dest='skip_covered',
|
||||
help='Disable --skip-covered.',
|
||||
)
|
||||
skip_empty = optparse.make_option(
|
||||
"--skip-empty", action="store_true",
|
||||
help="Skip files with no code.",
|
||||
'--skip-empty', action='store_true',
|
||||
help='Skip files with no code.',
|
||||
)
|
||||
sort = optparse.make_option(
|
||||
"--sort", action="store", metavar="COLUMN",
|
||||
'--sort', action='store', metavar='COLUMN',
|
||||
help=(
|
||||
"Sort the report by the named column: name, stmts, miss, branch, brpart, or cover. " +
|
||||
"Default is name."
|
||||
'Sort the report by the named column: name, stmts, miss, branch, brpart, or cover. ' +
|
||||
'Default is name.'
|
||||
),
|
||||
)
|
||||
source = optparse.make_option(
|
||||
"", "--source", action="store", metavar="SRC1,SRC2,...",
|
||||
help="A list of directories or importable names of code to measure.",
|
||||
'', '--source', action='store', metavar='SRC1,SRC2,...',
|
||||
help='A list of directories or importable names of code to measure.',
|
||||
)
|
||||
timid = optparse.make_option(
|
||||
"", "--timid", action="store_true",
|
||||
help="Use the slower Python trace function core.",
|
||||
'', '--timid', action='store_true',
|
||||
help='Use the slower Python trace function core.',
|
||||
)
|
||||
title = optparse.make_option(
|
||||
"", "--title", action="store", metavar="TITLE",
|
||||
help="A text string to use as the title on the HTML.",
|
||||
'', '--title', action='store', metavar='TITLE',
|
||||
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.",
|
||||
'', '--version', action='store_true',
|
||||
help='Display version information and exit.',
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -238,7 +243,7 @@ class CoverageOptionParser(optparse.OptionParser):
|
|||
"""
|
||||
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
||||
kwargs["add_help_option"] = False
|
||||
kwargs['add_help_option'] = False
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_defaults(
|
||||
# Keep these arguments alphabetized by their names.
|
||||
|
|
@ -330,7 +335,7 @@ class CmdOptionParser(CoverageOptionParser):
|
|||
|
||||
"""
|
||||
if usage:
|
||||
usage = "%prog " + usage
|
||||
usage = '%prog ' + usage
|
||||
super().__init__(
|
||||
usage=usage,
|
||||
description=description,
|
||||
|
|
@ -342,7 +347,7 @@ class CmdOptionParser(CoverageOptionParser):
|
|||
def __eq__(self, other: str) -> bool: # type: ignore[override]
|
||||
# A convenience equality, so that I can put strings in unit test
|
||||
# results, and they will compare equal to objects.
|
||||
return (other == f"<CmdOptionParser:{self.cmd}>")
|
||||
return (other == f'<CmdOptionParser:{self.cmd}>')
|
||||
|
||||
__hash__ = None # type: ignore[assignment]
|
||||
|
||||
|
|
@ -351,7 +356,7 @@ class CmdOptionParser(CoverageOptionParser):
|
|||
program_name = super().get_prog_name()
|
||||
|
||||
# Include the sub-command for this parser as part of the command.
|
||||
return f"{program_name} {self.cmd}"
|
||||
return f'{program_name} {self.cmd}'
|
||||
|
||||
# In lists of Opts, keep them alphabetized by the option names as they appear
|
||||
# on the command line, since these lists determine the order of the options in
|
||||
|
|
@ -359,6 +364,7 @@ class CmdOptionParser(CoverageOptionParser):
|
|||
#
|
||||
# In COMMANDS, keep the keys (command names) alphabetized.
|
||||
|
||||
|
||||
GLOBAL_ARGS = [
|
||||
Opts.debug,
|
||||
Opts.help,
|
||||
|
|
@ -366,72 +372,72 @@ GLOBAL_ARGS = [
|
|||
]
|
||||
|
||||
COMMANDS = {
|
||||
"annotate": CmdOptionParser(
|
||||
"annotate",
|
||||
'annotate': CmdOptionParser(
|
||||
'annotate',
|
||||
[
|
||||
Opts.directory,
|
||||
Opts.datafle_input,
|
||||
Opts.ignore_errors,
|
||||
Opts.include,
|
||||
Opts.omit,
|
||||
] + GLOBAL_ARGS,
|
||||
usage="[options] [modules]",
|
||||
] + 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 !."
|
||||
'Make annotated copies of the given files, marking statements that are executed ' +
|
||||
'with > and statements that are missed with !.'
|
||||
),
|
||||
),
|
||||
|
||||
"combine": CmdOptionParser(
|
||||
"combine",
|
||||
'combine': CmdOptionParser(
|
||||
'combine',
|
||||
[
|
||||
Opts.append,
|
||||
Opts.datafile,
|
||||
Opts.keep,
|
||||
Opts.quiet,
|
||||
] + GLOBAL_ARGS,
|
||||
usage="[options] <path1> <path2> ... <pathN>",
|
||||
] + GLOBAL_ARGS,
|
||||
usage='[options] <path1> <path2> ... <pathN>',
|
||||
description=(
|
||||
"Combine data from multiple coverage files. " +
|
||||
"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. " +
|
||||
'Combine data from multiple coverage files. ' +
|
||||
'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."
|
||||
'directory are combined.'
|
||||
),
|
||||
),
|
||||
|
||||
"debug": CmdOptionParser(
|
||||
"debug", GLOBAL_ARGS,
|
||||
usage="<topic>",
|
||||
'debug': CmdOptionParser(
|
||||
'debug', GLOBAL_ARGS,
|
||||
usage='<topic>',
|
||||
description=(
|
||||
"Display information about the internals of coverage.py, " +
|
||||
"for diagnosing problems. " +
|
||||
"Topics are: " +
|
||||
"'data' to show a summary of the collected data; " +
|
||||
"'sys' to show installation information; " +
|
||||
"'config' to show the configuration; " +
|
||||
"'premain' to show what is calling coverage; " +
|
||||
"'pybehave' to show internal flags describing Python behavior."
|
||||
'Display information about the internals of coverage.py, ' +
|
||||
'for diagnosing problems. ' +
|
||||
'Topics are: ' +
|
||||
"'data' to show a summary of the collected data; " +
|
||||
"'sys' to show installation information; " +
|
||||
"'config' to show the configuration; " +
|
||||
"'premain' to show what is calling coverage; " +
|
||||
"'pybehave' to show internal flags describing Python behavior."
|
||||
),
|
||||
),
|
||||
|
||||
"erase": CmdOptionParser(
|
||||
"erase",
|
||||
'erase': CmdOptionParser(
|
||||
'erase',
|
||||
[
|
||||
Opts.datafile,
|
||||
] + GLOBAL_ARGS,
|
||||
description="Erase previously collected coverage data.",
|
||||
] + GLOBAL_ARGS,
|
||||
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.contexts,
|
||||
Opts.directory,
|
||||
|
|
@ -447,17 +453,17 @@ COMMANDS = {
|
|||
Opts.no_skip_covered,
|
||||
Opts.skip_empty,
|
||||
Opts.title,
|
||||
] + GLOBAL_ARGS,
|
||||
usage="[options] [modules]",
|
||||
] + GLOBAL_ARGS,
|
||||
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."
|
||||
'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.'
|
||||
),
|
||||
),
|
||||
|
||||
"json": CmdOptionParser(
|
||||
"json",
|
||||
'json': CmdOptionParser(
|
||||
'json',
|
||||
[
|
||||
Opts.contexts,
|
||||
Opts.datafle_input,
|
||||
|
|
@ -469,13 +475,13 @@ COMMANDS = {
|
|||
Opts.json_pretty_print,
|
||||
Opts.quiet,
|
||||
Opts.show_contexts,
|
||||
] + GLOBAL_ARGS,
|
||||
usage="[options] [modules]",
|
||||
description="Generate a JSON report of coverage results.",
|
||||
] + GLOBAL_ARGS,
|
||||
usage='[options] [modules]',
|
||||
description='Generate a JSON report of coverage results.',
|
||||
),
|
||||
|
||||
"lcov": CmdOptionParser(
|
||||
"lcov",
|
||||
'lcov': CmdOptionParser(
|
||||
'lcov',
|
||||
[
|
||||
Opts.datafle_input,
|
||||
Opts.fail_under,
|
||||
|
|
@ -484,13 +490,13 @@ COMMANDS = {
|
|||
Opts.output_lcov,
|
||||
Opts.omit,
|
||||
Opts.quiet,
|
||||
] + GLOBAL_ARGS,
|
||||
usage="[options] [modules]",
|
||||
description="Generate an LCOV report of coverage results.",
|
||||
] + GLOBAL_ARGS,
|
||||
usage='[options] [modules]',
|
||||
description='Generate an LCOV report of coverage results.',
|
||||
),
|
||||
|
||||
"report": CmdOptionParser(
|
||||
"report",
|
||||
'report': CmdOptionParser(
|
||||
'report',
|
||||
[
|
||||
Opts.contexts,
|
||||
Opts.datafle_input,
|
||||
|
|
@ -505,13 +511,13 @@ COMMANDS = {
|
|||
Opts.skip_covered,
|
||||
Opts.no_skip_covered,
|
||||
Opts.skip_empty,
|
||||
] + GLOBAL_ARGS,
|
||||
usage="[options] [modules]",
|
||||
description="Report coverage statistics on modules.",
|
||||
] + GLOBAL_ARGS,
|
||||
usage='[options] [modules]',
|
||||
description='Report coverage statistics on modules.',
|
||||
),
|
||||
|
||||
"run": CmdOptionParser(
|
||||
"run",
|
||||
'run': CmdOptionParser(
|
||||
'run',
|
||||
[
|
||||
Opts.append,
|
||||
Opts.branch,
|
||||
|
|
@ -525,13 +531,13 @@ COMMANDS = {
|
|||
Opts.parallel_mode,
|
||||
Opts.source,
|
||||
Opts.timid,
|
||||
] + GLOBAL_ARGS,
|
||||
usage="[options] <pyfile> [program options]",
|
||||
description="Run a Python program, measuring code execution.",
|
||||
] + GLOBAL_ARGS,
|
||||
usage='[options] <pyfile> [program options]',
|
||||
description='Run a Python program, measuring code execution.',
|
||||
),
|
||||
|
||||
"xml": CmdOptionParser(
|
||||
"xml",
|
||||
'xml': CmdOptionParser(
|
||||
'xml',
|
||||
[
|
||||
Opts.datafle_input,
|
||||
Opts.fail_under,
|
||||
|
|
@ -541,9 +547,9 @@ COMMANDS = {
|
|||
Opts.output_xml,
|
||||
Opts.quiet,
|
||||
Opts.skip_empty,
|
||||
] + GLOBAL_ARGS,
|
||||
usage="[options] [modules]",
|
||||
description="Generate an XML report of coverage results.",
|
||||
] + GLOBAL_ARGS,
|
||||
usage='[options] [modules]',
|
||||
description='Generate an XML report of coverage results.',
|
||||
),
|
||||
}
|
||||
|
||||
|
|
@ -557,7 +563,7 @@ def show_help(
|
|||
assert error or topic or parser
|
||||
|
||||
program_path = sys.argv[0]
|
||||
if program_path.endswith(os.path.sep + "__main__.py"):
|
||||
if program_path.endswith(os.path.sep + '__main__.py'):
|
||||
# The path is the main module of a package; get that path instead.
|
||||
program_path = os.path.dirname(program_path)
|
||||
program_name = os.path.basename(program_path)
|
||||
|
|
@ -567,17 +573,17 @@ def show_help(
|
|||
# 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"
|
||||
auto_suffix = '-script.py'
|
||||
if program_name.endswith(auto_suffix):
|
||||
program_name = program_name[:-len(auto_suffix)]
|
||||
|
||||
help_params = dict(coverage.__dict__)
|
||||
help_params["__url__"] = __url__
|
||||
help_params["program_name"] = program_name
|
||||
help_params['__url__'] = __url__
|
||||
help_params['program_name'] = program_name
|
||||
if HAS_CTRACER:
|
||||
help_params["extension_modifier"] = "with C extension"
|
||||
help_params['extension_modifier'] = 'with C extension'
|
||||
else:
|
||||
help_params["extension_modifier"] = "without C extension"
|
||||
help_params['extension_modifier'] = 'without C extension'
|
||||
|
||||
if error:
|
||||
print(error, file=sys.stderr)
|
||||
|
|
@ -587,12 +593,12 @@ def show_help(
|
|||
print()
|
||||
else:
|
||||
assert topic is not None
|
||||
help_msg = textwrap.dedent(HELP_TOPICS.get(topic, "")).strip()
|
||||
help_msg = textwrap.dedent(HELP_TOPICS.get(topic, '')).strip()
|
||||
if help_msg:
|
||||
print(help_msg.format(**help_params))
|
||||
else:
|
||||
print(f"Don't know topic {topic!r}")
|
||||
print("Full documentation is at {__url__}".format(**help_params))
|
||||
print('Full documentation is at {__url__}'.format(**help_params))
|
||||
|
||||
|
||||
OK, ERR, FAIL_UNDER = 0, 1, 2
|
||||
|
|
@ -615,19 +621,19 @@ class CoverageScript:
|
|||
"""
|
||||
# Collect the command-line options.
|
||||
if not argv:
|
||||
show_help(topic="minimum_help")
|
||||
show_help(topic='minimum_help')
|
||||
return OK
|
||||
|
||||
# The command syntax we parse depends on the first argument. Global
|
||||
# switch syntax always starts with an option.
|
||||
parser: optparse.OptionParser | None
|
||||
self.global_option = argv[0].startswith("-")
|
||||
self.global_option = argv[0].startswith('-')
|
||||
if self.global_option:
|
||||
parser = GlobalOptionParser()
|
||||
else:
|
||||
parser = COMMANDS.get(argv[0])
|
||||
if not parser:
|
||||
show_help(f"Unknown command: {argv[0]!r}")
|
||||
show_help(f'Unknown command: {argv[0]!r}')
|
||||
return ERR
|
||||
argv = argv[1:]
|
||||
|
||||
|
|
@ -648,7 +654,7 @@ class CoverageScript:
|
|||
contexts = unshell_list(options.contexts)
|
||||
|
||||
if options.concurrency is not None:
|
||||
concurrency = options.concurrency.split(",")
|
||||
concurrency = options.concurrency.split(',')
|
||||
else:
|
||||
concurrency = None
|
||||
|
||||
|
|
@ -670,17 +676,17 @@ class CoverageScript:
|
|||
messages=not options.quiet,
|
||||
)
|
||||
|
||||
if options.action == "debug":
|
||||
if options.action == 'debug':
|
||||
return self.do_debug(args)
|
||||
|
||||
elif options.action == "erase":
|
||||
elif options.action == 'erase':
|
||||
self.coverage.erase()
|
||||
return OK
|
||||
|
||||
elif options.action == "run":
|
||||
elif options.action == 'run':
|
||||
return self.do_run(options, args)
|
||||
|
||||
elif options.action == "combine":
|
||||
elif options.action == 'combine':
|
||||
if options.append:
|
||||
self.coverage.load()
|
||||
data_paths = args or None
|
||||
|
|
@ -699,12 +705,12 @@ class CoverageScript:
|
|||
|
||||
# We need to be able to import from the current directory, because
|
||||
# plugins may try to, for example, to read Django settings.
|
||||
sys.path.insert(0, "")
|
||||
sys.path.insert(0, '')
|
||||
|
||||
self.coverage.load()
|
||||
|
||||
total = None
|
||||
if options.action == "report":
|
||||
if options.action == 'report':
|
||||
total = self.coverage.report(
|
||||
precision=options.precision,
|
||||
show_missing=options.show_missing,
|
||||
|
|
@ -714,9 +720,9 @@ class CoverageScript:
|
|||
output_format=options.format,
|
||||
**report_args,
|
||||
)
|
||||
elif options.action == "annotate":
|
||||
elif options.action == 'annotate':
|
||||
self.coverage.annotate(directory=options.directory, **report_args)
|
||||
elif options.action == "html":
|
||||
elif options.action == 'html':
|
||||
total = self.coverage.html_report(
|
||||
directory=options.directory,
|
||||
precision=options.precision,
|
||||
|
|
@ -726,20 +732,20 @@ class CoverageScript:
|
|||
title=options.title,
|
||||
**report_args,
|
||||
)
|
||||
elif options.action == "xml":
|
||||
elif options.action == 'xml':
|
||||
total = self.coverage.xml_report(
|
||||
outfile=options.outfile,
|
||||
skip_empty=options.skip_empty,
|
||||
**report_args,
|
||||
)
|
||||
elif options.action == "json":
|
||||
elif options.action == 'json':
|
||||
total = self.coverage.json_report(
|
||||
outfile=options.outfile,
|
||||
pretty_print=options.pretty_print,
|
||||
show_contexts=options.show_contexts,
|
||||
**report_args,
|
||||
)
|
||||
elif options.action == "lcov":
|
||||
elif options.action == 'lcov':
|
||||
total = self.coverage.lcov_report(
|
||||
outfile=options.outfile,
|
||||
**report_args,
|
||||
|
|
@ -752,19 +758,19 @@ class CoverageScript:
|
|||
# Apply the command line fail-under options, and then use the config
|
||||
# value, so we can get fail_under from the config file.
|
||||
if options.fail_under is not None:
|
||||
self.coverage.set_option("report:fail_under", options.fail_under)
|
||||
self.coverage.set_option('report:fail_under', options.fail_under)
|
||||
if options.precision is not None:
|
||||
self.coverage.set_option("report:precision", options.precision)
|
||||
self.coverage.set_option('report:precision', options.precision)
|
||||
|
||||
fail_under = cast(float, self.coverage.get_option("report:fail_under"))
|
||||
precision = cast(int, self.coverage.get_option("report:precision"))
|
||||
fail_under = cast(float, self.coverage.get_option('report:fail_under'))
|
||||
precision = cast(int, self.coverage.get_option('report:precision'))
|
||||
if should_fail_under(total, fail_under, precision):
|
||||
msg = "total of {total} is less than fail-under={fail_under:.{p}f}".format(
|
||||
msg = 'total of {total} is less than fail-under={fail_under:.{p}f}'.format(
|
||||
total=Numbers(precision=precision).display_covered(total),
|
||||
fail_under=fail_under,
|
||||
p=precision,
|
||||
)
|
||||
print("Coverage failure:", msg)
|
||||
print('Coverage failure:', msg)
|
||||
return FAIL_UNDER
|
||||
|
||||
return OK
|
||||
|
|
@ -783,12 +789,12 @@ class CoverageScript:
|
|||
# Handle help.
|
||||
if options.help:
|
||||
if self.global_option:
|
||||
show_help(topic="help")
|
||||
show_help(topic='help')
|
||||
else:
|
||||
show_help(parser=parser)
|
||||
return True
|
||||
|
||||
if options.action == "help":
|
||||
if options.action == 'help':
|
||||
if args:
|
||||
for a in args:
|
||||
parser_maybe = COMMANDS.get(a)
|
||||
|
|
@ -797,12 +803,12 @@ class CoverageScript:
|
|||
else:
|
||||
show_help(topic=a)
|
||||
else:
|
||||
show_help(topic="help")
|
||||
show_help(topic='help')
|
||||
return True
|
||||
|
||||
# Handle version.
|
||||
if options.version:
|
||||
show_help(topic="version")
|
||||
show_help(topic='version')
|
||||
return True
|
||||
|
||||
return False
|
||||
|
|
@ -813,37 +819,37 @@ class CoverageScript:
|
|||
if not args:
|
||||
if options.module:
|
||||
# Specified -m with nothing else.
|
||||
show_help("No module specified for -m")
|
||||
show_help('No module specified for -m')
|
||||
return ERR
|
||||
command_line = cast(str, self.coverage.get_option("run:command_line"))
|
||||
command_line = cast(str, self.coverage.get_option('run:command_line'))
|
||||
if command_line is not None:
|
||||
args = shlex.split(command_line)
|
||||
if args and args[0] in {"-m", "--module"}:
|
||||
if args and args[0] in {'-m', '--module'}:
|
||||
options.module = True
|
||||
args = args[1:]
|
||||
if not args:
|
||||
show_help("Nothing to do.")
|
||||
show_help('Nothing to do.')
|
||||
return ERR
|
||||
|
||||
if options.append and self.coverage.get_option("run:parallel"):
|
||||
if options.append and self.coverage.get_option('run:parallel'):
|
||||
show_help("Can't append to data files in parallel mode.")
|
||||
return ERR
|
||||
|
||||
if options.concurrency == "multiprocessing":
|
||||
if options.concurrency == 'multiprocessing':
|
||||
# Can't set other run-affecting command line options with
|
||||
# multiprocessing.
|
||||
for opt_name in ["branch", "include", "omit", "pylib", "source", "timid"]:
|
||||
for opt_name in ['branch', 'include', 'omit', 'pylib', 'source', 'timid']:
|
||||
# As it happens, all of these options have no default, meaning
|
||||
# they will be None if they have not been specified.
|
||||
if getattr(options, opt_name) is not None:
|
||||
show_help(
|
||||
"Options affecting multiprocessing must only be specified " +
|
||||
"in a configuration file.\n" +
|
||||
f"Remove --{opt_name} from the command line.",
|
||||
'Options affecting multiprocessing must only be specified ' +
|
||||
'in a configuration file.\n' +
|
||||
f'Remove --{opt_name} from the command line.',
|
||||
)
|
||||
return ERR
|
||||
|
||||
os.environ["COVERAGE_RUN"] = "true"
|
||||
os.environ['COVERAGE_RUN'] = 'true'
|
||||
|
||||
runner = PyRunner(args, as_module=bool(options.module))
|
||||
runner.prepare()
|
||||
|
|
@ -870,28 +876,28 @@ class CoverageScript:
|
|||
"""Implementation of 'coverage debug'."""
|
||||
|
||||
if not args:
|
||||
show_help("What information would you like: config, data, sys, premain, pybehave?")
|
||||
show_help('What information would you like: config, data, sys, premain, pybehave?')
|
||||
return ERR
|
||||
if args[1:]:
|
||||
show_help("Only one topic at a time, please")
|
||||
show_help('Only one topic at a time, please')
|
||||
return ERR
|
||||
|
||||
if args[0] == "sys":
|
||||
write_formatted_info(print, "sys", self.coverage.sys_info())
|
||||
elif args[0] == "data":
|
||||
print(info_header("data"))
|
||||
if args[0] == 'sys':
|
||||
write_formatted_info(print, 'sys', self.coverage.sys_info())
|
||||
elif args[0] == 'data':
|
||||
print(info_header('data'))
|
||||
data_file = self.coverage.config.data_file
|
||||
debug_data_file(data_file)
|
||||
for filename in combinable_files(data_file):
|
||||
print("-----")
|
||||
print('-----')
|
||||
debug_data_file(filename)
|
||||
elif args[0] == "config":
|
||||
write_formatted_info(print, "config", self.coverage.config.debug_info())
|
||||
elif args[0] == "premain":
|
||||
print(info_header("premain"))
|
||||
elif args[0] == 'config':
|
||||
write_formatted_info(print, 'config', self.coverage.config.debug_info())
|
||||
elif args[0] == 'premain':
|
||||
print(info_header('premain'))
|
||||
print(short_stack(full=True))
|
||||
elif args[0] == "pybehave":
|
||||
write_formatted_info(print, "pybehave", env.debug_info())
|
||||
elif args[0] == 'pybehave':
|
||||
write_formatted_info(print, 'pybehave', env.debug_info())
|
||||
else:
|
||||
show_help(f"Don't know what you mean by {args[0]!r}")
|
||||
return ERR
|
||||
|
|
@ -910,7 +916,7 @@ def unshell_list(s: str) -> list[str] | None:
|
|||
# line, but (not) helpfully, the single quotes are included in the
|
||||
# argument, so we have to strip them off here.
|
||||
s = s.strip("'")
|
||||
return s.split(",")
|
||||
return s.split(',')
|
||||
|
||||
|
||||
def unglob_args(args: list[str]) -> list[str]:
|
||||
|
|
@ -918,7 +924,7 @@ def unglob_args(args: list[str]) -> list[str]:
|
|||
if env.WINDOWS:
|
||||
globbed = []
|
||||
for arg in args:
|
||||
if "?" in arg or "*" in arg:
|
||||
if '?' in arg or '*' in arg:
|
||||
globbed.extend(glob.glob(arg))
|
||||
else:
|
||||
globbed.append(arg)
|
||||
|
|
@ -927,7 +933,7 @@ def unglob_args(args: list[str]) -> list[str]:
|
|||
|
||||
|
||||
HELP_TOPICS = {
|
||||
"help": """\
|
||||
'help': """\
|
||||
Coverage.py, version {__version__} {extension_modifier}
|
||||
Measure, collect, and report on code coverage in Python programs.
|
||||
|
||||
|
|
@ -949,12 +955,12 @@ HELP_TOPICS = {
|
|||
Use "{program_name} help <command>" for detailed help on any command.
|
||||
""",
|
||||
|
||||
"minimum_help": (
|
||||
"Code coverage for Python, version {__version__} {extension_modifier}. " +
|
||||
'minimum_help': (
|
||||
'Code coverage for Python, version {__version__} {extension_modifier}. ' +
|
||||
"Use '{program_name} help' for help."
|
||||
),
|
||||
|
||||
"version": "Coverage.py, version {__version__} {extension_modifier}",
|
||||
'version': 'Coverage.py, version {__version__} {extension_modifier}',
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -987,11 +993,12 @@ def main(argv: list[str] | None = None) -> int | None:
|
|||
status = None
|
||||
return status
|
||||
|
||||
|
||||
# Profiling using ox_profile. Install it from GitHub:
|
||||
# pip install git+https://github.com/emin63/ox_profile.git
|
||||
#
|
||||
# $set_env.py: COVERAGE_PROFILE - Set to use ox_profile.
|
||||
_profile = os.getenv("COVERAGE_PROFILE")
|
||||
_profile = os.getenv('COVERAGE_PROFILE')
|
||||
if _profile: # pragma: debugging
|
||||
from ox_profile.core.launchers import SimpleLauncher # pylint: disable=import-error
|
||||
original_main = main
|
||||
|
|
@ -1004,6 +1011,6 @@ if _profile: # pragma: debugging
|
|||
try:
|
||||
return original_main(argv)
|
||||
finally:
|
||||
data, _ = profiler.query(re_filter="coverage", max_records=100)
|
||||
print(profiler.show(query=data, limit=100, sep="", col=""))
|
||||
data, _ = profiler.query(re_filter='coverage', max_records=100)
|
||||
print(profiler.show(query=data, limit=100, sep='', col=''))
|
||||
profiler.cancel()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue