Skip to content

Commit 817542f

Browse files
committed
fix: added debug logging for patches
1 parent 958e30e commit 817542f

File tree

5 files changed

+33
-13
lines changed

5 files changed

+33
-13
lines changed

CHANGES.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ Unreleased
3737
``ModuleNotFound`` error trying to import coverage. This is now fixed,
3838
closing `issue 2022`_.
3939

40+
- Added ``debug=patch`` to help diagnose problems.
41+
4042
- Fix: really close all SQLite databases, even in-memory ones. Closes `issue
4143
2017`_.
4244

coverage/control.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -697,7 +697,7 @@ def start(self) -> None:
697697
if self._auto_load:
698698
self.load()
699699

700-
apply_patches(self, self.config, make_pth_file=self._make_pth_file)
700+
apply_patches(self, self.config, self._debug, make_pth_file=self._make_pth_file)
701701

702702
self._collector.start()
703703
self._started = True

coverage/patch.py

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
22
# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt
33

4-
"""Invasive patches for coverage.py"""
4+
"""Invasive patches for coverage.py."""
55

66
from __future__ import annotations
77

88
import atexit
9+
import contextlib
910
import os
1011
import site
1112
from pathlib import Path
@@ -17,22 +18,32 @@
1718
if TYPE_CHECKING:
1819
from coverage import Coverage
1920
from coverage.config import CoverageConfig
21+
from coverage.types import TDebugCtl
2022

2123

22-
def apply_patches(cov: Coverage, config: CoverageConfig, *, make_pth_file: bool=True) -> None:
24+
def apply_patches(
25+
cov: Coverage,
26+
config: CoverageConfig,
27+
debug: TDebugCtl,
28+
*,
29+
make_pth_file: bool = True,
30+
) -> None:
2331
"""Apply invasive patches requested by `[run] patch=`."""
2432

2533
for patch in sorted(set(config.patch)):
2634
if patch == "_exit":
35+
if debug.should("patch"):
36+
debug.write("Patching _exit")
2737

2838
def make_exit_patch(
2939
old_exit: Callable[[int], NoReturn],
3040
) -> Callable[[int], NoReturn]:
3141
def coverage_os_exit_patch(status: int) -> NoReturn:
32-
try:
42+
with contextlib.suppress(Exception):
43+
if debug.should("patch"):
44+
debug.write("Using _exit patch")
45+
with contextlib.suppress(Exception):
3346
cov.save()
34-
except: # pylint: disable=bare-except
35-
pass
3647
old_exit(status)
3748

3849
return coverage_os_exit_patch
@@ -43,12 +54,16 @@ def coverage_os_exit_patch(status: int) -> NoReturn:
4354
if env.WINDOWS:
4455
raise CoverageException("patch=execv isn't supported yet on Windows.")
4556

57+
if debug.should("patch"):
58+
debug.write("Patching execv")
59+
4660
def make_execv_patch(fname: str, old_execv: Any) -> Any:
4761
def coverage_execv_patch(*args: Any, **kwargs: Any) -> Any:
48-
try:
62+
with contextlib.suppress(Exception):
63+
if debug.should("patch"):
64+
debug.write(f"Using execv patch for {fname}")
65+
with contextlib.suppress(Exception):
4966
cov.save()
50-
except: # pylint: disable=bare-except
51-
pass
5267

5368
if fname.endswith("e"):
5469
# Assume the `env` argument is passed positionally.
@@ -62,9 +77,7 @@ def coverage_execv_patch(*args: Any, **kwargs: Any) -> Any:
6277
# When testing locally, we need to honor the pyc file location
6378
# or they get written to the .tox directories and pollute the
6479
# next run with a different core.
65-
if (
66-
cache_prefix := os.getenv("PYTHONPYCACHEPREFIX")
67-
) is not None:
80+
if (cache_prefix := os.getenv("PYTHONPYCACHEPREFIX")) is not None:
6881
new_env["PYTHONPYCACHEPREFIX"] = cache_prefix
6982

7083
# Without this, it fails on PyPy and Ubuntu.
@@ -78,6 +91,9 @@ def coverage_execv_patch(*args: Any, **kwargs: Any) -> Any:
7891
os.execve = make_execv_patch("execve", os.execve)
7992

8093
elif patch == "subprocess":
94+
if debug.should("patch"):
95+
debug.write("Patching subprocess")
96+
8197
if make_pth_file:
8298
pth_files = create_pth_files()
8399
def make_deleter(pth_files: list[Path]) -> Callable[[], None]:

doc/cmd.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,6 +1064,9 @@ of operation to log:
10641064

10651065
* ``multiproc``: log the start and stop of multiprocessing processes.
10661066

1067+
* ``patch``: log when patches are applied and when they are executed. See
1068+
:ref:`config_run_patch`.
1069+
10671070
* ``pathmap``: log the remapping of paths that happens during ``coverage
10681071
combine``. See :ref:`config_paths`.
10691072

pyproject.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,6 @@ ignore = [
177177
"ERA001", # Found commented-out code
178178
"PLR0913", # Too many arguments in function definition
179179
"S101", # Use of `assert` detected
180-
"SIM105", # Use `contextlib.suppress(Exception)` instead of `try`-`except`-`pass`
181180
"TRY003", # Avoid specifying long messages outside the exception class
182181
]
183182
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?)|[a-zA-Z0-9_]+_unused)$"

0 commit comments

Comments
 (0)