Repository navigation
Conversation
…vide Population.__call__ passes decode_enums=False to calculate_add or calculate_divide for every options=[ADD] or options=[DIVIDE] read in a formula, as it has since 0abe43a. Simulation's methods take that argument, but Microsimulation's overrides did not, so every such read raised a TypeError in a Microsimulation. Both overrides now take decode_enums, with Simulation's default of False, and pass it to super(). Simulation.calculate_add and calculate_divide accept the flag without using it, so every call that worked before returns the same values. Example tests run formulas that read with ADD and DIVIDE on a small country-template system. Hypothesis properties check that a Microsimulation's unweighted reads equal a Simulation's over generated data and read sequences, and that formula results equal the same arithmetic in NumPy. A strict xfail records that an Enum read with DIVIDE returns labels in a Microsimulation and an EnumArray in a Simulation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
In a Microsimulation, calculate_add and calculate_divide return a MicroSeries, and pandas pairs two Series' values by index label. GroupPopulation.project labels each member's value with its group's position. So a formula that projected such a read and combined it with another Series raised a ValueError, or, when every group had one member and the data listed them out of group order, paired members with another group's value. policyengine-us's wi_wheap_categorically_eligible has that shape (lines 38-44). Population.__call__ now returns the NumPy array a Simulation returns for these reads. They raised a TypeError in every Microsimulation on master, so no value that computed before moves. The fixture now takes each person's household, so data can list members in any order, and adds fee_or_all_paid, a reader with the PE-US formula's shape. The Enum DIVIDE test now records both classes' results instead of failing as a strict xfail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…order Population calls and calculate_add and calculate_divide requests now pair each variable with periods its option accepts, and population calls read only variables the population can read, so they return values instead of mostly raising in both classes. The data lists people in any order. hypothesis.event reports the mix of values, zeros and errors. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… run A new property checks that each population call a formula makes with ADD or DIVIDE returns a NumPy array in both classes. The NumPy-arithmetic property now runs for each formula, 25 examples each: with 100 examples drawn across all ten, one seeded run never drew fee_or_all_paid or members_grant_divided. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
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.
On master, a formula that reads a variable with
options=[ADD]oroptions=[DIVIDE]raises this error in aMicrosimulation, though aSimulationcomputes it:A policyengine-us impact run hit the error on
spm_unit("snap", period, options=[ADD])inmt_liheap_categorical_eligibility.py(PolicyEngine/policyengine-us#10141 (comment)). On policyengine-us main (PolicyEngine/policyengine-us@2b39b88e2f), 21 formulas read withoptions=[ADD], and each raises the error whenever aMicrosimulationcomputes it.Cause
Population.__call__has passeddecode_enums=Falsewith every read since 0abe43a (December 2022), and it sends reads withoptions=[ADD]oroptions=[DIVIDE]tocalculate_addorcalculate_divide(population.py#L147-L163).Simulation.calculate_addandcalculate_dividetake it (simulation.py#L2057-L2062, #L2126-L2131), butMicrosimulationoverrides both without it (microsimulation.py#L84-L118), so Python rejects the call.Plain reads go to
calculate, which takes the flag. When a formula reads a monthly flow over a year or a yearly flow over a month,Simulation._calculatecallscalculate_addorcalculate_dividewithout the flag (simulation.py#L1741-L1753), so those reads kept working.Fix
Both overrides now take
decode_enums: bool = False,Simulation's default, and pass it tosuper().Simulation.calculate_addandcalculate_divideaccept the flag without using it, and the new parameter goes last, so every call that worked before returns the same values.Invariants and tests
tests/fixtures/microsimulation_option_reads.pyadds to the country template nine formulas that read with ADD or DIVIDE. They read person and household variables, sum members' values into households, compare a sum with zero and call theaddhelper.tests/core/test_microsimulation_option_reads_property.pychecks two properties with Hypothesis:Microsimulation's unweighted reads equal aSimulation's, or both raise the same type of error. Hypothesis generates one to four households of one to three people, with weights and monthly and yearly inputs, and up to six reads in sequence. The reads cover the formulas, the population calls they make,calculate_addandcalculate_dividewith either value ofdecode_enums, and plain reads at months, years and a three-month period (200 examples).Example tests in
tests/core/test_microsimulation_option_reads.pycheck hand-computed values for each formula, the weights on a weighted result, seven population calls, and both methods with each value ofdecode_enums.On master, 23 of the new tests fail with the
TypeError, and Hypothesis shrinks the first property to("calculate", "allowance_divided", "2022"). On this branch the new tests pass, apart from one strict xfail, and so do the full suite (uv run pytest tests: 2,873 passed, 4 skipped, 4 xfailed) andruff format --check ..A policyengine-us
Microsimulationhasn't run on this branch, because the machine that built it caps memory for local microsimulation runs. Each of the 21 policyengine-us formulas reachesMicrosimulation.calculate_addthroughPopulation.__call__, then clips, compares, divides or adds the result, or sums it over a group withspm_unit.sum,.alloradd. Those operations return the same values for aMicroSeriesas for an array.Not changed here
Simulation.calculate_addandcalculate_divideread each term withself.calculate, which in aMicrosimulationdecodes Enums and applies weights by default (simulation.py#L2093-L2096, #L2152-L2160). So an Enum read with DIVIDE at a year returns labels in aMicrosimulationand anEnumArrayin aSimulation, andtest_enum_read_with_divide_in_a_microsimulation_matches_a_simulationrecords the difference as a strict xfail. No policyengine-us formula reads an Enum this way: the 21 formulas read 41 variables, all floats.Microsimulationthese reads return aMicroSeries, as reads thatSimulation._calculatesends tocalculate_addalready do on master. Its.sum()and.mean()apply weights, and none of the 21 formulas calls either on the read.Microsimulationbut has "micro" in its name, such as policyengine-uk's,Population.__call__passesunweighted=Trueto the calculate methods.Simulation.calculate_addandcalculate_dividedon't accept that argument, but on policyengine-uk main (PolicyEngine/policyengine-uk@1d4d020aa) no formula reads with ADD or DIVIDE.impact: no output moves for any variable that computed before; the 21 PE-US formulas that crashed in Microsimulation now compute
axiom: n/a: core infrastructure fix
🤖 Generated with Claude Code