BodyBalanceEvaluation/backend/venv/Lib/site-packages/coverage/patch.py
2025-07-31 17:23:05 +08:00

89 lines
3.4 KiB
Python

# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt
"""Invasive patches for coverage.py"""
from __future__ import annotations
import atexit
import os
from typing import Any, Callable, NoReturn, TYPE_CHECKING
from coverage import env
from coverage.exceptions import ConfigError, CoverageException
from coverage.files import create_pth_file
if TYPE_CHECKING:
from coverage import Coverage
from coverage.config import CoverageConfig
def apply_patches(cov: Coverage, config: CoverageConfig) -> None:
"""Apply invasive patches requested by `[run] patch=`."""
for patch in sorted(set(config.patch)):
if patch == "_exit":
def make_exit_patch(
old_exit: Callable[[int], NoReturn],
) -> Callable[[int], NoReturn]:
def coverage_os_exit_patch(status: int) -> NoReturn:
try:
cov.save()
except: # pylint: disable=bare-except
pass
old_exit(status)
return coverage_os_exit_patch
os._exit = make_exit_patch(os._exit) # type: ignore[assignment]
elif patch == "execv":
if env.WINDOWS:
raise CoverageException("patch=execv isn't supported yet on Windows.")
def make_execv_patch(fname: str, old_execv: Any) -> Any:
def coverage_execv_patch(*args: Any, **kwargs: Any) -> Any:
try:
cov.save()
except: # pylint: disable=bare-except
pass
if fname.endswith("e"):
# Assume the `env` argument is passed positionally.
new_env = args[-1]
# Pass our environment variable in the new environment.
new_env["COVERAGE_PROCESS_START"] = config.config_file
if env.TESTING:
# The subprocesses need to use the same core as the main process.
new_env["COVERAGE_CORE"] = os.getenv("COVERAGE_CORE")
# When testing locally, we need to honor the pyc file location
# or they get written to the .tox directories and pollute the
# next run with a different core.
if (
cache_prefix := os.getenv("PYTHONPYCACHEPREFIX")
) is not None:
new_env["PYTHONPYCACHEPREFIX"] = cache_prefix
# Without this, it fails on PyPy and Ubuntu.
new_env["PATH"] = os.getenv("PATH")
old_execv(*args, **kwargs)
return coverage_execv_patch
# All the exec* and spawn* functions eventually call execv or execve.
os.execv = make_execv_patch("execv", os.execv)
os.execve = make_execv_patch("execve", os.execve)
elif patch == "subprocess":
pth_file = create_pth_file()
assert pth_file is not None
atexit.register(pth_file.unlink, missing_ok=True)
assert config.config_file is not None
os.environ["COVERAGE_PROCESS_START"] = config.config_file
else:
raise ConfigError(f"Unknown patch {patch!r}")