Skip to content

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

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

Hash pyi files after ruff post-processing in pyi_generator#6640
masenf wants to merge 3 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 correctness bug in pyi_generator.py where pyi_hashes.json entries were computed from the raw ast.unparse output before ruff format / ruff check --fix rewrote the stubs, causing spurious hash changes for generator modifications that left the final .pyi files byte-for-byte identical.

  • _write_pyi_file now returns None instead of a hash, and _scan_file returns only the .pyi path as a string; scan_all reads each written file from disk after ruff post-processing to compute the md5.
  • written_files is moved from a shared class-level attribute to an instance attribute initialised in __init__, fixing a latent shared-mutable-state bug across PyiGenerator instances.
  • The zip in the merge path is upgraded to strict=True (safe because both lists are derived from the same source), and a regression test in test_hashes.py verifies the hash-after-ruff invariant end-to-end.

Confidence Score: 5/5

The change is safe to merge: it tightens correctness of the hash registry without affecting the generated .pyi content itself.

All changes are confined to the hash-computation path in pyi_generator and its tests. The generated stub content is unaffected; only when and how the md5 is captured changes. The mutable class-attribute bug fix and the strict=True upgrade are both unambiguously correct, and the new regression test covers the key invariant end-to-end.

No files require special attention.

Important Files Changed

Filename Overview
packages/reflex-base/src/reflex_base/utils/pyi_generator.py Core fix: _write_pyi_file no longer returns a hash, _scan_file returns only the pyi path, and scan_all hashes files post-ruff. Class-level shared mutable attributes removed in favour of an init-initialized instance attribute.
tests/units/reflex_base/utils/pyi_generator/test_hashes.py New regression test that verifies the hash in pyi_hashes.json matches the on-disk .pyi content after ruff post-processing rather than the intermediate generator output.
tests/units/reflex_base/utils/pyi_generator/test_regression.py Updated to treat gen.written_files as list[str] instead of list[tuple[str, str]] following the API change in pyi_generator.
pyi_hashes.json All 124 hash values regenerated with the new post-ruff scheme; keys are unchanged, values represent the final on-disk .pyi content.
packages/reflex-base/news/+pyi_hashes_post_ruff.bugfix.md Changelog entry accurately describing the bug fix.

Reviews (3): Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." | 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 (4dd5035) with main (b288bdc)

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.

claude and others added 2 commits June 10, 2026 01:21
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.

3 participants