refactor(testing): replace the pre-state auto-inject with field defaults#852
Merged
tcoratger merged 1 commit intoJun 5, 2026
Merged
Conversation
The filler wrapper sniffed each fixture class's annotations for a pre or anchor state field and silently injected a default genesis state into the constructor when the test omitted one. Meanwhile most state-transition tests passed the default explicitly anyway, leaving two competing mechanisms and a default invisible from the model. Changes: - the pre pytest fixture, the annotation sniffing, and the wrapper kwargs injection are deleted; the indirect-parametrization branch was already unused - the three fixtures carrying a pre-state field now declare the default where it belongs, as a field default factory producing the standard genesis state; the always-set fields lose their None branches and guards - the fork's spec accessor lost its only caller and is removed - tests adopt one convention: the standard genesis pre-state is omitted, only non-default pre-states are spelled out; the redundant no-argument calls are stripped Removing the accidental fork-package import in the consensus forks module exposed a latent import cycle in the spec itself: the xmss containers need the fork slot type, while the fork aggregation containers import the xmss containers back. Importing the crypto package first crashed; it only ever worked because some other module loaded the forks package earlier. The xmss package init now loads the forks package first, making the cycle resolve from any entry point. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Motivation
Item 6 of the
packages/testing/audit (follow-up to #848–#851). The pre-state default was a hybrid of two competing mechanisms:FixtureWrapper.__init__sniffed each fixture class's__annotations__for apre/anchor_statefield and silently injected a pytest-fixture-provided genesis state when the test omitted onestate_transition_testcalls passedpre=generate_pre_state()explicitly anyway, while 47/84fork_choice_testcalls relied on the magicWorst of both worlds: the default was invisible (the model declared
pre: Staterequired and a hidden wrapper papered over it), and the test suite had no consistent style.Changes
The magic dies; the default moves onto the model field — visible, standard Pydantic:
prepytest fixture, the annotation sniffing, and the wrapper kwargs injection are deleted (therequest.paramindirect branch was verified unused)| Nonetypes,None-branches, andassert ... is not NoneguardsLstar.spec_class()lost its only caller (the deletedprefixture) and is removedgenerate_pre_state(num_validators=8), advanced states,build_anchor(...)) — deviations from the baseline are now visually loudLatent import-cycle fix in the spec
Removing the accidental
LstarSpecimport from the consensus forks module exposed a real bug:import lean_spec.spec.crypto.xmsscrashes on current main with a circular-import error (xmss/containers.py→forks.lstar.slot→forks/__init__→aggregation.py→ back into the partially-initialized xmss containers). It only ever worked because some other module happened to load the forks package first. Fix at the root:xmss/__init__.pynow loads the forks package before its own containers, making the cycle resolve from any entry point (verified:xmss-first,forks-first, andconsensus_testingimports all succeed).Vector impact: none
The default factory produces exactly the state the deleted pytest fixture produced (same 4-validator genesis). The pre-state is always serialized into the emitted JSON, so clients see no difference.
Verification
just checkpasses (ruff, format, ty, codespell, mdformat)state_transition,verify_signatures,fork_choice— default and explicit paths): 14/14 pass🤖 Generated with Claude Code