[pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci
This commit is contained in:
pre-commit-ci[bot] 2024-04-13 00:00:18 +00:00
parent 72ad6dc953
commit f4cd1ba0d6
813 changed files with 66015 additions and 58839 deletions

View file

@ -1,14 +1,11 @@
# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt
"""Central control stuff for coverage.py."""
from __future__ import annotations
import atexit
import collections
import contextlib
import os
import os.path
import platform
import signal
@ -16,31 +13,48 @@ import sys
import threading
import time
import warnings
from types import FrameType
from typing import (
cast,
Any, Callable, IO, Iterable, Iterator, List,
)
from typing import Any
from typing import Callable
from typing import cast
from typing import IO
from typing import Iterable
from typing import Iterator
from typing import List
from coverage import env
from coverage.annotate import AnnotateReporter
from coverage.collector import Collector, HAS_CTRACER
from coverage.config import CoverageConfig, read_coverage_config
from coverage.context import should_start_context_test_function, combine_context_switchers
from coverage.data import CoverageData, combine_parallel_data
from coverage.debug import (
DebugControl, NoDebugging, short_stack, write_formatted_info, relevant_environment_display,
)
from coverage.collector import Collector
from coverage.collector import HAS_CTRACER
from coverage.config import CoverageConfig
from coverage.config import read_coverage_config
from coverage.context import combine_context_switchers
from coverage.context import should_start_context_test_function
from coverage.data import combine_parallel_data
from coverage.data import CoverageData
from coverage.debug import DebugControl
from coverage.debug import NoDebugging
from coverage.debug import relevant_environment_display
from coverage.debug import short_stack
from coverage.debug import write_formatted_info
from coverage.disposition import disposition_debug_msg
from coverage.exceptions import ConfigError, CoverageException, CoverageWarning, PluginError
from coverage.files import PathAliases, abs_file, relative_filename, set_relative_directory
from coverage.exceptions import ConfigError
from coverage.exceptions import CoverageException
from coverage.exceptions import CoverageWarning
from coverage.exceptions import PluginError
from coverage.files import abs_file
from coverage.files import PathAliases
from coverage.files import relative_filename
from coverage.files import set_relative_directory
from coverage.html import HtmlReporter
from coverage.inorout import InOrOut
from coverage.jsonreport import JsonReporter
from coverage.lcovreport import LcovReporter
from coverage.misc import bool_or_none, join_regex
from coverage.misc import DefaultValue, ensure_dir_for_file, isolate_module
from coverage.misc import bool_or_none
from coverage.misc import DefaultValue
from coverage.misc import ensure_dir_for_file
from coverage.misc import isolate_module
from coverage.misc import join_regex
from coverage.multiproc import patch_multiprocessing
from coverage.plugin import FileReporter
from coverage.plugin_support import Plugins
@ -48,14 +62,19 @@ from coverage.python import PythonFileReporter
from coverage.report import SummaryReporter
from coverage.report_core import render_report
from coverage.results import Analysis
from coverage.types import (
FilePath, TConfigurable, TConfigSectionIn, TConfigValueIn, TConfigValueOut,
TFileDisposition, TLineNo, TMorf,
)
from coverage.types import FilePath
from coverage.types import TConfigSectionIn
from coverage.types import TConfigurable
from coverage.types import TConfigValueIn
from coverage.types import TConfigValueOut
from coverage.types import TFileDisposition
from coverage.types import TLineNo
from coverage.types import TMorf
from coverage.xmlreport import XmlReporter
os = isolate_module(os)
@contextlib.contextmanager
def override_config(cov: Coverage, **kwargs: TConfigValueIn) -> Iterator[None]:
"""Temporarily tweak the configuration of `cov`.
@ -72,9 +91,10 @@ def override_config(cov: Coverage, **kwargs: TConfigValueIn) -> Iterator[None]:
cov.config = original_config
DEFAULT_DATAFILE = DefaultValue("MISSING")
DEFAULT_DATAFILE = DefaultValue('MISSING')
_DEFAULT_DATAFILE = DEFAULT_DATAFILE # Just in case, for backwards compatibility
class Coverage(TConfigurable):
"""Programmatic access to coverage.py.
@ -323,10 +343,10 @@ class Coverage(TConfigurable):
# Create and configure the debugging controller.
self._debug = DebugControl(self.config.debug, self._debug_file, self.config.debug_file)
if self._debug.should("process"):
self._debug.write("Coverage._init")
if self._debug.should('process'):
self._debug.write('Coverage._init')
if "multiprocessing" in (self.config.concurrency or ()):
if 'multiprocessing' in (self.config.concurrency or ()):
# Multi-processing uses parallel for the subprocesses, so also use
# it for the main process.
self.config.parallel = True
@ -358,31 +378,31 @@ class Coverage(TConfigurable):
# "[run] _crash" will raise an exception if the value is close by in
# the call stack, for testing error handling.
if self.config._crash and self.config._crash in short_stack():
raise RuntimeError(f"Crashing because called by {self.config._crash}")
raise RuntimeError(f'Crashing because called by {self.config._crash}')
def _write_startup_debug(self) -> None:
"""Write out debug info at startup if needed."""
wrote_any = False
with self._debug.without_callers():
if self._debug.should("config"):
if self._debug.should('config'):
config_info = self.config.debug_info()
write_formatted_info(self._debug.write, "config", config_info)
write_formatted_info(self._debug.write, 'config', config_info)
wrote_any = True
if self._debug.should("sys"):
write_formatted_info(self._debug.write, "sys", self.sys_info())
if self._debug.should('sys'):
write_formatted_info(self._debug.write, 'sys', self.sys_info())
for plugin in self._plugins:
header = "sys: " + plugin._coverage_plugin_name
header = 'sys: ' + plugin._coverage_plugin_name
info = plugin.sys_info()
write_formatted_info(self._debug.write, header, info)
wrote_any = True
if self._debug.should("pybehave"):
write_formatted_info(self._debug.write, "pybehave", env.debug_info())
if self._debug.should('pybehave'):
write_formatted_info(self._debug.write, 'pybehave', env.debug_info())
wrote_any = True
if wrote_any:
write_formatted_info(self._debug.write, "end", ())
write_formatted_info(self._debug.write, 'end', ())
def _should_trace(self, filename: str, frame: FrameType) -> TFileDisposition:
"""Decide whether to trace execution in `filename`.
@ -392,7 +412,7 @@ class Coverage(TConfigurable):
"""
assert self._inorout is not None
disp = self._inorout.should_trace(filename, frame)
if self._debug.should("trace"):
if self._debug.should('trace'):
self._debug.write(disposition_debug_msg(disp))
return disp
@ -404,11 +424,11 @@ class Coverage(TConfigurable):
"""
assert self._inorout is not None
reason = self._inorout.check_include_omit_etc(filename, frame)
if self._debug.should("trace"):
if self._debug.should('trace'):
if not reason:
msg = f"Including {filename!r}"
msg = f'Including {filename!r}'
else:
msg = f"Not including {filename!r}: {reason}"
msg = f'Not including {filename!r}: {reason}'
self._debug.write(msg)
return not reason
@ -431,9 +451,9 @@ class Coverage(TConfigurable):
self._warnings.append(msg)
if slug:
msg = f"{msg} ({slug})"
if self._debug.should("pid"):
msg = f"[{os.getpid()}] {msg}"
msg = f'{msg} ({slug})'
if self._debug.should('pid'):
msg = f'[{os.getpid()}] {msg}'
warnings.warn(msg, category=CoverageWarning, stacklevel=2)
if once:
@ -512,15 +532,15 @@ class Coverage(TConfigurable):
"""Initialization for start()"""
# Construct the collector.
concurrency: list[str] = self.config.concurrency or []
if "multiprocessing" in concurrency:
if 'multiprocessing' in concurrency:
if self.config.config_file is None:
raise ConfigError("multiprocessing requires a configuration file")
raise ConfigError('multiprocessing requires a configuration file')
patch_multiprocessing(rcfile=self.config.config_file)
dycon = self.config.dynamic_context
if not dycon or dycon == "none":
if not dycon or dycon == 'none':
context_switchers = []
elif dycon == "test_function":
elif dycon == 'test_function':
context_switchers = [should_start_context_test_function]
else:
raise ConfigError(f"Don't understand dynamic_context setting: {dycon!r}")
@ -565,9 +585,9 @@ class Coverage(TConfigurable):
if self._plugins.file_tracers and not self._collector.supports_plugins:
self._warn(
"Plugin file tracers ({}) aren't supported with {}".format(
", ".join(
', '.join(
plugin._coverage_plugin_name
for plugin in self._plugins.file_tracers
for plugin in self._plugins.file_tracers
),
self._collector.tracer_name(),
),
@ -579,7 +599,7 @@ class Coverage(TConfigurable):
self._inorout = InOrOut(
config=self.config,
warn=self._warn,
debug=(self._debug if self._debug.should("trace") else None),
debug=(self._debug if self._debug.should('trace') else None),
include_namespace_packages=self.config.include_namespace_packages,
)
self._inorout.plugins = self._plugins
@ -676,18 +696,18 @@ class Coverage(TConfigurable):
finally:
self.stop()
def _atexit(self, event: str = "atexit") -> None:
def _atexit(self, event: str = 'atexit') -> None:
"""Clean up on process shutdown."""
if self._debug.should("process"):
self._debug.write(f"{event}: pid: {os.getpid()}, instance: {self!r}")
if self._debug.should('process'):
self._debug.write(f'{event}: pid: {os.getpid()}, instance: {self!r}')
if self._started:
self.stop()
if self._auto_save or event == "sigterm":
if self._auto_save or event == 'sigterm':
self.save()
def _on_sigterm(self, signum_unused: int, frame_unused: FrameType | None) -> None:
"""A handler for signal.SIGTERM."""
self._atexit("sigterm")
self._atexit('sigterm')
# Statements after here won't be seen by metacov because we just wrote
# the data, and are about to kill the process.
signal.signal(signal.SIGTERM, self._old_sigterm) # pragma: not covered
@ -724,21 +744,21 @@ class Coverage(TConfigurable):
"""
if not self._started: # pragma: part started
raise CoverageException("Cannot switch context, coverage is not started")
raise CoverageException('Cannot switch context, coverage is not started')
assert self._collector is not None
if self._collector.should_start_context:
self._warn("Conflicting dynamic contexts", slug="dynamic-conflict", once=True)
self._warn('Conflicting dynamic contexts', slug='dynamic-conflict', once=True)
self._collector.switch_context(new_context)
def clear_exclude(self, which: str = "exclude") -> None:
def clear_exclude(self, which: str = 'exclude') -> None:
"""Clear the exclude list."""
self._init()
setattr(self.config, which + "_list", [])
setattr(self.config, which + '_list', [])
self._exclude_regex_stale()
def exclude(self, regex: str, which: str = "exclude") -> None:
def exclude(self, regex: str, which: str = 'exclude') -> None:
"""Exclude source lines from execution consideration.
A number of lists of regular expressions are maintained. Each list
@ -754,7 +774,7 @@ class Coverage(TConfigurable):
"""
self._init()
excl_list = getattr(self.config, which + "_list")
excl_list = getattr(self.config, which + '_list')
excl_list.append(regex)
self._exclude_regex_stale()
@ -765,11 +785,11 @@ class Coverage(TConfigurable):
def _exclude_regex(self, which: str) -> str:
"""Return a regex string for the given exclusion list."""
if which not in self._exclude_re:
excl_list = getattr(self.config, which + "_list")
excl_list = getattr(self.config, which + '_list')
self._exclude_re[which] = join_regex(excl_list)
return self._exclude_re[which]
def get_exclude_list(self, which: str = "exclude") -> list[str]:
def get_exclude_list(self, which: str = 'exclude') -> list[str]:
"""Return a list of excluded regex strings.
`which` indicates which list is desired. See :meth:`exclude` for the
@ -777,7 +797,7 @@ class Coverage(TConfigurable):
"""
self._init()
return cast(List[str], getattr(self.config, which + "_list"))
return cast(List[str], getattr(self.config, which + '_list'))
def save(self) -> None:
"""Save the collected coverage data to the data file."""
@ -787,7 +807,7 @@ class Coverage(TConfigurable):
def _make_aliases(self) -> PathAliases:
"""Create a PathAliases from our configuration."""
aliases = PathAliases(
debugfn=(self._debug.write if self._debug.should("pathmap") else None),
debugfn=(self._debug.write if self._debug.should('pathmap') else None),
relative=self.config.relative_files,
)
for paths in self.config.paths.values():
@ -884,7 +904,7 @@ class Coverage(TConfigurable):
# Find out if we got any data.
if not self._data and self._warn_no_data:
self._warn("No data was collected.", slug="no-data-collected")
self._warn('No data was collected.', slug='no-data-collected')
# Touch all the files that could have executed, so that we can
# mark completely un-executed files as 0% covered.
@ -952,7 +972,7 @@ class Coverage(TConfigurable):
"""Get a FileReporter for a module or file name."""
assert self._data is not None
plugin = None
file_reporter: str | FileReporter = "python"
file_reporter: str | FileReporter = 'python'
if isinstance(morf, str):
mapped_morf = self._file_mapper(morf)
@ -964,12 +984,12 @@ class Coverage(TConfigurable):
file_reporter = plugin.file_reporter(mapped_morf)
if file_reporter is None:
raise PluginError(
"Plugin {!r} did not provide a file reporter for {!r}.".format(
'Plugin {!r} did not provide a file reporter for {!r}.'.format(
plugin._coverage_plugin_name, morf,
),
)
if file_reporter == "python":
if file_reporter == 'python':
file_reporter = PythonFileReporter(morf, self)
assert isinstance(file_reporter, FileReporter)
@ -1290,36 +1310,37 @@ class Coverage(TConfigurable):
for plugin in plugins:
entry = plugin._coverage_plugin_name
if not plugin._coverage_enabled:
entry += " (disabled)"
entry += ' (disabled)'
entries.append(entry)
return entries
info = [
("coverage_version", covmod.__version__),
("coverage_module", covmod.__file__),
("core", self._collector.tracer_name() if self._collector is not None else "-none-"),
("CTracer", "available" if HAS_CTRACER else "unavailable"),
("plugins.file_tracers", plugin_info(self._plugins.file_tracers)),
("plugins.configurers", plugin_info(self._plugins.configurers)),
("plugins.context_switchers", plugin_info(self._plugins.context_switchers)),
("configs_attempted", self.config.attempted_config_files),
("configs_read", self.config.config_files_read),
("config_file", self.config.config_file),
("config_contents",
repr(self.config._config_contents) if self.config._config_contents else "-none-",
('coverage_version', covmod.__version__),
('coverage_module', covmod.__file__),
('core', self._collector.tracer_name() if self._collector is not None else '-none-'),
('CTracer', 'available' if HAS_CTRACER else 'unavailable'),
('plugins.file_tracers', plugin_info(self._plugins.file_tracers)),
('plugins.configurers', plugin_info(self._plugins.configurers)),
('plugins.context_switchers', plugin_info(self._plugins.context_switchers)),
('configs_attempted', self.config.attempted_config_files),
('configs_read', self.config.config_files_read),
('config_file', self.config.config_file),
(
'config_contents',
repr(self.config._config_contents) if self.config._config_contents else '-none-',
),
("data_file", self._data.data_filename() if self._data is not None else "-none-"),
("python", sys.version.replace("\n", "")),
("platform", platform.platform()),
("implementation", platform.python_implementation()),
("executable", sys.executable),
("def_encoding", sys.getdefaultencoding()),
("fs_encoding", sys.getfilesystemencoding()),
("pid", os.getpid()),
("cwd", os.getcwd()),
("path", sys.path),
("environment", [f"{k} = {v}" for k, v in relevant_environment_display(os.environ)]),
("command_line", " ".join(getattr(sys, "argv", ["-none-"]))),
('data_file', self._data.data_filename() if self._data is not None else '-none-'),
('python', sys.version.replace('\n', '')),
('platform', platform.platform()),
('implementation', platform.python_implementation()),
('executable', sys.executable),
('def_encoding', sys.getdefaultencoding()),
('fs_encoding', sys.getfilesystemencoding()),
('pid', os.getpid()),
('cwd', os.getcwd()),
('path', sys.path),
('environment', [f'{k} = {v}' for k, v in relevant_environment_display(os.environ)]),
('command_line', ' '.join(getattr(sys, 'argv', ['-none-']))),
]
if self._inorout is not None:
@ -1332,12 +1353,12 @@ class Coverage(TConfigurable):
# Mega debugging...
# $set_env.py: COVERAGE_DEBUG_CALLS - Lots and lots of output about calls to Coverage.
if int(os.getenv("COVERAGE_DEBUG_CALLS", 0)): # pragma: debugging
if int(os.getenv('COVERAGE_DEBUG_CALLS', 0)): # pragma: debugging
from coverage.debug import decorate_methods, show_calls
Coverage = decorate_methods( # type: ignore[misc]
show_calls(show_args=True),
butnot=["get_data"],
butnot=['get_data'],
)(Coverage)
@ -1364,7 +1385,7 @@ def process_startup() -> Coverage | None:
not started by this call.
"""
cps = os.getenv("COVERAGE_PROCESS_START")
cps = os.getenv('COVERAGE_PROCESS_START')
if not cps:
# No request for coverage, nothing to do.
return None
@ -1378,7 +1399,7 @@ def process_startup() -> Coverage | None:
#
# https://github.com/nedbat/coveragepy/issues/340 has more details.
if hasattr(process_startup, "coverage"):
if hasattr(process_startup, 'coverage'):
# We've annotated this function before, so we must have already
# started coverage.py in this process. Nothing to do.
return None
@ -1396,6 +1417,6 @@ def process_startup() -> Coverage | None:
def _prevent_sub_process_measurement() -> None:
"""Stop any subprocess auto-measurement from writing data."""
auto_created_coverage = getattr(process_startup, "coverage", None)
auto_created_coverage = getattr(process_startup, 'coverage', None)
if auto_created_coverage is not None:
auto_created_coverage._auto_save = False