-
-
Notifications
You must be signed in to change notification settings - Fork 466
Description
Title
coverage combine with relative_files=true collapses nested directories with duplicate names, causing data loss
Description
Summary
When using relative_files=true, coverage combine generates overly broad path mapping rules that collapse files from nested directories sharing the same name. For example, both features/templates.py and pkg/features/templates.py map to features/templates.py, causing coverage data loss.
Expected vs Actual
Expected: Both files tracked separately
features/templates.py→features/templates.pypkg/features/templates.py→pkg/features/templates.py
Actual: Nested file collapses into root-level file
features/templates.py→features/templates.py✓pkg/features/templates.py→features/templates.py❌ (data lost)
Reproducer
Minimal reproduction: https://github.com/dephiros/pytest-coverage-path-bug
# Clone and setup
git clone https://github.com/dephiros/pytest-coverage-path-bug.git
cd pytest-coverage-path-bug
uv sync
# Run workflow
uv run coverage erase
COVERAGE_DEBUG=pathmap uv run coverage run --parallel-mode -m pytest
COVERAGE_DEBUG=pathmap uv run coverage combine
uv run coverage reportResult: Report shows 44 statements instead of 48. pkg/features/templates.py is missing.
Without combine (for comparison):
uv run coverage erase
uv run coverage run -m pytest # No --parallel-mode
uv run coverage reportResult: Report correctly shows 48 statements with all files.
Debug Output
coverage combine shows the collision:
Generating rule: '*/features' -> 'features/' using regex '^(.*[\\\\/])?features[\\\\/]'
Matched path 'features/templates.py' to rule '*/features' -> 'features/', producing 'features/templates.py'
Matched path 'pkg/features/templates.py' to rule '*/features' -> 'features/', producing 'features/templates.py'
The */features rule matches any path ending with /features/, causing the collision.
Versions
- Python: 3.11.10
- coverage.py: 7.11.0
- pytest: 8.4.2
- pytest-cov: 7.0.0
Config
[tool.coverage.run]
relative_files = true
branch = true
source = ["."]Repository Structure
.
├── features/
│ └── templates.py # 4 statements
├── pkg/
│ └── features/
│ └── templates.py # 4 statements - GETS COLLAPSED
└── pyproject.toml
Related Issues
- Path mapping collapses nested directories with identical names pytest-dev/pytest-cov#724 - Initially filed against pytest-cov, but investigation revealed the bug is in
coverage combineitself