Repository navigation
Multi-period inputs in a variable's own unit: helper skipped, uprating base, storage aliasing #583
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 Break equal-start uprating ties the way auto-carry-over does #582 fixes that one: it takes the one that ends last, the same order auto-carry-over uses (Carry over only inputs, the latest at or before the requested period #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 (Break equal-start uprating ties the way auto-carry-over does #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: Carry over only inputs, the latest at or before the requested 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
Activity