diff --git a/changelog_entry.yaml b/changelog_entry.yaml index e69de29bb2d..08481968cd9 100644 --- a/changelog_entry.yaml +++ b/changelog_entry.yaml @@ -0,0 +1,4 @@ +- bump: minor + changes: + added: + - Add five-year-forward check on all reforms diff --git a/policyengine_us/reforms/biden/budget_2025/capital_gains_tax_increase.py b/policyengine_us/reforms/biden/budget_2025/capital_gains_tax_increase.py index 8ec22746075..b8ab179e1e6 100644 --- a/policyengine_us/reforms/biden/budget_2025/capital_gains_tax_increase.py +++ b/policyengine_us/reforms/biden/budget_2025/capital_gains_tax_increase.py @@ -1,4 +1,5 @@ from policyengine_us.model_api import * +from policyengine_core.periods import period as period_ def create_capital_gains_tax_increase() -> Reform: @@ -145,8 +146,16 @@ def create_capital_gains_tax_increase_reform( return create_capital_gains_tax_increase() p = parameters(period).gov.contrib.biden.budget_2025.capital_gains + current_period = period_(period) + reform_active = False - if p.active: + for i in range(5): + if p(current_period).active: + reform_active = True + break + current_period = current_period.offset(1, "year") + + if reform_active: return create_capital_gains_tax_increase() else: return None diff --git a/policyengine_us/reforms/biden/budget_2025/medicare_and_investment_tax_increase.py b/policyengine_us/reforms/biden/budget_2025/medicare_and_investment_tax_increase.py index ba3c848c77e..3575686bb79 100644 --- a/policyengine_us/reforms/biden/budget_2025/medicare_and_investment_tax_increase.py +++ b/policyengine_us/reforms/biden/budget_2025/medicare_and_investment_tax_increase.py @@ -1,4 +1,5 @@ from policyengine_us.model_api import * +from policyengine_core.periods import period as period_ def create_medicare_and_investment_tax_increase() -> Reform: @@ -75,8 +76,19 @@ def create_medicare_and_investment_tax_increase_reform( return create_medicare_and_investment_tax_increase() p = parameters(period).gov.contrib.biden.budget_2025 + current_period = period_(period) + reform_active = False - if (p.medicare.rate > 0) | (p.net_investment_income.rate > 0): + for i in range(5): + if ( + p(current_period).medicare.rate > 0 + or p(current_period).net_investment_income.rate > 0 + ): + reform_active = True + break + current_period = current_period.offset(1, "year") + + if reform_active: return create_medicare_and_investment_tax_increase() else: return None diff --git a/policyengine_us/reforms/cbo/payroll/increase_taxable_earnings_for_social_security.py b/policyengine_us/reforms/cbo/payroll/increase_taxable_earnings_for_social_security.py index 1199cf18dbe..817f680e89c 100644 --- a/policyengine_us/reforms/cbo/payroll/increase_taxable_earnings_for_social_security.py +++ b/policyengine_us/reforms/cbo/payroll/increase_taxable_earnings_for_social_security.py @@ -1,4 +1,5 @@ from policyengine_us.model_api import * +from policyengine_core.periods import period as period_ def create_increase_taxable_earnings_for_social_security() -> Reform: @@ -33,8 +34,16 @@ def create_increase_taxable_earnings_for_social_security_reform( return create_increase_taxable_earnings_for_social_security() p = parameters(period).gov.contrib.cbo.payroll + current_period = period_(period) + reform_active = False - if p.secondary_earnings_threshold < np.inf: + for i in range(5): + if p(current_period).secondary_earnings_threshold < np.inf: + reform_active = True + break + current_period = current_period.offset(1, "year") + + if reform_active: return create_increase_taxable_earnings_for_social_security() else: return None diff --git a/policyengine_us/reforms/congress/tlaib/boost/boost_middle_class_tax_credit.py b/policyengine_us/reforms/congress/tlaib/boost/boost_middle_class_tax_credit.py index 57a2d87df04..b1342e1dd62 100644 --- a/policyengine_us/reforms/congress/tlaib/boost/boost_middle_class_tax_credit.py +++ b/policyengine_us/reforms/congress/tlaib/boost/boost_middle_class_tax_credit.py @@ -1,4 +1,5 @@ from policyengine_us.model_api import * +from policyengine_core.periods import period as period_ def create_boost_middle_class_tax_credit() -> Reform: @@ -147,8 +148,16 @@ def create_boost_middle_class_tax_credit_reform( return create_boost_middle_class_tax_credit() p = parameters(period).gov.contrib.harris.lift.middle_class_tax_credit + current_period = period_(period) + reform_active = False - if p.in_effect: + for i in range(5): + if p(current_period).in_effect: + reform_active = True + break + current_period = current_period.offset(1, "year") + + if reform_active: return create_boost_middle_class_tax_credit() else: return None diff --git a/policyengine_us/reforms/congress/tlaib/end_child_poverty_act.py b/policyengine_us/reforms/congress/tlaib/end_child_poverty_act.py index e85f226b509..5c5382fd679 100644 --- a/policyengine_us/reforms/congress/tlaib/end_child_poverty_act.py +++ b/policyengine_us/reforms/congress/tlaib/end_child_poverty_act.py @@ -1,4 +1,5 @@ from policyengine_us.model_api import * +from policyengine_core.periods import period as period_ def create_end_child_poverty_act() -> Reform: @@ -180,8 +181,16 @@ def create_end_child_poverty_act_reform( return create_end_child_poverty_act() p = parameters(period).gov.contrib.congress.tlaib.end_child_poverty_act + current_period = period_(period) + reform_active = False - if p.in_effect: + for i in range(5): + if p(current_period).in_effect: + reform_active = True + break + current_period = current_period.offset(1, "year") + + if reform_active: return create_end_child_poverty_act() else: return None diff --git a/policyengine_us/reforms/dc_kccatc.py b/policyengine_us/reforms/dc_kccatc.py index 0bf5ee9d66e..e778dff480a 100644 --- a/policyengine_us/reforms/dc_kccatc.py +++ b/policyengine_us/reforms/dc_kccatc.py @@ -1,7 +1,8 @@ from policyengine_us.model_api import * +from policyengine_core.periods import period as period_ -def create_dc_kccatc_reform(parameters, period, bypass=False): +def create_dc_kccatc(): class dc_kccatc(Variable): value_type = float entity = TaxUnit @@ -87,8 +88,24 @@ class reform(Reform): def apply(self): self.update_variable(dc_kccatc) - if bypass or parameters(period).gov.contrib.dc_kccatc.active: - return reform + return reform + + +def create_dc_kccatc_reform(parameters, period, bypass=False): + if bypass: + return create_dc_kccatc() + + p = parameters(period).gov.contrib.dc_kccatc + current_period = period_(period) + + for i in range(5): + if p(current_period).active: + reform_active = True + break + current_period = current_period.offset(1, "year") + + if reform_active: + return create_dc_kccatc() else: return None diff --git a/policyengine_us/reforms/eitc/halve_joint_eitc_phase_out_rate.py b/policyengine_us/reforms/eitc/halve_joint_eitc_phase_out_rate.py index ac94bae72dc..715bf4e0582 100644 --- a/policyengine_us/reforms/eitc/halve_joint_eitc_phase_out_rate.py +++ b/policyengine_us/reforms/eitc/halve_joint_eitc_phase_out_rate.py @@ -1,4 +1,5 @@ from policyengine_us.model_api import * +from policyengine_core.periods import period as period_ def create_halve_joint_eitc_phase_out_rate() -> Reform: @@ -32,8 +33,16 @@ def create_halve_joint_eitc_phase_out_rate_reform( return create_halve_joint_eitc_phase_out_rate() p = parameters(period).gov.contrib.joint_eitc + current_period = period_(period) + reform_active = False - if p.in_effect: + for i in range(5): + if p(current_period).in_effect: + reform_active = True + break + current_period = current_period.offset(1, "year") + + if reform_active: return create_halve_joint_eitc_phase_out_rate() else: return None diff --git a/policyengine_us/reforms/federal/abolish_federal_income_tax.py b/policyengine_us/reforms/federal/abolish_federal_income_tax.py index 71517463770..72a1d78114a 100644 --- a/policyengine_us/reforms/federal/abolish_federal_income_tax.py +++ b/policyengine_us/reforms/federal/abolish_federal_income_tax.py @@ -1,4 +1,5 @@ from policyengine_us.model_api import * +from policyengine_core.periods import period as period_ def create_abolish_federal_income_tax() -> Reform: @@ -54,8 +55,15 @@ def create_abolish_federal_income_tax_reform( return create_abolish_federal_income_tax() p = parameters(period).gov.contrib.ubi_center.flat_tax + current_period = period_(period) - if p.abolish_federal_income_tax: + for i in range(5): + if p(current_period).abolish_federal_income_tax: + reform_active = True + break + current_period = current_period.offset(1, "year") + + if reform_active: return create_abolish_federal_income_tax() else: return None diff --git a/policyengine_us/reforms/federal/abolish_payroll_tax.py b/policyengine_us/reforms/federal/abolish_payroll_tax.py index d6192b47671..3dd2b550430 100644 --- a/policyengine_us/reforms/federal/abolish_payroll_tax.py +++ b/policyengine_us/reforms/federal/abolish_payroll_tax.py @@ -1,4 +1,5 @@ from policyengine_us.model_api import * +from policyengine_core.periods import period as period_ def create_abolish_payroll_tax() -> Reform: @@ -34,8 +35,15 @@ def create_abolish_payroll_tax_reform( return create_abolish_payroll_tax() p = parameters(period).gov.contrib.ubi_center.flat_tax + current_period = period_(period) - if p.abolish_payroll_tax: + for i in range(5): + if p(current_period).abolish_payroll_tax: + reform_active = True + break + current_period = current_period.offset(1, "year") + + if reform_active: return create_abolish_payroll_tax() else: return None diff --git a/policyengine_us/reforms/federal/reported_state_income_tax.py b/policyengine_us/reforms/federal/reported_state_income_tax.py index 5f6b90294fc..fa328f22210 100644 --- a/policyengine_us/reforms/federal/reported_state_income_tax.py +++ b/policyengine_us/reforms/federal/reported_state_income_tax.py @@ -61,8 +61,15 @@ def create_reported_state_income_tax_reform( return create_reported_state_income_tax() p = parameters(period).simulation + current_period = period_(period) - if p.reported_state_income_tax: + for i in range(5): + if p(current_period).reported_state_income_tax: + reform_active = True + break + current_period = current_period.offset(1, "year") + + if reform_active: return create_reported_state_income_tax() else: return None diff --git a/policyengine_us/reforms/harris/lift/middle_class_tax_credit.py b/policyengine_us/reforms/harris/lift/middle_class_tax_credit.py index a438321d9ef..3b930010d2c 100644 --- a/policyengine_us/reforms/harris/lift/middle_class_tax_credit.py +++ b/policyengine_us/reforms/harris/lift/middle_class_tax_credit.py @@ -1,4 +1,5 @@ from policyengine_us.model_api import * +from policyengine_core.periods import period as period_ def create_middle_class_tax_credit() -> Reform: @@ -61,8 +62,15 @@ def create_middle_class_tax_credit_reform( return create_middle_class_tax_credit() p = parameters(period).gov.contrib.harris.lift.middle_class_tax_credit + current_period = period_(period) - if p.in_effect: + for i in range(5): + if p(current_period).in_effect: + reform_active = True + break + current_period = current_period.offset(1, "year") + + if reform_active: return create_middle_class_tax_credit() else: return None diff --git a/policyengine_us/reforms/harris/rent_relief_act/rent_relief_tax_credit.py b/policyengine_us/reforms/harris/rent_relief_act/rent_relief_tax_credit.py index a3db48068a7..3d7fdf19193 100644 --- a/policyengine_us/reforms/harris/rent_relief_act/rent_relief_tax_credit.py +++ b/policyengine_us/reforms/harris/rent_relief_act/rent_relief_tax_credit.py @@ -1,4 +1,5 @@ from policyengine_us.model_api import * +from policyengine_core.periods import period as period_ def create_rent_relief_tax_credit() -> Reform: @@ -83,8 +84,15 @@ def create_rent_relief_tax_credit_reform( p = parameters( period ).gov.contrib.harris.rent_relief_act.rent_relief_credit + current_period = period_(period) - if p.in_effect: + for i in range(5): + if p(current_period).in_effect: + reform_active = True + break + current_period = current_period.offset(1, "year") + + if reform_active: return create_rent_relief_tax_credit() else: return None diff --git a/policyengine_us/reforms/local/nyc/stc/adjust_income_limit_by_filing_status_and_eligibility_by_children.py b/policyengine_us/reforms/local/nyc/stc/adjust_income_limit_by_filing_status_and_eligibility_by_children.py index 46cd0d13ae4..35b4c61c82a 100644 --- a/policyengine_us/reforms/local/nyc/stc/adjust_income_limit_by_filing_status_and_eligibility_by_children.py +++ b/policyengine_us/reforms/local/nyc/stc/adjust_income_limit_by_filing_status_and_eligibility_by_children.py @@ -1,4 +1,5 @@ from policyengine_us.model_api import * +from policyengine_core.periods import period as period_ def create_adjust_income_limit_and_min_children_by_filing_status() -> Reform: @@ -55,8 +56,17 @@ def create_adjust_income_limit_by_filing_status_and_eligibility_by_children_refo return create_adjust_income_limit_and_min_children_by_filing_status() p = parameters(period).gov.contrib.local.nyc.stc + current_period = period_(period) - if p.adjust_income_limit_by_filing_status_and_eligibility_by_children: + for i in range(5): + if p( + current_period + ).adjust_income_limit_by_filing_status_and_eligibility_by_children: + reform_active = True + break + current_period = current_period.offset(1, "year") + + if reform_active: return create_adjust_income_limit_and_min_children_by_filing_status() else: return None diff --git a/policyengine_us/reforms/states/dc/dc_ctc.py b/policyengine_us/reforms/states/dc/dc_ctc.py index d49d37a2363..0ffe128057a 100644 --- a/policyengine_us/reforms/states/dc/dc_ctc.py +++ b/policyengine_us/reforms/states/dc/dc_ctc.py @@ -61,14 +61,19 @@ def create_dc_ctc_reform(parameters, period, bypass: bool = False): return create_dc_ctc() p = parameters.gov.contrib.states.dc.ctc - current_period = period_(period) + reform_active = False for i in range(5): if p(current_period).in_effect: - return create_dc_ctc() + reform_active = True + break current_period = current_period.offset(1, "year") - return None + + if reform_active: + return create_dc_ctc() + else: + return None dc_ctc = create_dc_ctc_reform(None, None, bypass=True) diff --git a/policyengine_us/reforms/states/mn/walz/mn_walz_hf1938.py b/policyengine_us/reforms/states/mn/walz/mn_walz_hf1938.py index 16f729546dd..c9fbaba0379 100644 --- a/policyengine_us/reforms/states/mn/walz/mn_walz_hf1938.py +++ b/policyengine_us/reforms/states/mn/walz/mn_walz_hf1938.py @@ -1,4 +1,5 @@ from policyengine_us.model_api import * +from policyengine_core.periods import period as period_ # Repealing Minnesota Bill HF1938 to pre 2023 rules @@ -212,8 +213,16 @@ def create_mn_walz_hf1938_repeal_reform( return create_mn_walz_hf1938_repeal() p = parameters(period).gov.contrib.states.mn.walz.hf1938 + reform_active = False + current_period = period_(period) - if p.repeal: + for i in range(5): + if p(current_period).repeal: + reform_active = True + break + current_period = current_period.offset(1, "year") + + if reform_active: return create_mn_walz_hf1938_repeal() else: return None diff --git a/policyengine_us/reforms/states/ny/wftc/ny_working_families_tax_credit.py b/policyengine_us/reforms/states/ny/wftc/ny_working_families_tax_credit.py index aa879a39906..481e99b93b5 100644 --- a/policyengine_us/reforms/states/ny/wftc/ny_working_families_tax_credit.py +++ b/policyengine_us/reforms/states/ny/wftc/ny_working_families_tax_credit.py @@ -1,4 +1,5 @@ from policyengine_us.model_api import * +from policyengine_core.periods import period as period_ def create_ny_working_families_tax_credit() -> Reform: @@ -530,8 +531,16 @@ def create_ny_working_families_tax_credit_reform( return create_ny_working_families_tax_credit() p = parameters(period).gov.contrib.states.ny.wftc + reform_active = False + current_period = period_(period) - if p.in_effect: + for i in range(5): + if p(current_period).in_effect: + reform_active = True + break + current_period = current_period.offset(1, "year") + + if reform_active: return create_ny_working_families_tax_credit() else: return None diff --git a/policyengine_us/reforms/states/oregon/rebate/or_rebate_state_tax_exempt.py b/policyengine_us/reforms/states/oregon/rebate/or_rebate_state_tax_exempt.py index 6752deaafb3..2c14894af94 100644 --- a/policyengine_us/reforms/states/oregon/rebate/or_rebate_state_tax_exempt.py +++ b/policyengine_us/reforms/states/oregon/rebate/or_rebate_state_tax_exempt.py @@ -1,4 +1,5 @@ from policyengine_us.model_api import * +from policyengine_core.periods import period as period_ def create_or_rebate_state_tax_exempt() -> Reform: @@ -49,8 +50,16 @@ def create_or_rebate_state_tax_exempt_reform( return create_or_rebate_state_tax_exempt() p = parameters(period).gov.contrib.states["or"].rebate + reform_active = False + current_period = period_(period) - if p.state_tax_exempt: + for i in range(5): + if p(current_period).state_tax_exempt: + reform_active = True + break + current_period = current_period.offset(1, "year") + + if reform_active: return create_or_rebate_state_tax_exempt() else: return None