Skip to content

SPM county input check skips a mistyped county carried over to a later year #9749

Description

@MaxGhenis

What happens

county_fips is documented as a five-digit string, and the SPM forecast provider rejects a county supplied as anything else ("County 36061 was supplied for 2024 as 36061, not as text"). That rejection is skipped when the measurement is calculated for a year the input was not stored for.

from policyengine_us import Simulation

situation = {
    "people": {"person": {"age": {2024: 40}}},
    "households": {
        "household": {"members": ["person"], "county_fips": {2024: 36_061}}
    },
}
sim = Simulation(situation=situation)
sim.calculate("county_fips", 2025)             # array([36061], dtype=object): the integer, carried over
sim.calculate("spm_unit_spm_threshold", 2025)  # returns about 22,091 instead of raising
sim.calculate("spm_unit_spm_threshold", 2024)  # raises SPM_GEOGRAPHY_REQUIRED, as intended

Observed on main at fbe24ad with policyengine-core 3.32.8.

Why

  • SPMSimulationMixin._record_county_input_types (policyengine_us/spm.py) records non-text counties for each period the holder stores, and CountyRequiringSPMProvider.record_county_input_types keys them by (year, county text).
  • require_county_input(year, county_fips) looks the county up under the year being calculated.
  • For an input variable with no value in the requested period, core's Simulation._calculate returns the array stored for the latest known period (the auto_carry_over_input_variables block). So 2025 consumes the 2024 integer, while the record only has a 2024 key.

Dataset runs are mostly unaffected, because the dataset loader stores county_fips for every year it extends to. Household situations that give one input year and calculate another are the exposed path.

What a fix needs to keep

  • Correcting an input clears its rejection for that year.
  • A national geography selection records nothing.
  • Each simulation and branch holds its own provider and is judged by the county it reads itself.

Carry-over semantics differ between core versions (PolicyEngine/policyengine-core#562 proposes carrying over inputs only), so the fix should key on what the simulation actually reads for the requested year instead of re-implementing core's rule.

Found while fixing the branch read of the same check.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions