From 5290b0f3acf2f375f46b4beb6b43e56a690de4db Mon Sep 17 00:00:00 2001
From: Jeremy Fleischman <jeremyfleischman@gmail.com>
Date: Thu, 27 Mar 2025 10:43:42 -0500
Subject: [PATCH] Ensure source dirs are absolute

This `COV_CORE_SOURCE` environment variable is key for making sure that
child processes continue computing code coverage. However, there's no
guarantee that child processes start in the same directory as their parent
process, which screws up coverage reporting if you're using relative
paths for coverage sources. The fix is to make sure we're dealing with
absolute paths.

This is a little tricky to get right, because sources can include both
dirs and packages.

This fixes https://github.com/pytest-dev/pytest-cov/issues/465
---
 src/pytest_cov/engine.py | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/src/pytest_cov/engine.py b/src/pytest_cov/engine.py
index 826205d7..01214bb2 100644
--- a/src/pytest_cov/engine.py
+++ b/src/pytest_cov/engine.py
@@ -108,7 +108,17 @@ def set_env(self):
         if self.cov_source is None:
             os.environ['COV_CORE_SOURCE'] = os.pathsep
         else:
-            os.environ['COV_CORE_SOURCE'] = os.pathsep.join(self.cov_source)
+            os.environ['COV_CORE_SOURCE'] = os.pathsep.join(
+                # We must make the paths absolute to ensure that subprocesses started in different
+                # directories still find the same sources: https://github.com/nedbat/coveragepy/issues/1942.
+                # Unfortunately, coverage.py doesn't provide a mechanism
+                # for unambiguously specifying source_dirs, so we have to detect if a source is
+                # a directory or a package by looking in the filesystem: https://github.com/nedbat/coveragepy/issues/1942.
+                os.path.abspath(source)  # noqa: PTH100 #  see note below for why we're using `os.path.abspath`
+                if Path(source).is_dir()
+                else source
+                for source in self.cov_source
+            )
         config_file = Path(self.cov_config)
         if config_file.exists():
             os.environ['COV_CORE_CONFIG'] = os.fspath(config_file.resolve())