Skip to content

Commit

Permalink
fix: ensure absolute paths are relative when combined #1752
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
nedbat committed Mar 14, 2024
1 parent 1ef020d commit d62af86
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 1 deletion.
5 changes: 4 additions & 1 deletion coverage/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,10 @@ def combinable_files(data_file: str, data_paths: Iterable[str] | None = None) ->
# We never want to combine those.
files_to_combine = [fnm for fnm in files_to_combine if not fnm.endswith("-journal")]

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


def combine_parallel_data(
Expand Down
3 changes: 3 additions & 0 deletions coverage/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,9 @@ def map(self, path: str, exists:Callable[[str], bool] = source_exists) -> str:

# If we get here, no pattern matched.

if self.relative:
path = relative_filename(path)

if self.relative and not isabs_anywhere(path):
# Auto-generate a pattern to implicitly match relative files
parts = re.split(r"[/\\]", path)
Expand Down
20 changes: 20 additions & 0 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -1465,3 +1465,23 @@ def test_combine_parallel_data_keep(self) -> None:
# After combining, the .coverage file & the original combined file should still be there.
self.assert_exists(".coverage")
self.assert_file_count(".coverage.*", 2)

@pytest.mark.parametrize("abs_order, rel_order", [(1, 2), (2, 1)])
def test_combine_absolute_then_relative_1752(self, abs_order: int, rel_order: int) -> None:
# https://github.com/nedbat/coveragepy/issues/1752
# If we're combining a relative data file and an absolute data file,
# the absolutes were made relative only if the relative file name was
# encountered first. Test combining in both orders and check that the
# absolute file name is properly relative in either order.
FILE = "sub/myprog.py"
self.make_file(FILE, "a = 1")

self.make_data_file(suffix=f"{abs_order}.abs", lines={abs_file(FILE): [1]})
self.make_data_file(suffix=f"{rel_order}.rel", lines={FILE: [1]})

self.make_file(".coveragerc", "[run]\nrelative_files = True\n")
cov = coverage.Coverage()
cov.combine()
data = coverage.CoverageData()
data.read()
assert {os_sep("sub/myprog.py")} == data.measured_files()

0 comments on commit d62af86

Please sign in to comment.