Skip to content

Commit 7e49831

Browse files
committed
refactor: patch=_exit without a global
1 parent 4d4ddd8 commit 7e49831

File tree

2 files changed

+16
-10
lines changed

2 files changed

+16
-10
lines changed

coverage/patch.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import atexit
99
import os
1010

11-
from typing import NoReturn, TYPE_CHECKING
11+
from typing import Callable, NoReturn, TYPE_CHECKING
1212

1313
from coverage.exceptions import ConfigError
1414
from coverage.files import create_pth_file
@@ -17,25 +17,28 @@
1717
from coverage import Coverage
1818
from coverage.config import CoverageConfig
1919

20-
_old_os_exit = os._exit
2120

2221
def apply_patches(cov: Coverage, config: CoverageConfig) -> None:
2322
"""Apply invasive patches requested by `[run] patch=`."""
2423

2524
for patch in set(config.patch):
2625
if patch == "_exit":
27-
def _coverage_os_exit_patch(status: int) -> NoReturn:
28-
try:
29-
cov.save()
30-
except: # pylint: disable=bare-except
31-
pass
32-
_old_os_exit(status)
33-
os._exit = _coverage_os_exit_patch
26+
def make_patch(old_os_exit: Callable[[int], NoReturn]) -> Callable[[int], NoReturn]:
27+
def _coverage_os_exit_patch(status: int) -> NoReturn:
28+
try:
29+
cov.save()
30+
except: # pylint: disable=bare-except
31+
pass
32+
old_os_exit(status)
33+
return _coverage_os_exit_patch
34+
os._exit = make_patch(os._exit) # type: ignore[assignment]
35+
3436
elif patch == "subprocess":
3537
pth_file = create_pth_file()
3638
assert pth_file is not None
3739
atexit.register(pth_file.unlink, missing_ok=True)
3840
assert config.config_file is not None
3941
os.environ["COVERAGE_PROCESS_START"] = config.config_file
42+
4043
else:
4144
raise ConfigError(f"Unknown patch {patch!r}")

tests/test_process.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,8 +443,10 @@ def test_os_exit(self, patch: bool) -> None:
443443
with open(complete_file, mode="w", encoding="ascii") as f:
444444
f.write("Complete")
445445
os._exit(0)
446+
# if this exists, then we broke os._exit completely
447+
open("impossible.txt", mode="w")
446448
""")
447-
total_lines = 17
449+
total_lines = 17 # don't count the last impossible.txt line
448450
if patch:
449451
self.make_file(".coveragerc", "[run]\npatch = _exit\n")
450452
self.run_command("coverage run -p forky.py")
@@ -456,6 +458,7 @@ def test_os_exit(self, patch: bool) -> None:
456458
assert seen == total_lines
457459
else:
458460
assert seen < total_lines
461+
self.assert_doesnt_exist("impossible.txt")
459462

460463
def test_warnings_during_reporting(self) -> None:
461464
# While fixing issue #224, the warnings were being printed far too

0 commit comments

Comments
 (0)