Skip to content

Give the Social Security state backend the situation hook Core's builder will call - #10850

Merged
hua7450 merged 1 commit into
mainfrom
ss-backend-preprocess-situation-hook
Nov 12, 2026
Merged

hua7450 merged 1 commit into
mainfrom
ss-backend-preprocess-situation-hook

Conversation

@hua7450

@hua7450 hua7450 commented Nov 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

PolicyEngine/policyengine-core#600 adds TaxBenefitSystem.preprocess_situation, which SimulationBuilder.build_from_entities calls before building an entity-form situation. tests/core/_social_security_state_backend.py copies build_from_entities from the installed Core into a stand-in System that has no such method. CI installs the newest Core, so once Core releases the hook, test_social_security_input_state_machine.py would fail with an AttributeError on every PR, as it did after Core 3.33.13 (#10504) and 3.34.8 (#10684).

This PR gives the stand-in System a preprocess_situation that returns the situation unchanged. Today's Core never calls it, so the test behaves the same until the Core release, and the release doesn't break it.

The break comes from reading the backend and Core 600's builder change; the test was not run locally against Core 600.

Related

axiom: n/a: test fixture only, no change to a legal provision.

🤖 Generated with Claude Code

policyengine-core PR 600 makes SimulationBuilder.build_from_entities call
TaxBenefitSystem.preprocess_situation before building a situation. The
Social Security state-machine backend copies that method into a stand-in
system without the hook, so a Core release with it would fail the test.
Add a no-op hook; today's Core never calls it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@PavelMakarchuk PavelMakarchuk left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: APPROVE — the fix is correct, minimal, and safe to merge before PolicyEngine/policyengine-core#600 releases.

Suggestions

  • The PR body can now state a tested result. The body says the break "comes from reading the backend and Core 600's builder change; the test was not run locally against Core 600". I ran it; see below.
  • Comment wording (policyengine_us/tests/core/_social_security_state_backend.py:270-272). "policyengine-core PR 600" will age once the release has a version number. The nearby comment for _restore_count uses the form "From Core 3.33.13"; the same form here would match after the release. Optional.
  • Longer term. This fixture has now needed a patch for three Core changes (3.33.13, 3.34.8, and this one), because it runs Core's method bodies on a stand-in system. A tolerant lookup in Core would avoid this case; I raised it as an optional point on PolicyEngine/policyengine-core#600. No change needed here.

What I verified

  • The claim, reproduced. policyengine_us/tests/core/test_social_security_input_state_machine.py runs Core's build_from_dict -> build_from_entities source against the backend's stand-in System (lines 760-769 of the test; the backend copies the builder methods at _social_security_state_backend.py:662-675).

    Core installed Backend file Result
    3.34.10 (released, no hook) main 1 passed
    3.34.10 (released, no hook) this PR 1 passed
    PolicyEngine/policyengine-core#600 head f37aef590a main 1 failed: AttributeError: 'System' object has no attribute 'preprocess_situation' at simulation_builder.py:229
    PolicyEngine/policyengine-core#600 head f37aef590a this PR 1 passed
  • CI exposure is real. The workflows run uv lock --upgrade-package policyengine-core (.github/workflows/pr.yaml:200, push.yaml:228, and others), so every PR would pick up the Core release.

  • Signature. preprocess_situation(self, situation, default_period=None) matches Core's default and the call tax_benefit_system.preprocess_situation(input_dict, self.default_period). It returns the same dict, so the builder's type check passes. The fixture's situations always supply households, so an identity hook is the right behavior.

  • No other stand-in is affected. I searched for every class that duck-types a system (MockSystem, FakeTaxBenefitSystem, _StubSystem, _RecordingSystem) and every caller of build_from_dict / build_from_entities. Only this backend passes a non-TaxBenefitSystem object to Core's entity builder. The other callers use the real CountryTaxBenefitSystem or a Core TaxBenefitSystem, which inherit the default hook. With the Core PR head installed, the 8 test files that hold those stand-ins and builder callers pass (362 passed).

  • Repo rules. changelog.d/ss-backend-preprocess-situation-hook.fixed.md is a top-level fragment with a valid type. The body has axiom: n/a: test fixture only, no change to a legal provision.

  • Diff scope. 2 files, +7/-0; no model code changes.

  • CI at 1:57pm EST on Nov 12: 37 of 37 checks pass on head f1f04b5777.

@hua7450
hua7450 merged commit 9d0d881 into main Nov 12, 2026
37 checks passed
@hua7450
hua7450 deleted the ss-backend-preprocess-situation-hook branch November 12, 2026 19:27
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