Visitar URL original
fix: hash the data in a parallel data file, not only the data we added by mppyxx · Pull Request #2387 · coveragepy/coveragepy · GitHub
Skip to content

fix: hash the data in a parallel data file, not only the data we added - #2387

Open
mppyxx wants to merge 2 commits into
coveragepy:mainfrom
mppyxx:fix-2370-hash-data-in-file
Open

mppyxx wants to merge 2 commits into
coveragepy:mainfrom
mppyxx:fix-2370-hash-data-in-file

Conversation

@mppyxx

@mppyxx mppyxx commented Nov 11, 2026

Copy link
Copy Markdown

Fixes #2370.

Since 160ad3b (7.13.1) a parallel data file's name carries a hash, and combine skips files whose hash it has already seen. The hash only covered data added through that CoverageData object, so data that reached the file another way left the name describing different data. With coverage's own API alone:

cov = coverage.Coverage(data_suffix=True)
cov.start(); cov.stop()
cov.combine()   # pulls another parallel file's data in
cov.save()

On main the saved file is named with the empty-data hash (...HNQIp837rWOh) although it holds the combined data. In #2370, nbval has the notebook kernel write into pytest-cov's data file, which pytest-cov then saves with that empty hash. A python -c pass child gets the same hash, and combine skips and deletes the other file. Which one is lost depends on whether the host name sorts before H.

The fix: write() hashes the data that is in the file (the file, context, line_bits, arc and tracer tables in id order) and the per-call hashing in set_context and add_* goes away. Combine still reads the hash from the name, so 160ad3b's speedup stays.

Cost: one save got cheaper in my timings (arcs, 400 files x 250, 168 to 109 ms), but every write() now rescans the file, so a process that saves many times pays that each time. If that matters, the scan could run only when the file may have changed underneath us, for example by checking SQLite's PRAGMA data_version.

This removes the add_arcs hashing line that #2376 speeds up, so it overlaps that PR. #2376 measured the same arc cost. I'm happy to rebase onto it if it lands first.

Tests: two regression tests in tests/test_data.py (data written by another object, data from update()) fail on main and pass here. tox -e py312,lint,mypy passes, and the reporter's notebook repro (with a host name before H) goes from "No data to report" to 4 lines.

AI note: Claude Code prepared this on my behalf: it traced the cause, wrote the fix, tests and this text, and ran the checks. A separate Claude review pass checked it before I opened the PR.

🤖 Generated with Claude Code

Copilot AI balanced review requested due to automatic review settings November 11, 2026 00:55

This comment was marked as low quality.

The hash in a parallel data file's name came from the data that its
CoverageData object added itself. Other data can be in the file too:
from update() or loads(), or from another CoverageData writing to the
same file. nbval does the last one, pointing a notebook kernel's
Coverage at pytest-cov's data file. That file then got the hash of an
empty data set, the same hash as a subprocess that measured nothing,
and combining skipped it as a duplicate and deleted it.

Now write() computes the hash from the data in the file.

Fixes coveragepy#2370

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mppyxx
mppyxx force-pushed the fix-2370-hash-data-in-file branch from 7ca845b to b2d7984 Compare November 11, 2026 00:55
@nedbat

nedbat commented Nov 13, 2026

Copy link
Copy Markdown
Member

Could you provide clear instructions to reproduce the problem? Files to create, packages to install, commands to run, expected and actual outputs. Thanks.

This branch has not been deployed

No deployments
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.

Notebook kernel coverage lost under pytest + nbval + pytest-cov (combine prints "Skipping duplicate data"). Since 7.13.1

3 participants