test(determinism): sweep PYTHONHASHSEED and repeat cleaning 100 times - #477
Merged
Merged
Conversation
Determinism was thin at the public-API level. tests/test_properties.py:11 is two calls on one fixture, and PYTHONHASHSEED was set at exactly one site (test_plan_hash_and_mostly.py:134) for repair-plan hashing only. Nothing swept the hash seed across fd.clean itself, even though set and dict iteration order feeds category normalisation, dominant-variant selection and action ordering -- the places where a decision could silently track interpreter state. Three properties, on a frame that reaches dtype repair, sentinel handling, currency parsing and the semantic layer at once: - 100 repeated runs produce a single digest. - The digest is unchanged across PYTHONHASHSEED 0, 1, 42, 31337 and 65535, each measured in a subprocess because the seed is fixed at interpreter start. - report.to_dict() is stable between runs. The digest covers cell values, dtypes, every action's step, column, count, risk and status, and decisions_hash. Timing and memory fields are excluded on purpose and the exclusion list is named in the module docstring: they are documented as volatile, and report.peak_memory is process-lifetime RSS, which cannot be reproducible. Asserting otherwise would be asserting that a wall clock repeats. All three already hold, so these are regression guards. No library code changed. Full suite 6664 passed / 0 failed, coverage 93.90%; ruff clean repo-wide.
Contributor
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
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
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Determinism was thin at the public-API level.
tests/test_properties.py:11is two calls on one fixture, andPYTHONHASHSEEDwas set at exactly one site (test_plan_hash_and_mostly.py:134) for repair-plan hashing only.Nothing swept the hash seed across
fd.cleanitself — even though set and dict iteration order feeds category normalisation, dominant-variant selection and action ordering, which is precisely where a decision could silently track interpreter state.What is asserted
On a frame that reaches dtype repair, sentinel handling, currency parsing and the semantic layer at once:
PYTHONHASHSEED∈ {0, 1, 42, 31337, 65535}report.to_dict()across runsThe hash-seed cases run in a subprocess, because the seed is fixed at interpreter start and cannot be changed in-process.
What the digest covers
Cell values, dtypes, every action's
step/column/count/risk/status, anddecisions_hash.Timing and memory fields are excluded on purpose, and the exclusion list is named in the module docstring rather than hidden in a helper: they are documented as volatile, and
report.peak_memoryis process-lifetime RSS. Asserting they repeat would be asserting that a wall clock repeats.Verification
main, so these are regression guards.ruff check .clean repo-wide.