Multi-period inputs in a variable's own unit: helper skipped, uprating base, storage aliasing
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 52/100
Research direction
Start in holder.py at Holder.set_input and trace how multi-period inputs reach the variable helper and storage. Use tests/fixtures/uprating_order.py and the existing year_input_without_helper tests referenced from #562 to compare current behavior. Done means the recommended B+C+E behavior is covered while existing period-based reads remain valid.
Written by the indexing model from the issue text.
Description
What happens
A variable stores an input for a period several units long in its own unit as given. Examples are year:2012:2 for a yearly variable and month:2012-01:3 for a monthly one. Holder.set_input calls the variable's set_input helper only when the input's unit differs from the variable's (holder.py, period.unit != self.variable.definition_period). So the key year:2012:2 is stored even for a variable whose helper is set_input_divide_by_period.
Auto-carry-over and uprating then read that key as the variable's value in each year it covers. Four consequences follow. All four were executed on #563's head with the test fixtures in tests/fixtures/uprating_order.py, using index values of 100 × 1.037^(year − 2010):
- The helper is skipped.
uprated(helperset_input_divide_by_period) givenyear:2012:2 = 100storesyear:2012:2, not2012and2013at 50 each.carried(no uprating, same helper) given the same input carries 100 into 2013 and 2014. - Uprating within the covered span.
uprated_any_unitgiven onlyyear:2012:2 = 1returns 1.037 for 2013, a year the input covers. The uprating factor runs from the source'sstart(2012), not from the last year it covers. - An input starting on the requested period is not an uprating source. Uprating takes only inputs that start before the period. Given
2011 = 1andyear:2012:2 = 5, 2012 gets 2011's input uprated (1.037), not 5. Auto-carry-over would carry 5. Given onlyyear:2012:2 = 5, 2012 gets 5 with auto-carry-over and the default (0) without it, while 2013 gets 5 × 1.037 either way. - Ties between inputs that start on the same day (
2012andyear:2012:2) used to go to whichever was stored first. PR #582 fixes that one: it takes the one that ends last, the same order auto-carry-over uses (#562). - A period whose string form is another period's. Storage keys are period strings, and
str(period("month:2012-01:12"))is"2012". So a twelve-month input from January to a monthly variable is stored as the year 2012 and read back as a yearly period.uprated_monthlygivenmonth:2012-01:12 = 7storesPeriod(('year', 2012-01-01, 1)). With auto-carry-over it then carries 7 unchanged to 2013-03, because a yearly period is never a monthly variable's uprating source. Without auto-carry-over it returns 0 for 2012-02, a month the input covers.
Exposure
None known. PE-US's eCPS and PE-UK's Enhanced FRS store single years only: the eCPS h5 has period keys 2024 and 2025, and PE-UK's loader calls set_input(variable, year, …) for each year in dataset.years. Neither repository's source or YAML tests set a multi-period variable input. Every year:…:N string in either repository is a parameter update.
Options
- A. Leave it. Multi-period own-unit inputs keep today's semantics (#582 makes ties deterministic).
- B. Call the helper for any multi-period input (
period.size > 1), so a variable with a helper splits or copies it into single periods. Helper-less variables still store it as given. - C. Uprate a multi-period source from the start of its last own-unit sub-period, and treat an own-unit input that starts at the requested period as a source (
<=, the auto-carry-over rule). This fixes items 2 and 3. Within a covered span the factor is then 1, which is what auto-carry-over gives. - D. Reject multi-period inputs for helper-less variables (a
PeriodMismatchErrorin_set). Combined with B, no multi-period own-unit key is ever stored, and items 1–4 cannot arise. This breaks code that reads such inputs back by their own period: #562'syear_input_without_helpertests do, throughcalculate_add(…, "year:2012:2"). - E. Key storage by the period itself (or a canonical form that keeps the unit and size), not by
str(period). This fixes item 5 whatever is chosen above.
Recommendation: B + C + E. They keep every stored input readable, match what the helper is for, make uprating agree with auto-carry-over within a covered span, and stop one period being stored as another. Because no country package stores such inputs today, results do not change.
🤖 Generated with Claude Code
- Dominant language
- Python
- Stars
- 22
- Forks
- 30
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 22
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from PolicyEngine/policyengine-core
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
PolicyEngine/policyengine-core#549 ·
Maintainers usually reply within 1 day
-
`restore_simulation` silently drops memberless group entitiesPossibly taken @Adelagric claimed this 30 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
PolicyEngine/policyengine-core#547 ·
Maintainers usually reply within 1 day
-
Remove transitional cache access after country migrationsMay be free again A pull request for this issue was closed without being merged. Open
Difficulty 5/5 Over a week Newbie friendliness 35/100
PolicyEngine/policyengine-core#602 ·
Maintainers usually reply within 1 day
-
Define explicit cache ownership contracts through Phase 6May be free again A pull request for this issue was closed without being merged. Open
Difficulty 5/5 Over a week Newbie friendliness 25/100
PolicyEngine/policyengine-core#598 ·
Maintainers usually reply within 1 day
-
set_input for one period leaves the variable's cached sum or twelfth over an overlapping period in placePossibly taken @MaxGhenis claimed this 4 days ago. Open
Difficulty 4/5 3-5 days Newbie friendliness 68/100
PolicyEngine/policyengine-core#579 ·
Maintainers usually reply within 1 day
All issues in PolicyEngine/policyengine-core
Similar issues
-
enhancement good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
python-version
Difficulty 1/5 Under an hour Newbie friendliness 88/100
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
Maintainers usually reply within 1 day
-
bug javascript P2-medium python release:v3.1
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
adrirubio/claude-deck#546 ·
Maintainers usually reply within 1 day
-
area: desktop area: website priority: P2 type: feature
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
appandflow/stim#3411 · 1 comment ·
Maintainers usually reply within 1 day