Skip to content

Hash pyi files after ruff post-processing in pyi_generator#6640

Open
masenf wants to merge 2 commits into
mainfrom
claude/peaceful-curie-ew0aa9
Open

Hash pyi files after ruff post-processing in pyi_generator#6640
masenf wants to merge 2 commits into
mainfrom
claude/peaceful-curie-ew0aa9

Conversation

@masenf

@masenf masenf commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator

pyi_hashes.json entries were computed as each stub was written, before
scan_all ran ruff format and ruff check --fix over the generated
files. Since ruff materially rewrites the stubs (quoting, wrapping,
import fixes), the registry recorded hashes of intermediate content
that never exists on disk afterwards: any generator change affecting
only the pre-format output flagged hash changes even when the final
.pyi files were byte-for-byte identical.

_scan_file now just records which .pyi files were written, and scan_all
computes the md5 hashes from the final on-disk content after ruff
post-processing. written_files becomes a per-instance list (it was a
mutable class attribute shared across generator instances) and the dead
modules/root/current_module class attributes are dropped.

pyi_hashes.json is regenerated with the new scheme (one-time value
churn for every entry; keys unchanged). Verified idempotent across
repeated --force runs and explicit-target merge runs.

pyi_hashes.json entries were computed as each stub was written, before
scan_all ran `ruff format` and `ruff check --fix` over the generated
files. Since ruff materially rewrites the stubs (quoting, wrapping,
import fixes), the registry recorded hashes of intermediate content
that never exists on disk afterwards: any generator change affecting
only the pre-format output flagged hash changes even when the final
.pyi files were byte-for-byte identical.

_scan_file now just records which .pyi files were written, and scan_all
computes the md5 hashes from the final on-disk content after ruff
post-processing. written_files becomes a per-instance list (it was a
mutable class attribute shared across generator instances) and the dead
modules/root/current_module class attributes are dropped.

pyi_hashes.json is regenerated with the new scheme (one-time value
churn for every entry; keys unchanged). Verified idempotent across
repeated --force runs and explicit-target merge runs.
@masenf masenf requested a review from a team as a code owner June 10, 2026 00:53
@greptile-apps

greptile-apps Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a bug where pyi_hashes.json entries were computed from the intermediate generator output before ruff format / ruff check --fix rewrote the stubs, causing spurious hash changes even when the final on-disk .pyi files were byte-for-byte identical. Hashes are now computed from the final on-disk content after ruff post-processing.

  • _write_pyi_file is simplified to -> None; _scan_file now returns the .pyi path string instead of a (path, hash) tuple; scan_all computes hashes from disk after ruff runs and writes them only in the use_json path.
  • PyiGenerator.written_files is moved from a mutable class attribute (shared across all instances) to a per-instance list initialized in a new __init__, fixing a latent shared-state bug.
  • strict=False is tightened to strict=True in the non-prune zip branch; a new regression test (test_hashes.py) verifies the recorded hash matches the post-ruff file content end-to-end.

Confidence Score: 5/5

Safe to merge — the change is narrowly scoped to hash-timing and a class-attribute cleanup with no behavioral impact on stub generation itself.

The stub writing logic is unchanged; only the moment at which hashes are computed moves (from before ruff to after). The mutable class-attribute fix eliminates a potential cross-instance contamination. The new test exercises the full end-to-end path.

No files require special attention.

Important Files Changed

Filename Overview
packages/reflex-base/src/reflex_base/utils/pyi_generator.py Moves hash computation to after ruff post-processing; fixes shared mutable class attribute bug in PyiGenerator; tightens zip strict=True in non-prune path
tests/units/reflex_base/utils/pyi_generator/test_hashes.py New regression test that verifies recorded hash matches on-disk content after ruff processes the generated stub
tests/units/reflex_base/utils/pyi_generator/test_regression.py Updated written_files iteration to match new list[str] type (was list[tuple[str,str]])
pyi_hashes.json All 124 hash values regenerated to reflect post-ruff file content; keys are unchanged
packages/reflex-base/news/+pyi_hashes_post_ruff.bugfix.md Changelog entry describing the hash computation fix

Reviews (2): Last reviewed commit: "Re-trigger CI" | Re-trigger Greptile

@codspeed-hq

codspeed-hq Bot commented Jun 10, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 26 untouched benchmarks
⏩ 8 skipped benchmarks1


Comparing claude/peaceful-curie-ew0aa9 (780ed9b) with main (fdb00db)

Open in CodSpeed

Footnotes

  1. 8 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

integration-app-harness-playwright (redis, 3.11) failed to pull the
redis image from Docker Hub (context deadline exceeded) before any
tests ran; all 105 other checks passed. Empty commit to re-roll.

https://claude.ai/code/session_01APPJC9ZSmcHQy9WkzfxqVs
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