Skip to content

Commit bc8602d

Browse files
committed
fix: issue a warning if the C tracer can't be imported
1 parent d81a5f8 commit bc8602d

File tree

4 files changed

+21
-5
lines changed

4 files changed

+21
-5
lines changed

CHANGES.rst

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,11 @@ Unreleased
3030
- Fixed incorrect rendering of f-strings with doubled braces, closing `issue
3131
1980`_.
3232

33-
- The C extension module now conforms to `PEP 489`_, closing `issue 1977`_.
34-
Thanks, `Adam Turner <pull 1978_>`_.
33+
- The C tracer core extension module now conforms to `PEP 489`_, closing `issue
34+
1977`_. Thanks, `Adam Turner <pull 1978_>`_.
35+
36+
- If the C tracer core can't be imported, a warning ("no-ctracer") is issued
37+
with the reason.
3538

3639
- Fixed a "ValueError: min() arg is an empty sequence" error caused by strange
3740
empty modules, found by `oss-fuzz`_.

coverage/core.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,13 @@
2525

2626
os = isolate_module(os)
2727

28+
IMPORT_ERROR: str = ""
29+
2830
try:
2931
# Use the C extension code when we can, for speed.
3032
import coverage.tracer
3133
CTRACER_FILE: str | None = coverage.tracer.__file__
32-
except ImportError:
34+
except ImportError as imp_err:
3335
# Couldn't import the C extension, maybe it isn't built.
3436
# We still need to check the environment variable directly here,
3537
# as this code runs before configuration is loaded.
@@ -42,6 +44,7 @@
4244
# exception here causes all sorts of other noise in unittest.
4345
sys.stderr.write("*** COVERAGE_CORE is 'ctrace' but can't import CTracer!\n")
4446
sys.exit(1)
47+
IMPORT_ERROR = str(imp_err)
4548
CTRACER_FILE = None
4649

4750

@@ -89,6 +92,8 @@ def __init__(
8992
if CTRACER_FILE:
9093
core_name = "ctrace"
9194
else:
95+
if env.CPYTHON and IMPORT_ERROR:
96+
warn(f"Couldn't import C tracer: {IMPORT_ERROR}", slug="no-ctracer", once=True)
9297
core_name = "pytrace"
9398

9499
self.tracer_kwargs = {}

doc/cmd.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,11 @@ Conflicting dynamic contexts (dynamic-conflict)
274274
:meth:`.Coverage.switch_context` function to change the context. Only one of
275275
these mechanisms should be in use at a time.
276276

277+
Couldn't import C tracer (no-ctracer)
278+
The core tracer implemented in C should have been used, but couldn't be
279+
imported. The reason is included in the warning message. The Python tracer
280+
will be used instead.
281+
277282
sys.monitoring isn't available in this version, using default core (no-sysmon)
278283
You requested to use the sys.monitoring measurement core, but are running on
279284
Python 3.11 or lower where it isn't available. A default core will be used

tests/test_process.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,10 +1136,13 @@ def test_core_default(self) -> None:
11361136
core = re_line(r" core:", out).strip()
11371137
# if env.PYBEHAVIOR.pep669:
11381138
# assert core == "core: SysMonitor"
1139+
warns = re_lines(r"\(no-ctracer\)", out)
11391140
if self.has_ctracer:
11401141
assert core == "core: CTracer"
1142+
assert not warns
11411143
else:
11421144
assert core == "core: PyTracer"
1145+
assert bool(warns) == env.CPYTHON
11431146

11441147
@pytest.mark.skipif(not has_ctracer, reason="No CTracer to request")
11451148
def test_core_request_ctrace(self) -> None:
@@ -1164,12 +1167,12 @@ def test_core_request_sysmon(self) -> None:
11641167
out = self.run_command("coverage run --debug=sys numbers.py")
11651168
assert out.endswith("123 456\n")
11661169
core = re_line(r" core:", out).strip()
1167-
warns = re_lines(r"CoverageWarning: sys.monitoring isn't available", out)
1170+
warns = re_lines(r"\(no-sysmon\)", out)
11681171
if env.PYBEHAVIOR.pep669:
11691172
assert core == "core: SysMonitor"
11701173
assert not warns
11711174
else:
1172-
assert core in ("core: CTracer", "core: PyTracer")
1175+
assert core in ["core: CTracer", "core: PyTracer"]
11731176
assert warns
11741177

11751178
def test_core_request_nosuchcore(self) -> None:

0 commit comments

Comments
 (0)