FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Map only the matched prefix in PathAliases by ckarnell · Pull Request #2268 · coveragepy/coveragepy · GitHub

Map only the matched prefix in PathAliases - #2268

Merged
nedbat merged 4 commits into
coveragepy:mainfrom
ckarnell:fix-alias-replaces-every-occurrence
Aug 19, 2026
Merged

Map only the matched prefix in PathAliases#2268
nedbat merged 4 commits into
coveragepy:mainfrom
ckarnell:fix-alias-replaces-every-occurrence

Conversation

Copy link
Copy Markdown
Contributor

PathAliases.map substitutes with str.replace, so once a rule matches it rewrites every occurrence of the matched text, not just the part that matched:

new = path.replace(m[0], result)
aliases.add("/ci/src", "./mysrc")
aliases.map("/ci/src/vendor/ci/src/a.py", exists=lambda _: True)
# ./mysrc/vendor./mysrc/a.py
# want ./mysrc/vendor/ci/src/a.py

The second /ci/src is part of the file's real location, and it gets rewritten too. The separator normalisation on the next line then runs over the damage, which is where the vendor./mysrc comes from. Combining across machines is where this shows up, since the mapped path either fails the exists check and falls through to the next rule, or lands on the wrong file.

The regex is anchored with match, so slicing at the match bounds is the same thing the code already means.

Two open PRs touch this file, #2120 and #2233, and both change which rule matches, not the substitution. Different line, different failure. Happy to rebase behind either if you would rather land those first.

Tests are 425 passing across test_files.py, test_api.py and test_data.py. Reverting just the files.py line fails the new test in both its relative and absolute forms and nothing else, with the skip count at 7 either way.

str.replace rewrote every occurrence of the matched text, so a path that
repeats the aliased directory later on was rewritten twice.
Comment thread coverage/files.py Outdated
nedbat and others added 3 commits August 18, 2026 09:57
The alias result ./mysrc carries a forward separator, so map() keeps forward
slashes in relative mode on every platform. Wrapping the expected in os_sep()
rewrote it to backslashes on Windows only, so the [True] case failed there
while [False] passed (assert_mapped canonicalizes the non-relative expected).
Drop os_sep, matching the sibling test_wildcard with the same result.

Copy link
Copy Markdown
Contributor Author

The Windows failure was my test, not the change. In relative mode map() keeps the result's separator, and ./mysrc is forward slashed, so the output stays forward slashed on every platform. My expected value wrapped it in os_sep(), which flips to backslashes on Windows, so the [True] case failed there while [False] passed through canonical_filename first. I dropped the os_sep to match test_wildcard right above it. Pushed, CI should go green.

nedbat merged commit 9b05cc9 into coveragepy:main Aug 19, 2026
76 of 77 checks passed
nedbat added a commit that referenced this pull request Aug 19, 2026

nedbat commented Aug 28, 2026

Copy link
Copy Markdown
Member

This is now released as part of coverage 7.16.0.

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants


Back | FazBrowse Home | New Git URL