Skip to content

Commit 6b67330

Browse files
committed
fix: ensure absolute paths are relative when combined #1752
If two data files are combined, one with absolute paths, and one with relative, with relative_files=True in effect, the results depended on the order of combining. If the absolute files were seen first, they were added as absolute paths. If the relative files were seen first, a mapping rule was generated that would then remap the absolute paths when they were seen. This fix ensures that absolute paths are remapped even if they are seen first.
1 parent 6289be8 commit 6b67330

File tree

3 files changed

+27
-1
lines changed

3 files changed

+27
-1
lines changed

coverage/data.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,10 @@ def combinable_files(data_file: str, data_paths: Iterable[str] | None = None) ->
8888
# We never want to combine those.
8989
files_to_combine = [fnm for fnm in files_to_combine if not fnm.endswith("-journal")]
9090

91-
return files_to_combine
91+
# Sorting isn't usually needed, since it shouldn't matter what order files
92+
# are combined, but sorting makes tests more predictable, and makes
93+
# debugging more understandable when things go wrong.
94+
return sorted(files_to_combine)
9295

9396

9497
def combine_parallel_data(

coverage/files.py

+3
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,9 @@ def map(self, path: str, exists:Callable[[str], bool] = source_exists) -> str:
489489

490490
# If we get here, no pattern matched.
491491

492+
if self.relative:
493+
path = relative_filename(path)
494+
492495
if self.relative and not isabs_anywhere(path):
493496
# Auto-generate a pattern to implicitly match relative files
494497
parts = re.split(r"[/\\]", path)

tests/test_api.py

+20
Original file line numberDiff line numberDiff line change
@@ -1465,3 +1465,23 @@ def test_combine_parallel_data_keep(self) -> None:
14651465
# After combining, the .coverage file & the original combined file should still be there.
14661466
self.assert_exists(".coverage")
14671467
self.assert_file_count(".coverage.*", 2)
1468+
1469+
@pytest.mark.parametrize("abs_order, rel_order", [(1, 2), (2, 1)])
1470+
def test_combine_absolute_then_relative_1752(self, abs_order: int, rel_order: int) -> None:
1471+
# https://github.com/nedbat/coveragepy/issues/1752
1472+
# If we're combining a relative data file and an absolute data file,
1473+
# the absolutes were made relative only if the relative file name was
1474+
# encountered first. Test combining in both orders and check that the
1475+
# absolute file name is properly relative in either order.
1476+
FILE = "sub/myprog.py"
1477+
self.make_file(FILE, "a = 1")
1478+
1479+
self.make_data_file(suffix=f"{abs_order}.abs", lines={abs_file(FILE): [1]})
1480+
self.make_data_file(suffix=f"{rel_order}.rel", lines={FILE: [1]})
1481+
1482+
self.make_file(".coveragerc", "[run]\nrelative_files = True\n")
1483+
cov = coverage.Coverage()
1484+
cov.combine()
1485+
data = coverage.CoverageData()
1486+
data.read()
1487+
assert {'sub/myprog.py'} == data.measured_files()

0 commit comments

Comments
 (0)