13
13
from typing import TYPE_CHECKING , Any , NoReturn
14
14
15
15
from coverage import env
16
+ from coverage .debug import NoDebugging , DevNullDebug
16
17
from coverage .exceptions import ConfigError , CoverageException
17
18
18
19
if TYPE_CHECKING :
@@ -29,6 +30,7 @@ def apply_patches(
29
30
make_pth_file : bool = True ,
30
31
) -> None :
31
32
"""Apply invasive patches requested by `[run] patch=`."""
33
+ debug = debug if debug .should ("patch" ) else DevNullDebug ()
32
34
for patch in sorted (set (config .patch )):
33
35
if patch == "_exit" :
34
36
_patch__exit (cov , debug )
@@ -45,15 +47,13 @@ def apply_patches(
45
47
46
48
def _patch__exit (cov : Coverage , debug : TDebugCtl ) -> None :
47
49
"""Patch os._exit."""
48
- if debug .should ("patch" ):
49
- debug .write ("Patching _exit" )
50
+ debug .write ("Patching _exit" )
50
51
51
52
old_exit = os ._exit
52
53
53
54
def coverage_os_exit_patch (status : int ) -> NoReturn :
54
55
with contextlib .suppress (Exception ):
55
- if debug .should ("patch" ):
56
- debug .write ("Using _exit patch" )
56
+ debug .write ("Using _exit patch" )
57
57
with contextlib .suppress (Exception ):
58
58
cov .save ()
59
59
old_exit (status )
@@ -66,14 +66,12 @@ def _patch_execv(cov: Coverage, config: CoverageConfig, debug: TDebugCtl) -> Non
66
66
if env .WINDOWS :
67
67
raise CoverageException ("patch=execv isn't supported yet on Windows." )
68
68
69
- if debug .should ("patch" ):
70
- debug .write ("Patching execv" )
69
+ debug .write ("Patching execv" )
71
70
72
71
def make_execv_patch (fname : str , old_execv : Any ) -> Any :
73
72
def coverage_execv_patch (* args : Any , ** kwargs : Any ) -> Any :
74
73
with contextlib .suppress (Exception ):
75
- if debug .should ("patch" ):
76
- debug .write (f"Using execv patch for { fname } " )
74
+ debug .write (f"Using execv patch for { fname } " )
77
75
with contextlib .suppress (Exception ):
78
76
cov .save ()
79
77
@@ -105,13 +103,13 @@ def coverage_execv_patch(*args: Any, **kwargs: Any) -> Any:
105
103
106
104
def _patch_subprocess (config : CoverageConfig , debug : TDebugCtl , make_pth_file : bool ) -> None :
107
105
"""Write .pth files and set environment vars to measure subprocesses."""
108
- if debug .should ("patch" ):
109
- debug .write ("Patching subprocess" )
106
+ debug .write ("Patching subprocess" )
110
107
111
108
if make_pth_file :
112
- pth_files = create_pth_files ()
109
+ pth_files = create_pth_files (debug )
113
110
def delete_pth_files () -> None :
114
111
for p in pth_files :
112
+ debug .write (f"Deleting subprocess .pth file: { str (p )!r} " )
115
113
p .unlink (missing_ok = True )
116
114
atexit .register (delete_pth_files )
117
115
assert config .config_file is not None
@@ -133,14 +131,17 @@ def delete_pth_files() -> None:
133
131
coverage.process_startup()
134
132
"""
135
133
136
- def create_pth_files () -> list [Path ]:
134
+ PTH_TEXT = f"import sys; exec({ PTH_CODE !r} )"
135
+
136
+ def create_pth_files (debug : TDebugCtl = NoDebugging ()) -> list [Path ]:
137
137
"""Create .pth files for measuring subprocesses."""
138
- pth_text = rf"import sys; exec({ PTH_CODE !r} )"
139
138
pth_files = []
140
139
for pth_dir in site .getsitepackages ():
141
140
pth_file = Path (pth_dir ) / f"subcover_{ os .getpid ()} .pth"
142
141
try :
143
- pth_file .write_text (pth_text , encoding = "utf-8" )
142
+ if debug .should ("patch" ):
143
+ debug .write (f"Writing subprocess .pth file: { str (pth_file )!r} " )
144
+ pth_file .write_text (PTH_TEXT , encoding = "utf-8" )
144
145
except OSError : # pragma: cant happen
145
146
continue
146
147
else :
0 commit comments