diff --git a/CHANGES.rst b/CHANGES.rst index a22628bfd..0bfcee51b 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -28,16 +28,45 @@ Nothing yet. .. start-releases +.. _changes_7-11-2: + +Version 7.11.2 — 2025-11-08 +--------------------------- + +- Fix: using the "sysmon" measurement core in 7.11.1, if Python code was + claimed to come from a non-Python file, a ``NotPython`` exception could be + raised. This could happen for example with Jinja templates compiled to + Python, as reported in `issue 2077`_. This is now fixed. + +- Doc: corrected the first entry in the 7.11.1 changelog. + +.. _issue 2077: https://github.com/nedbat/coveragepy/issues/2077 + + .. _changes_7-11-1: Version 7.11.1 — 2025-11-07 --------------------------- +- Fix: some chanages to details of how the measurement core is chosen, and how + conflicting settings are handled. The "sysmon" core cannot be used with some + conurrency settings, with dynamic context, and in Python 3.12/3.13, with + branch measurement. + + - If the core is not specified and defaults to "sysmon" (Python 3.14+), but + other settings conflict with sysmon, then the "ctrace" core will be used + instead with no warning. For concurrency conflicts, this used to produce an + error, as described in `issue 2064`_. + + - If the "sysmon" core is explicitly requested in your configuration, but + other settings conflict, an error is now raised. This used to produce a + warning. + - Fix: if the measurement core defaults to "sysmon" (the default for Python 3.14+ since v7.9.1), but sysmon can't support some aspect of your configuration (concurrency settings, dynamic contexts, and so on), then the ctrace core is used instead. Previously, this would result in an error. - Now a warning is issued instead, explaining the fallback. An explicit request + An explicit request for sysmon with conflicting settings will still result in an error. Closes `issue 2064`_. diff --git a/coverage/core.py b/coverage/core.py index e88289ce3..6edb12432 100644 --- a/coverage/core.py +++ b/coverage/core.py @@ -137,3 +137,6 @@ def _debug(msg: str) -> None: self.systrace = True else: raise ConfigError(f"Unknown core value: {core_name!r}") + + def __repr__(self) -> str: + return f"" diff --git a/coverage/sysmon.py b/coverage/sysmon.py index a46c92620..c31da2c03 100644 --- a/coverage/sysmon.py +++ b/coverage/sysmon.py @@ -19,6 +19,7 @@ from coverage import env from coverage.bytecode import TBranchTrails, always_jumps, branch_trails from coverage.debug import short_filename, short_stack +from coverage.exceptions import NotPython from coverage.misc import isolate_module from coverage.parser import PythonParser from coverage.types import ( @@ -470,5 +471,12 @@ def sysmon_branch_either( def get_multiline_map(filename: str) -> dict[TLineNo, TLineNo]: """Get a PythonParser for the given filename, cached.""" parser = PythonParser(filename=filename) - parser.parse_source() + try: + parser.parse_source() + except NotPython: + # The file was not Python. This can happen when the code object refers + # to an original non-Python source file, like a Jinja template. + # In that case, just return an empty map, which might lead to slightly + # wrong branch coverage, but we don't have any better option. + return {} return parser.multiline_map diff --git a/coverage/version.py b/coverage/version.py index 3e59950de..9f4bb1edc 100644 --- a/coverage/version.py +++ b/coverage/version.py @@ -8,7 +8,7 @@ # version_info: same semantics as sys.version_info. # _dev: the .devN suffix if any. -version_info = (7, 11, 2, "alpha", 0) +version_info = (7, 11, 3, "alpha", 0) _dev = 1 diff --git a/doc/conf.py b/doc/conf.py index 37cf1f17a..ee0ee33c3 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -68,11 +68,11 @@ # @@@ editable copyright = "2009–2025, Ned Batchelder" # pylint: disable=redefined-builtin # The short X.Y.Z version. -version = "7.11.1" +version = "7.11.2" # The full version, including alpha/beta/rc tags. -release = "7.11.1" +release = "7.11.2" # The date of release, in "monthname day, year" format. -release_date = "November 7, 2025" +release_date = "November 8, 2025" # @@@ end rst_epilog = f""" diff --git a/doc/sample_html/class_index.html b/doc/sample_html/class_index.html index ea8dcedb7..2a82cd123 100644 --- a/doc/sample_html/class_index.html +++ b/doc/sample_html/class_index.html @@ -56,8 +56,8 @@

Classes

- coverage.py v7.11.1, - created at 2025-11-07 05:01 -0500 + coverage.py v7.11.2, + created at 2025-11-08 14:30 -0500

@@ -567,8 +567,8 @@

- coverage.py v7.11.1, - created at 2025-11-07 05:01 -0500 + coverage.py v7.11.2, + created at 2025-11-08 14:30 -0500

diff --git a/doc/sample_html/z_7b071bdc2a35fa80_hashhandler_py.html b/doc/sample_html/z_7b071bdc2a35fa80_hashhandler_py.html index b1d91d6b1..f086aae81 100644 --- a/doc/sample_html/z_7b071bdc2a35fa80_hashhandler_py.html +++ b/doc/sample_html/z_7b071bdc2a35fa80_hashhandler_py.html @@ -66,8 +66,8 @@

^ index     » next       - coverage.py v7.11.1, - created at 2025-11-07 05:01 -0500 + coverage.py v7.11.2, + created at 2025-11-08 14:30 -0500