From 35233a5efc69f9c1a274b61f386a551c9a691b54 Mon Sep 17 00:00:00 2001 From: Arkady Gilinsky <9481855+ark-g@users.noreply.github.com> Date: Sat, 12 Jul 2025 07:32:18 +0300 Subject: [PATCH 01/10] run: Support system signal as a coverage report dump trigger. Signed-off-by: Arkady Gilinsky <9481855+ark-g@users.noreply.github.com> --- coverage/cmdline.py | 28 +++++++++++++++++++++++++++- doc/cmd.rst | 10 +++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/coverage/cmdline.py b/coverage/cmdline.py index 998e6b398..480ced404 100644 --- a/coverage/cmdline.py +++ b/coverage/cmdline.py @@ -10,9 +10,11 @@ import os import os.path import shlex +import signal import sys import textwrap import traceback +import types from typing import cast, Any, NoReturn @@ -227,7 +229,15 @@ class Opts: "", "--version", action="store_true", help="Display version information and exit.", ) - + dump_signal = optparse.make_option( + '', '--dump_signal', action='store', metavar='DUMP_SIGNAL', + choices = ['USR1', 'USR2'], + help=( + "Define a system signal that will trigger coverage report dump. " + + "It is important that target script do not intercept this signal. " + + "Currently supported options are: USR1, USR2." + ), + ) class CoverageOptionParser(optparse.OptionParser): """Base OptionParser for coverage.py. @@ -251,6 +261,7 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: data_file=None, debug=None, directory=None, + dump_signal=None, fail_under=None, format=None, help=None, @@ -525,6 +536,7 @@ def get_prog_name(self) -> str: Opts.parallel_mode, Opts.source, Opts.timid, + Opts.dump_signal, ] + GLOBAL_ARGS, usage="[options] [program options]", description="Run a Python program, measuring code execution.", @@ -807,6 +819,11 @@ def do_help( return False + def do_dump(self, _signum: int, _frame: types.FrameType | None) -> None: + """ Signal handler to dump coverage report """ + print("Dumping coverage data ...") + self.coverage.save() + def do_run(self, options: optparse.Values, args: list[str]) -> int: """Implementation of 'coverage run'.""" @@ -851,6 +868,15 @@ def do_run(self, options: optparse.Values, args: list[str]) -> int: if options.append: self.coverage.load() + if options.dump_signal: + if options.dump_signal.upper() == 'USR1': + signal.signal(signal.SIGUSR1, self.do_dump) + elif options.dump_signal.upper() == 'USR2': + signal.signal(signal.SIGUSR2, self.do_dump) + else: + show_help(f"Unsupported signal for dump coverage report: {options.dump_signal}") + return ERR + # Run the script. self.coverage.start() code_ran = True diff --git a/doc/cmd.rst b/doc/cmd.rst index ee40a4fe5..23681cac8 100644 --- a/doc/cmd.rst +++ b/doc/cmd.rst @@ -137,13 +137,18 @@ There are many options: A list of directories or importable names of code to measure. --timid Use the slower Python trace function core. + --dump_signal=DUMP_SIGNAL + Define a system signal that will trigger coverage + report dump. It is important that target script do not + intercept this signal. Currently supported options + are: USR1, USR2. --debug=OPTS Debug options, separated by commas. [env: COVERAGE_DEBUG] -h, --help Get help on this command. --rcfile=RCFILE Specify configuration file. By default '.coveragerc', 'setup.cfg', 'tox.ini', and 'pyproject.toml' are tried. [env: COVERAGE_RCFILE] -.. [[[end]]] (sum: saD//ido/B) +.. [[[end]]] (sum: kxkJi2xQZv) If you want :ref:`branch coverage ` measurement, use the ``--branch`` flag. Otherwise only statement coverage is measured. @@ -215,6 +220,9 @@ and may change in the future. These options can also be set in the :ref:`config_run` section of your .coveragerc file. +In case if you are specifying ``--dump_signal``, please make sure that +your target script doesn't intercept this signal. Otherwise the coverage +reports will not be generated. .. _cmd_warnings: From cd2a9144d0fad1d6622ba3de57b9fa7c51310d38 Mon Sep 17 00:00:00 2001 From: Arkady Gilinsky <9481855+ark-g@users.noreply.github.com> Date: Sat, 12 Jul 2025 18:41:20 +0300 Subject: [PATCH 02/10] misc: Changes per pull request * Set options in alphabetical order * Rename "dump-signal" to "save-signal" Signed-off-by: Arkady Gilinsky <9481855+ark-g@users.noreply.github.com> --- coverage/cmdline.py | 40 ++++++++++++++++++++-------------------- doc/cmd.rst | 12 ++++++------ 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/coverage/cmdline.py b/coverage/cmdline.py index 480ced404..8b89d551a 100644 --- a/coverage/cmdline.py +++ b/coverage/cmdline.py @@ -190,6 +190,15 @@ class Opts: "'pyproject.toml' are tried. [env: COVERAGE_RCFILE]" ), ) + save_signal = optparse.make_option( + '', '--save-signal', action='store', metavar='SAVE_SIGNAL', + choices = ['USR1', 'USR2'], + help=( + "Define a system signal that will trigger coverage report save operation. " + + "It is important that target script do not intercept this signal. " + + "Currently supported options are: USR1, USR2." + ), + ) show_contexts = optparse.make_option( "--show-contexts", action="store_true", help="Show contexts for covered lines.", @@ -229,15 +238,6 @@ class Opts: "", "--version", action="store_true", help="Display version information and exit.", ) - dump_signal = optparse.make_option( - '', '--dump_signal', action='store', metavar='DUMP_SIGNAL', - choices = ['USR1', 'USR2'], - help=( - "Define a system signal that will trigger coverage report dump. " + - "It is important that target script do not intercept this signal. " + - "Currently supported options are: USR1, USR2." - ), - ) class CoverageOptionParser(optparse.OptionParser): """Base OptionParser for coverage.py. @@ -261,7 +261,6 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: data_file=None, debug=None, directory=None, - dump_signal=None, fail_under=None, format=None, help=None, @@ -275,6 +274,7 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: pylib=None, quiet=None, rcfile=True, + save_signal=None, show_contexts=None, show_missing=None, skip_covered=None, @@ -534,9 +534,9 @@ def get_prog_name(self) -> str: Opts.omit, Opts.pylib, Opts.parallel_mode, + Opts.save_signal, Opts.source, Opts.timid, - Opts.dump_signal, ] + GLOBAL_ARGS, usage="[options] [program options]", description="Run a Python program, measuring code execution.", @@ -819,9 +819,9 @@ def do_help( return False - def do_dump(self, _signum: int, _frame: types.FrameType | None) -> None: - """ Signal handler to dump coverage report """ - print("Dumping coverage data ...") + def do_signal_save(self, _signum: int, _frame: types.FrameType | None) -> None: + """ Signal handler to save coverage report """ + print("Saving coverage data ...") self.coverage.save() def do_run(self, options: optparse.Values, args: list[str]) -> int: @@ -868,13 +868,13 @@ def do_run(self, options: optparse.Values, args: list[str]) -> int: if options.append: self.coverage.load() - if options.dump_signal: - if options.dump_signal.upper() == 'USR1': - signal.signal(signal.SIGUSR1, self.do_dump) - elif options.dump_signal.upper() == 'USR2': - signal.signal(signal.SIGUSR2, self.do_dump) + if options.save_signal: + if options.save_signal.upper() == 'USR1': + signal.signal(signal.SIGUSR1, self.do_signal_save) + elif options.save_signal.upper() == 'USR2': + signal.signal(signal.SIGUSR2, self.do_signal_save) else: - show_help(f"Unsupported signal for dump coverage report: {options.dump_signal}") + show_help(f"Unsupported signal for save coverage report: {options.save_signal}") return ERR # Run the script. diff --git a/doc/cmd.rst b/doc/cmd.rst index 23681cac8..b1b99be86 100644 --- a/doc/cmd.rst +++ b/doc/cmd.rst @@ -133,22 +133,22 @@ There are many options: -p, --parallel-mode Append the machine name, process id and random number to the data file name to simplify collecting data from many processes. + --save-signal=SAVE_SIGNAL + Define a system signal that will trigger coverage + report save operation. It is important that target + script do not intercept this signal. Currently + supported options are: USR1, USR2. --source=SRC1,SRC2,... A list of directories or importable names of code to measure. --timid Use the slower Python trace function core. - --dump_signal=DUMP_SIGNAL - Define a system signal that will trigger coverage - report dump. It is important that target script do not - intercept this signal. Currently supported options - are: USR1, USR2. --debug=OPTS Debug options, separated by commas. [env: COVERAGE_DEBUG] -h, --help Get help on this command. --rcfile=RCFILE Specify configuration file. By default '.coveragerc', 'setup.cfg', 'tox.ini', and 'pyproject.toml' are tried. [env: COVERAGE_RCFILE] -.. [[[end]]] (sum: kxkJi2xQZv) +.. [[[end]]] (sum: 1+s3B5JO5I) If you want :ref:`branch coverage ` measurement, use the ``--branch`` flag. Otherwise only statement coverage is measured. From b4f34678bb8561d04f5a6e88cec38a28217fb199 Mon Sep 17 00:00:00 2001 From: Arkady Gilinsky <9481855+ark-g@users.noreply.github.com> Date: Sat, 12 Jul 2025 22:02:17 +0300 Subject: [PATCH 03/10] docs: Update - save signal doesn't work on Windows Signed-off-by: Arkady Gilinsky <9481855+ark-g@users.noreply.github.com> --- coverage/cmdline.py | 6 +++++- doc/cmd.rst | 5 +++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/coverage/cmdline.py b/coverage/cmdline.py index 8b89d551a..115e6741e 100644 --- a/coverage/cmdline.py +++ b/coverage/cmdline.py @@ -196,7 +196,8 @@ class Opts: help=( "Define a system signal that will trigger coverage report save operation. " + "It is important that target script do not intercept this signal. " + - "Currently supported options are: USR1, USR2." + "Currently supported options are: USR1, USR2. " + + "This feature does not work on Windows." ), ) show_contexts = optparse.make_option( @@ -869,6 +870,9 @@ def do_run(self, options: optparse.Values, args: list[str]) -> int: self.coverage.load() if options.save_signal: + if env.WINDOWS: + show_help("Signals are not supported in Windows environment.") + return ERR if options.save_signal.upper() == 'USR1': signal.signal(signal.SIGUSR1, self.do_signal_save) elif options.save_signal.upper() == 'USR2': diff --git a/doc/cmd.rst b/doc/cmd.rst index b1b99be86..0446b1aa6 100644 --- a/doc/cmd.rst +++ b/doc/cmd.rst @@ -137,7 +137,8 @@ There are many options: Define a system signal that will trigger coverage report save operation. It is important that target script do not intercept this signal. Currently - supported options are: USR1, USR2. + supported options are: USR1, USR2. This feature does + not work on Windows. --source=SRC1,SRC2,... A list of directories or importable names of code to measure. @@ -148,7 +149,7 @@ There are many options: --rcfile=RCFILE Specify configuration file. By default '.coveragerc', 'setup.cfg', 'tox.ini', and 'pyproject.toml' are tried. [env: COVERAGE_RCFILE] -.. [[[end]]] (sum: 1+s3B5JO5I) +.. [[[end]]] (sum: X8Kbvdq2+f) If you want :ref:`branch coverage ` measurement, use the ``--branch`` flag. Otherwise only statement coverage is measured. From 0858fb0df21ebf74e1553fec18eab89082f90914 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Sun, 13 Jul 2025 07:10:59 -0400 Subject: [PATCH 04/10] simplify and test --save-signal handling optparse catches the problem of an incorrect signal name, we don't need to. --- coverage/cmdline.py | 11 +++-------- tests/test_cmdline.py | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/coverage/cmdline.py b/coverage/cmdline.py index 115e6741e..7a9bac8cf 100644 --- a/coverage/cmdline.py +++ b/coverage/cmdline.py @@ -871,15 +871,10 @@ def do_run(self, options: optparse.Values, args: list[str]) -> int: if options.save_signal: if env.WINDOWS: - show_help("Signals are not supported in Windows environment.") - return ERR - if options.save_signal.upper() == 'USR1': - signal.signal(signal.SIGUSR1, self.do_signal_save) - elif options.save_signal.upper() == 'USR2': - signal.signal(signal.SIGUSR2, self.do_signal_save) - else: - show_help(f"Unsupported signal for save coverage report: {options.save_signal}") + show_help("--save-signal is not supported on Windows.") return ERR + sig = getattr(signal, f"SIG{options.save_signal}") + signal.signal(sig, self.do_signal_save) # Run the script. self.coverage.start() diff --git a/tests/test_cmdline.py b/tests/test_cmdline.py index 0ebf27267..37d9a0688 100644 --- a/tests/test_cmdline.py +++ b/tests/test_cmdline.py @@ -20,6 +20,7 @@ import coverage import coverage.cmdline +from coverage import env from coverage.control import DEFAULT_DATAFILE from coverage.config import CoverageConfig from coverage.exceptions import _ExceptionDuringRun @@ -942,6 +943,19 @@ def test_no_arguments_at_all(self) -> None: def test_bad_command(self) -> None: self.cmd_help("xyzzy", "Unknown command: 'xyzzy'") + def test_save_signal_wrong(self) -> None: + self.cmd_help( + "run --save-signal=XYZ nothing.py", + "option --save-signal: invalid choice: 'XYZ' (choose from 'USR1', 'USR2')", + ) + + @pytest.mark.skipif(not env.WINDOWS, reason="this is a windows-only error") + def test_save_signal_windows(self) -> None: + self.cmd_help( + "run --save-signal=USR1 nothing.py", + "--save-signal is not supported on Windows.", + ) + class CmdLineWithFilesTest(BaseCmdLineTest): """Test the command line in ways that need temp files.""" From 5d0acca2b8f8b745c8a5f7b82cb3f418ebae08e8 Mon Sep 17 00:00:00 2001 From: Arkady Gilinsky <9481855+ark-g@users.noreply.github.com> Date: Sun, 13 Jul 2025 20:24:57 +0300 Subject: [PATCH 05/10] test: Add test cases for signal dump Signed-off-by: Arkady Gilinsky <9481855+ark-g@users.noreply.github.com> --- tests/test_process.py | 45 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/tests/test_process.py b/tests/test_process.py index 24eb1a68b..1856aa2e0 100644 --- a/tests/test_process.py +++ b/tests/test_process.py @@ -689,6 +689,51 @@ def test_module_name(self) -> None: out = self.run_command("python -m coverage") assert "Use 'coverage help' for help" in out + @pytest.mark.skipif(env.WINDOWS, reason="This test is not for Windows") + def test_save_signal(self) -> None: + test_file = "dummy_hello.py" + self.assert_doesnt_exist(".coverage") + self.make_file(test_file, """\ + import os + import signal + + print(f"Sending SIGUSR1 to process {os.getpid()}") + os.kill(os.getpid(), signal.SIGUSR1) + os.kill(os.getpid(), signal.SIGKILL) + + print('Done and goodbye') + """) + covered_lines = 4 + self.run_command(f"coverage run --save-signal USR1 {test_file}") + self.assert_exists(".coverage") + data = coverage.CoverageData() + data.read() + assert line_counts(data)[test_file] == covered_lines + out = self.run_command("coverage report") + assert out == textwrap.dedent("""\ + Name Stmts Miss Cover + ------------------------------------ + dummy_hello.py 6 2 67% + ------------------------------------ + TOTAL 6 2 67% + """) + + # Negative test for signal + @pytest.mark.skipif(env.WINDOWS, reason="This test is not for Windows") + def test_save_signal_no_send(self) -> None: + test_file = "dummy_hello.py" + self.assert_doesnt_exist(".coverage") + self.make_file(test_file, """\ + import os + import signal + + os.kill(os.getpid(), signal.SIGKILL) + + print('Done and goodbye') + """) + self.run_command(f"coverage run --save-signal USR1 {test_file}") + self.assert_doesnt_exist(".coverage") + TRY_EXECFILE = os.path.join(os.path.dirname(__file__), "modules/process_test/try_execfile.py") From a89c7893543f53679115c8d1a994a86f689cea6b Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Sun, 13 Jul 2025 08:55:27 -0400 Subject: [PATCH 06/10] test: a test for --save-signal --- coverage/cmdline.py | 2 +- tests/helpers.py | 8 ++++++-- tests/test_process.py | 31 ++++++++++++++++++++++++++++++- 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/coverage/cmdline.py b/coverage/cmdline.py index 7a9bac8cf..4cd4542b4 100644 --- a/coverage/cmdline.py +++ b/coverage/cmdline.py @@ -822,7 +822,7 @@ def do_help( def do_signal_save(self, _signum: int, _frame: types.FrameType | None) -> None: """ Signal handler to save coverage report """ - print("Saving coverage data ...") + print("Saving coverage data ...", flush=True) self.coverage.save() def do_run(self, options: optparse.Values, args: list[str]) -> int: diff --git a/tests/helpers.py b/tests/helpers.py index 0861eb854..74c88d861 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -13,6 +13,7 @@ import os import os.path import re +import shlex import shutil import subprocess import sys @@ -47,7 +48,7 @@ def _correct_encoding() -> str: return encoding -def subprocess_popen(cmd: str) -> subprocess.Popen[bytes]: +def subprocess_popen(cmd: str, shell: bool=True) -> subprocess.Popen[bytes]: """Run a command in a subprocess. Returns the Popen object. @@ -66,9 +67,12 @@ def subprocess_popen(cmd: str) -> subprocess.Popen[bytes]: sub_env = dict(os.environ) sub_env["PYTHONIOENCODING"] = _correct_encoding() + if not shell: + cmd = shlex.split(cmd) # type: ignore[assignment] + proc = subprocess.Popen( cmd, - shell=True, + shell=shell, env=sub_env, stdin=subprocess.PIPE, stdout=subprocess.PIPE, diff --git a/tests/test_process.py b/tests/test_process.py index 24eb1a68b..96582487f 100644 --- a/tests/test_process.py +++ b/tests/test_process.py @@ -11,9 +11,11 @@ import os.path import platform import re +import signal import stat import sys import textwrap +import time from pathlib import Path from typing import Any @@ -27,7 +29,7 @@ from tests import testenv from tests.coveragetest import CoverageTest, TESTS_DIR -from tests.helpers import re_line, re_lines, re_lines_text +from tests.helpers import re_line, re_lines, re_lines_text, subprocess_popen class ProcessTest(CoverageTest): @@ -458,6 +460,33 @@ def test_os_exit(self, patch: bool) -> None: else: assert seen < total_lines + @pytest.mark.skipif(env.WINDOWS, reason="Windows can't do --save-signal") + @pytest.mark.parametrize("send", [False, True]) + def test_save_signal(self, send: bool) -> None: + # PyPy on Ubuntu seems to need more time for things to happen. + base_time = 0.75 if (env.PYPY and env.LINUX) else 0.0 + self.make_file("loop.py", """\ + import time + print("Starting", flush=True) + while True: + time.sleep(.02) + """) + proc = subprocess_popen("coverage run --save-signal=USR1 loop.py", shell=False) + time.sleep(base_time + .25) + if send: + proc.send_signal(signal.SIGUSR1) + time.sleep(base_time + .25) + proc.kill() + proc.wait(timeout=base_time + .25) + stdout, _ = proc.communicate() + assert b"Starting" in stdout + if send: + self.assert_exists(".coverage") + assert b"Saving coverage data" in stdout + else: + self.assert_doesnt_exist(".coverage") + assert b"Saving coverage data" not in stdout + def test_warnings_during_reporting(self) -> None: # While fixing issue #224, the warnings were being printed far too # often. Make sure they're not any more. From f3bcee19cba8951c0c5a54a6a9d80d9c2d67f06b Mon Sep 17 00:00:00 2001 From: Arkady Gilinsky <9481855+ark-g@users.noreply.github.com> Date: Sat, 19 Jul 2025 11:51:18 +0300 Subject: [PATCH 07/10] test: Rename send signal test functons Signed-off-by: Arkady Gilinsky <9481855+ark-g@users.noreply.github.com> --- tests/test_process.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_process.py b/tests/test_process.py index a64514ea4..33e04b5ec 100644 --- a/tests/test_process.py +++ b/tests/test_process.py @@ -717,7 +717,7 @@ def test_module_name(self) -> None: assert "Use 'coverage help' for help" in out @pytest.mark.skipif(env.WINDOWS, reason="This test is not for Windows") - def test_save_signal(self) -> None: + def test_save_signal_usr1(self) -> None: test_file = "dummy_hello.py" self.assert_doesnt_exist(".coverage") self.make_file(test_file, """\ @@ -747,7 +747,7 @@ def test_save_signal(self) -> None: # Negative test for signal @pytest.mark.skipif(env.WINDOWS, reason="This test is not for Windows") - def test_save_signal_no_send(self) -> None: + def test_save_signal_kill(self) -> None: test_file = "dummy_hello.py" self.assert_doesnt_exist(".coverage") self.make_file(test_file, """\ From ed22d06305398e5912226a6bd33b9f21d049011a Mon Sep 17 00:00:00 2001 From: Arkady Gilinsky <9481855+ark-g@users.noreply.github.com> Date: Sat, 19 Jul 2025 12:03:01 +0300 Subject: [PATCH 08/10] Update signal test functions Signed-off-by: Arkady Gilinsky <9481855+ark-g@users.noreply.github.com> --- tests/coveragetest.py | 6 +++++- tests/test_process.py | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/coveragetest.py b/tests/coveragetest.py index 6b19f1e7d..e9734d633 100644 --- a/tests/coveragetest.py +++ b/tests/coveragetest.py @@ -418,7 +418,11 @@ def run_command(self, cmd: str, *, status: int = 0) -> str: """ actual_status, output = self.run_command_status(cmd) - assert actual_status == status + if actual_status > 128: + # Killed by signal, shell returns 128 + signal_num + assert actual_status == 128 + (-1 * status) + else: + assert actual_status == status return output def run_command_status(self, cmd: str) -> tuple[int, str]: diff --git a/tests/test_process.py b/tests/test_process.py index 33e04b5ec..fbe05b465 100644 --- a/tests/test_process.py +++ b/tests/test_process.py @@ -731,7 +731,7 @@ def test_save_signal_usr1(self) -> None: print('Done and goodbye') """) covered_lines = 4 - self.run_command(f"coverage run --save-signal USR1 {test_file}") + self.run_command(f"coverage run --save-signal USR1 {test_file}", status = -signal.SIGKILL) self.assert_exists(".coverage") data = coverage.CoverageData() data.read() @@ -758,7 +758,7 @@ def test_save_signal_kill(self) -> None: print('Done and goodbye') """) - self.run_command(f"coverage run --save-signal USR1 {test_file}") + self.run_command(f"coverage run --save-signal USR1 {test_file}", status = -signal.SIGKILL) self.assert_doesnt_exist(".coverage") From 31920ff7c280016eebdef43986a78c6dd79a48b7 Mon Sep 17 00:00:00 2001 From: Arkady Gilinsky <9481855+ark-g@users.noreply.github.com> Date: Sat, 19 Jul 2025 14:40:41 +0300 Subject: [PATCH 09/10] test: Remove redundant test Signed-off-by: Arkady Gilinsky <9481855+ark-g@users.noreply.github.com> --- tests/test_process.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/tests/test_process.py b/tests/test_process.py index fbe05b465..f95fd259a 100644 --- a/tests/test_process.py +++ b/tests/test_process.py @@ -745,23 +745,6 @@ def test_save_signal_usr1(self) -> None: TOTAL 6 2 67% """) - # Negative test for signal - @pytest.mark.skipif(env.WINDOWS, reason="This test is not for Windows") - def test_save_signal_kill(self) -> None: - test_file = "dummy_hello.py" - self.assert_doesnt_exist(".coverage") - self.make_file(test_file, """\ - import os - import signal - - os.kill(os.getpid(), signal.SIGKILL) - - print('Done and goodbye') - """) - self.run_command(f"coverage run --save-signal USR1 {test_file}", status = -signal.SIGKILL) - self.assert_doesnt_exist(".coverage") - - TRY_EXECFILE = os.path.join(os.path.dirname(__file__), "modules/process_test/try_execfile.py") class EnvironmentTest(CoverageTest): From ce9dfe94a2b0ac6f656c9330a0e7aeb82a8edbeb Mon Sep 17 00:00:00 2001 From: Arkady Gilinsky <9481855+ark-g@users.noreply.github.com> Date: Sat, 19 Jul 2025 15:14:04 +0300 Subject: [PATCH 10/10] docs: Fix docs Signed-off-by: Arkady Gilinsky <9481855+ark-g@users.noreply.github.com> --- doc/cmd.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/cmd.rst b/doc/cmd.rst index 0446b1aa6..791aee1cc 100644 --- a/doc/cmd.rst +++ b/doc/cmd.rst @@ -221,7 +221,7 @@ and may change in the future. These options can also be set in the :ref:`config_run` section of your .coveragerc file. -In case if you are specifying ``--dump_signal``, please make sure that +In case if you are specifying ``--save-signal``, please make sure that your target script doesn't intercept this signal. Otherwise the coverage reports will not be generated.