Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/fix-backdate-before-reforms.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Reforms to a parameter first dated after 2015 no longer change years outside the reform's period. Parameters are now backdated to 2015 before the reform is applied (and parameters a reform adds or replaces are backdated afterwards, as before), so a reform starting on or before a parameter's first dated value is no longer copied back to 2015, and a reform ending before that value no longer leaves the years in between undefined, which dropped brackets from scales and made formulas reading the parameter raise ParameterNotFoundError. CountryTaxBenefitSystem and Simulation(reform=...) also now build with any start_instant from 2015 through 2023; they raised ParameterNotFoundError because structural-reform detection read contrib parameters first dated after the start before they were backdated.
21 changes: 17 additions & 4 deletions policyengine_us/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,16 @@ def __init__(
self.parameters = propagate_parameter_metadata(self.parameters)
add_default_uprating(self)

# Backdated before any reform is applied. Backdating copies each
# parameter's earliest value back to the start of FIRST_MODELED_YEAR,
# so on a parameter first dated after that it would copy a reform
# value that starts on or before that first date back to that year,
# and a reform ending before that date would leave the years between
# the two undefined.
self.parameters = backdate_parameters(
self.parameters, first_instant=f"{FIRST_MODELED_YEAR}-01-01"
)

if reform:
# Applied after the parameter processing pipeline so that values
# a reform inserts at future dates cannot act as defined values
Expand All @@ -134,6 +144,13 @@ def __init__(
# structural-reform detection, which reads reformed parameter
# values.
self.apply_reform_set(reform)
# Backdates parameters the reform added or replaced, as before.
# Those it only updated already have a value dated by the start of
# FIRST_MODELED_YEAR, and ``Parameter.update`` never removes
# values dated before the period it sets, so they keep it.
self.parameters = backdate_parameters(
self.parameters, first_instant=f"{FIRST_MODELED_YEAR}-01-01"
)

structural_reform = create_structural_reforms_from_parameters(
self.parameters, start_instant
Expand All @@ -142,10 +159,6 @@ def __init__(
reform = ()
reform = (reform, structural_reform)

self.parameters = backdate_parameters(
self.parameters, first_instant=f"{FIRST_MODELED_YEAR}-01-01"
)

for parameter in self.parameters.get_descendants():
parameter.modified = False

Expand Down
Loading
Loading