Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Multi-period inputs in a variable's own unit: helper skipped, uprating base, storage aliasing

Open
#583 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
52/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
python
Domain
backend

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):

  1. The helper is skipped. uprated (helper set_input_divide_by_period) given year:2012:2 = 100 stores year:2012:2, not 2012 and 2013 at 50 each. carried (no uprating, same helper) given the same input carries 100 into 2013 and 2014.
  2. Uprating within the covered span. uprated_any_unit given only year:2012:2 = 1 returns 1.037 for 2013, a year the input covers. The uprating factor runs from the source's start (2012), not from the last year it covers.
  3. An input starting on the requested period is not an uprating source. Uprating takes only inputs that start before the period. Given 2011 = 1 and year:2012:2 = 5, 2012 gets 2011's input uprated (1.037), not 5. Auto-carry-over would carry 5. Given only year:2012:2 = 5, 2012 gets 5 with auto-carry-over and the default (0) without it, while 2013 gets 5 × 1.037 either way.
  4. Ties between inputs that start on the same day (2012 and year: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).
  5. 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_monthly given month:2012-01:12 = 7 stores Period(('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 PeriodMismatchError in _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's year_input_without_helper tests do, through calculate_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

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from PolicyEngine/policyengine-core

All issues in PolicyEngine/policyengine-core

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.