Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CONTRIBUTORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ Mathieu Kniewallner
Matt Bachmann
Matthew Boehm
Matthew Desmarais
Matthias Schoettle
Matus Valo
Max Linke
Mayank Singhal
Expand Down
12 changes: 7 additions & 5 deletions coverage/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,13 @@ def _debug(msg: str) -> None:
# Check the conditions that preclude us from using sys.monitoring.
reason_no_sysmon = ""
if not env.PYBEHAVIOR.pep669:
reason_no_sysmon = "isn't available in this version"
reason_no_sysmon = "sys.monitoring isn't available in this version"
elif config.branch and not env.PYBEHAVIOR.branch_right_left:
reason_no_sysmon = "can't measure branches in this version"
reason_no_sysmon = "sys.monitoring can't measure branches in this version"
elif dynamic_contexts:
reason_no_sysmon = "doesn't yet support dynamic contexts"
reason_no_sysmon = "it doesn't yet support dynamic contexts"
elif any((bad := c) in config.concurrency for c in ["greenlet", "eventlet", "gevent"]):
reason_no_sysmon = f"doesn't support concurrency={bad}"
reason_no_sysmon = f"it doesn't support concurrency={bad}"

core_name: str | None = None
if config.timid:
Expand All @@ -92,7 +92,9 @@ def _debug(msg: str) -> None:
if core_name == "sysmon" and reason_no_sysmon:
_debug(f"core.py: raising ConfigError because sysmon not usable: {reason_no_sysmon}")
raise ConfigError(
f"Can't use core=sysmon: sys.monitoring {reason_no_sysmon}", skip_tests=True
f"Can't use core=sysmon: {reason_no_sysmon}",
skip_tests=True,
slug="no-sysmon",
)

if core_name is None:
Expand Down
24 changes: 15 additions & 9 deletions doc/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -333,15 +333,21 @@ Before version 4.2, this option only accepted a single string.
[run] core
..........

(string) Specify which trace function implementation to use. Valid values are:
"pytrace" for the pure Python implementation, "ctrace" for the C implementation
(default until Python 3.13),
or "sysmon" (Python 3.12+ only) for the
:mod:`sys.monitoring <python:sys.monitoring>`
implementation (default with Python 3.14+).

This was previously only available as the COVERAGE_CORE environment variable.
Note that the "sysmon" core does not yet support plugins or dynamic contexts.
(string, default depends on the Python version) Specify which measurement core
to use. Valid values are:

- ``ctrace``: the C implementation of a sys.settrace function. This was the
default until Python 3.13.

- ``sysmon``: the :mod:`sys.monitoring <python:sys.monitoring>` implementation.
Only available in Python 3.12+, and the default in Python 3.14+. The sysmon
core does not yet support plugins, dynamic contexts, or some concurrency
libraries. In Python 3.12 and 3.13, it does not support branch coverage.

- ``pytrace``: the pure Python implementation of a sys.settrace function.

This setting was previously only available as the COVERAGE_CORE environment
variable.

.. versionadded:: 7.9

Expand Down
33 changes: 16 additions & 17 deletions doc/messages.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,22 @@ Can't combine (branch or statement) coverage data with (statement or branch) dat
incompatible. You'll need to ensure that all of your data files are
collected with the same settings.

.. _error_no_sysmon:

Can't use core=sysmon: sys.monitoring isn't available in this version
You requested the sys.monitoring measurement core, but are running on
Python 3.11 or lower where it isn't available.

Can't use core=sysmon: sys.monitoring can't measure branches in this version
You requested the sys.monitoring measurement core and also branch coverage.
This isn't supported until the Python 3.14.

Can't use core=sysmon: it doesn't yet support dynamic contexts
You requested the sys.monitoring measurement core and also dynamic contexts.
This isn't supported by coverage.py yet.

Can't use core=sysmon: it doesn't support concurrency=ZZZ


.. _cmd_warnings:
.. _warnings:
Expand Down Expand Up @@ -138,23 +154,6 @@ Couldn't import C tracer (no-ctracer)
imported. The reason is included in the warning message. The Python tracer
will be used instead.

.. _warning_no_sysmon:

sys.monitoring isn't available in this version, using default core (no-sysmon)
You requested to use the sys.monitoring measurement core, but are running on
Python 3.11 or lower where it isn't available. A default core will be used
instead.

sys.monitoring can't measure branches in this version, using default core (no-sysmon)
You requested the sys.monitoring measurement core and also branch coverage.
This isn't supported until the later alphas of Python 3.14. A default core
will be used instead.

sys.monitoring doesn't yet support dynamic contexts, using default core (no-sysmon)
You requested the sys.monitoring measurement core and also dynamic contexts.
This isn't supported by coverage.py yet. A default core will be used
instead.


Disabling warnings
------------------
Expand Down
1 change: 0 additions & 1 deletion metacov.ini
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
[run]
branch = true
data_file = ${COVERAGE_METAFILE-.metacov}
disable_warnings = no-sysmon
parallel = true
relative_files = true
source =
Expand Down
2 changes: 0 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,6 @@ filterwarnings = [

## Pytest warns if it can't collect things that seem to be tests. This should be an error.
"error::pytest.PytestCollectionWarning",

"ignore:.*no-sysmon"
]

# xfail tests that pass should fail the test suite
Expand Down
2 changes: 0 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,6 @@ def set_warnings() -> None:
# https://github.com/python/cpython/issues/105539
warnings.filterwarnings("ignore", r"unclosed database", category=ResourceWarning)

warnings.filterwarnings("ignore", r".*no-sysmon")

# We have a test that has a return in a finally: test_bug_1891.
warnings.filterwarnings("ignore", "'return' in a 'finally' block", category=SyntaxWarning)

Expand Down
23 changes: 7 additions & 16 deletions tests/test_concurrency.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,21 +183,17 @@ def cant_trace_msg(concurrency: str, the_module: ModuleType | None) -> str | Non
concurrency = ",".join(parts)

if testenv.SYS_MON and concurrency:
expected_out = (
f"Can't use core=sysmon: sys.monitoring doesn't support concurrency={concurrency}\n"
)
expected_out = f"Can't use core=sysmon: it doesn't support concurrency={concurrency};"
elif the_module is None:
# We don't even have the underlying module installed, we expect
# coverage to alert us to this fact.
expected_out = (
f"Couldn't trace with concurrency={concurrency}, the module isn't installed.\n"
)
expected_out = f"Couldn't trace with concurrency={concurrency}, the module isn't installed."
elif testenv.C_TRACER or concurrency == "thread" or concurrency == "":
expected_out = None
else:
expected_out = (
f"Can't support concurrency={concurrency} with {testenv.REQUESTED_TRACER_CLASS}, "
+ "only threads are supported.\n"
+ "only threads are supported."
)
return expected_out

Expand Down Expand Up @@ -230,7 +226,7 @@ def try_some_code(
expected_cant_trace = cant_trace_msg(concurrency, the_module)

if expected_cant_trace is not None:
assert out == expected_cant_trace
assert expected_cant_trace in out
pytest.skip(f"Can't test: {expected_cant_trace}")
else:
# We can fully measure the code if we are using the C tracer, which
Expand Down Expand Up @@ -406,7 +402,7 @@ def test_missing_module(self, module: str) -> None:
self.make_file("prog.py", "a = 1")
sys.modules[module] = None # type: ignore[assignment]
if testenv.SYS_MON:
msg = rf"Can't use core=sysmon: sys.monitoring doesn't support concurrency={module}"
msg = rf"Can't use core=sysmon: it doesn't support concurrency={module}"
else:
msg = rf"Couldn't trace with concurrency={module}, the module isn't installed."
with pytest.raises(ConfigError, match=msg):
Expand Down Expand Up @@ -501,8 +497,7 @@ def try_multiprocessing_code(
expected_cant_trace = cant_trace_msg(concurrency, the_module)

if expected_cant_trace is not None:
print(out)
assert out == expected_cant_trace
assert expected_cant_trace in out
pytest.skip(f"Can't test: {expected_cant_trace}")
else:
assert out.rstrip() == expected_out
Expand Down Expand Up @@ -579,9 +574,6 @@ def test_multiprocessing_with_branching(self, start_method: str) -> None:
code = (SQUARE_OR_CUBE_WORK + MULTI_CODE).format(NPROCS=nprocs, UPTO=upto)
total = sum(x * x if x % 2 else x * x * x for x in range(upto))
expected_out = f"{nprocs} pids, total = {total}"
expect_warn = (
env.PYBEHAVIOR.pep669 and (not env.PYBEHAVIOR.branch_right_left) and testenv.SYS_MON
)
self.make_file("multi.py", code)
self.make_file(
"multi.rc",
Expand All @@ -590,8 +582,7 @@ def test_multiprocessing_with_branching(self, start_method: str) -> None:
concurrency = multiprocessing
branch = True
omit = */site-packages/*
"""
+ ("disable_warnings = no-sysmon" if expect_warn else ""),
""",
)

out = self.run_command(f"coverage run --rcfile=multi.rc multi.py {start_method}")
Expand Down
21 changes: 6 additions & 15 deletions tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,9 @@ def test_core_request_sysmon(self) -> None:
if status == 0:
assert out.endswith("123 456\n")
core = re_line(r" core:", out).strip()
warns = re_lines(r"\(no-sysmon\)", out)
assert core == "core: SysMonitor"
assert not warns
else:
assert out.endswith(
"Can't use core=sysmon: sys.monitoring isn't available in this version\n"
)
assert "Can't use core=sysmon: sys.monitoring isn't available in this version;" in out

def test_core_request_sysmon_no_dyncontext(self) -> None:
# Use config core= for this test just to be different.
Expand All @@ -103,12 +99,9 @@ def test_core_request_sysmon_no_dyncontext(self) -> None:
)
out = self.run_command("coverage run --debug=sys numbers.py", status=1)
if env.PYBEHAVIOR.pep669:
assert (
"Can't use core=sysmon: sys.monitoring doesn't yet support dynamic contexts\n"
in out
)
assert "Can't use core=sysmon: it doesn't yet support dynamic contexts;" in out
else:
assert "Can't use core=sysmon: sys.monitoring isn't available in this version\n" in out
assert "Can't use core=sysmon: sys.monitoring isn't available in this version;" in out

def test_core_request_sysmon_no_branches(self) -> None:
# Use config core= for this test just to be different.
Expand All @@ -124,19 +117,17 @@ def test_core_request_sysmon_no_branches(self) -> None:
status = 0
elif env.PYBEHAVIOR.pep669:
status = 1
msg = "Can't use core=sysmon: sys.monitoring can't measure branches in this version\n"
msg = "Can't use core=sysmon: sys.monitoring can't measure branches in this version;"
else:
status = 1
msg = "Can't use core=sysmon: sys.monitoring isn't available in this version\n"
msg = "Can't use core=sysmon: sys.monitoring isn't available in this version;"
out = self.run_command("coverage run --debug=sys numbers.py", status=status)
if status == 0:
assert out.endswith("123 456\n")
core = re_line(r" core:", out).strip()
warns = re_lines(r"\(no-sysmon\)", out)
assert core == "core: SysMonitor"
assert not warns
else:
assert out.endswith(msg) # pylint: disable=possibly-used-before-assignment
assert msg in out # pylint: disable=possibly-used-before-assignment

def test_core_request_nosuchcore(self) -> None:
# Test the coverage misconfigurations in-process with pytest. Running a
Expand Down
1 change: 0 additions & 1 deletion tests/test_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -1545,7 +1545,6 @@ def f2():
".coveragerc",
"""\
[run]
disable_warnings = no-sysmon
patch = subprocess
""",
)
Expand Down
Loading