From a28e79f9463c6c227403a13abd9f50fb6715c21a Mon Sep 17 00:00:00 2001 From: "Aryan Singh K." <70511529+aryansk@users.noreply.github.com> Date: Tue, 18 Aug 2026 16:57:36 +0530 Subject: [PATCH] fix: force trace core when dynamic contexts are requested MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When --cov-context=test is used, force the trace core instead of sysmon (the default on Python 3.14+) because sysmon does not support dynamic contexts and coveragepy >= 7.15.3 emits a warning: Dynamic contexts aren't supported with core=sysmon; context data may be incomplete (no-sysmon-context) The _coverage_core property returns 'trace' when cov_context == 'test', and None otherwise (preserving the default core selection). This is applied to all three Coverage() constructor call sites (Central, DistMaster, DistWorker). Fixes #755 🤖 Generated with Codebuff Co-Authored-By: Codebuff --- src/pytest_cov/engine.py | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/pytest_cov/engine.py b/src/pytest_cov/engine.py index a6a465fa..8db9ecad 100644 --- a/src/pytest_cov/engine.py +++ b/src/pytest_cov/engine.py @@ -60,6 +60,7 @@ def __init__(self, options: argparse.Namespace, config: Union[None, object], nod self.cov_append = options.cov_append self.cov_branch = options.cov_branch self.cov_precision = options.cov_precision + self.cov_context = getattr(options, 'cov_context', None) self.config = config self.nodeid = nodeid @@ -72,6 +73,19 @@ def __init__(self, options: argparse.Namespace, config: Union[None, object], nod self.is_collocated = None self.started = False + @property + def _coverage_core(self): + """Return the coverage core to use. + + When dynamic contexts are requested (--cov-context=test), + force the ``trace`` core because ``sysmon`` (the default on + Python 3.14+) does not support them and coveragepy >= 7.15.3 + emits a warning. (#755) + """ + if self.cov_context == 'test': + return 'trace' + return None + @contextlib.contextmanager def ensure_topdir(self): original_cwd = Path.cwd() @@ -234,12 +248,15 @@ class Central(CovController): @_ensure_topdir def start(self): - self.cov = coverage.Coverage( + cov_kwargs = dict( source=self.cov_source, branch=self.cov_branch, data_suffix=True, config_file=self.cov_config, ) + if self._coverage_core is not None: + cov_kwargs['core'] = self._coverage_core + self.cov = coverage.Coverage(**cov_kwargs) if self.cov.config.dynamic_context == 'test_function': message = ( 'Detected dynamic_context=test_function in coverage configuration. ' @@ -284,12 +301,15 @@ class DistMaster(CovController): @_ensure_topdir def start(self): - self.cov = coverage.Coverage( + cov_kwargs = dict( source=self.cov_source, branch=self.cov_branch, data_suffix=True, config_file=self.cov_config, ) + if self._coverage_core is not None: + cov_kwargs['core'] = self._coverage_core + self.cov = coverage.Coverage(**cov_kwargs) if self.cov.config.dynamic_context == 'test_function': raise DistCovError( 'Detected dynamic_context=test_function in coverage configuration. ' @@ -387,12 +407,15 @@ def start(self): self.cov_config = self.cov_config.replace(master_topdir, worker_topdir) # Erase any previous data and start coverage. - self.cov = coverage.Coverage( + cov_kwargs = dict( source=self.cov_source, branch=self.cov_branch, data_suffix=True, config_file=self.cov_config, ) + if self._coverage_core is not None: + cov_kwargs['core'] = self._coverage_core + self.cov = coverage.Coverage(**cov_kwargs) # Prevent workers from issuing module-not-measured type of warnings (expected for a workers to not have coverage in all the files). self.cov._warn_unimported_source = False self.cov.start()