Skip to content

Commit 32cbac6

Browse files
authored
Merge pull request #1548 from PolicyEngine/codex/fix-state-pension-reforms
Fix state pension reforms having no budget impact
2 parents 7318448 + 75c698e commit 32cbac6

File tree

3 files changed

+59
-23
lines changed

3 files changed

+59
-23
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""Test state pension parameter reforms affect microsimulation outputs."""
2+
3+
import pytest
4+
5+
from policyengine_uk import Microsimulation
6+
7+
YEAR = 2025
8+
9+
10+
@pytest.fixture(scope="module")
11+
def baseline():
12+
return Microsimulation()
13+
14+
15+
@pytest.fixture(scope="module")
16+
def reform_halved():
17+
return Microsimulation(
18+
reform={
19+
"gov.dwp.state_pension.basic_state_pension.amount": {
20+
"2025-01-01": 84.75,
21+
}
22+
}
23+
)
24+
25+
26+
@pytest.mark.microsimulation
27+
def test_basic_state_pension_responds_to_reform(baseline, reform_halved):
28+
baseline_total = baseline.calculate("basic_state_pension", YEAR).sum()
29+
reform_total = reform_halved.calculate("basic_state_pension", YEAR).sum()
30+
31+
assert baseline_total > 0
32+
assert reform_total < baseline_total * 0.9

policyengine_uk/variables/gov/dwp/additional_state_pension.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,17 @@ def formula(person, period, parameters):
1818
data_year = period.start.year
1919
reported = person("state_pension_reported", data_year) / WEEKS_IN_YEAR
2020
type = person("state_pension_type", data_year)
21-
maximum_basic_sp = parameters(
22-
data_year
23-
).gov.dwp.state_pension.basic_state_pension.amount
21+
sp_amount = parameters.gov.dwp.state_pension.basic_state_pension.amount
22+
max_sp_data_year = sp_amount(data_year)
23+
max_sp_period = sp_amount(period)
2424
amount_in_data_year = where(
2525
type == type.possible_values.BASIC,
26-
max_(reported - maximum_basic_sp, 0),
26+
max_(reported - max_sp_data_year, 0),
2727
0,
2828
)
29-
return amount_in_data_year * WEEKS_IN_YEAR
29+
uprating = where(
30+
max_sp_data_year > 0,
31+
max_sp_period / max_sp_data_year,
32+
1,
33+
)
34+
return amount_in_data_year * uprating * WEEKS_IN_YEAR

policyengine_uk/variables/gov/dwp/basic_state_pension.py

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,23 +23,22 @@ def formula(person, period, parameters):
2323

2424
reported = person("state_pension_reported", data_year) / WEEKS_IN_YEAR
2525
pension_type = person("state_pension_type", period)
26-
maximum_basic_sp = parameters(
27-
data_year
28-
).gov.dwp.state_pension.basic_state_pension.amount
29-
30-
# For BASIC pension type, cap at the maximum; otherwise return 0
31-
amount_in_data_year = where(
32-
pension_type == pension_type.possible_values.BASIC,
33-
min_(reported, maximum_basic_sp),
26+
sp_amount = parameters.gov.dwp.state_pension.basic_state_pension.amount
27+
max_sp_data_year = sp_amount(data_year)
28+
max_sp_period = sp_amount(period)
29+
30+
# Compute the person's share of the data-year maximum so reforms can
31+
# scale the current-period amount while preserving the original cap.
32+
share = where(
33+
max_sp_data_year > 0,
34+
min_(reported, max_sp_data_year) / max_sp_data_year,
3435
0,
3536
)
36-
37-
# Apply triple lock uprating only when using dataset
38-
# (i.e., when data year differs from simulation period)
39-
if has_dataset:
40-
triple_lock = parameters.gov.economic_assumptions.indices.triple_lock
41-
uprating = triple_lock(period) / triple_lock(data_year)
42-
else:
43-
uprating = 1
44-
45-
return amount_in_data_year * uprating * WEEKS_IN_YEAR
37+
return (
38+
where(
39+
pension_type == pension_type.possible_values.BASIC,
40+
share * max_sp_period,
41+
0,
42+
)
43+
* WEEKS_IN_YEAR
44+
)

0 commit comments

Comments
 (0)