taxcalc 4.2.2__py3-none-any.whl → 4.3.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- taxcalc/__init__.py +3 -1
- taxcalc/calcfunctions.py +4 -12
- taxcalc/cli/tc.py +26 -10
- taxcalc/data.py +13 -5
- taxcalc/policy.py +1 -1
- taxcalc/policy_current_law.json +2714 -228
- taxcalc/records.py +32 -18
- taxcalc/reforms/ext.json +20 -20
- taxcalc/taxcalcio.py +61 -28
- taxcalc/tests/cpscsv_agg_expect.csv +18 -18
- taxcalc/tests/puf_var_wght_means_by_year.csv +5 -5
- taxcalc/tests/pufcsv_agg_expect.csv +19 -19
- taxcalc/tests/test_benefits.py +3 -3
- taxcalc/tests/test_calcfunctions.py +4 -5
- taxcalc/tests/test_calculator.py +1 -36
- taxcalc/tests/test_policy.py +460 -478
- taxcalc/tests/test_reforms.py +16 -15
- {taxcalc-4.2.2.dist-info → taxcalc-4.3.1.dist-info}/METADATA +1 -1
- {taxcalc-4.2.2.dist-info → taxcalc-4.3.1.dist-info}/RECORD +23 -28
- {taxcalc-4.2.2.dist-info → taxcalc-4.3.1.dist-info}/WHEEL +1 -1
- taxcalc/reforms/rounding2022.json +0 -153
- taxcalc/reforms/rounding2022.out.csv +0 -10
- taxcalc/tests/test_tmdcsv.py +0 -38
- taxcalc/tmd_growfactors.csv +0 -55
- taxcalc/tmd_weights.csv.gz +0 -0
- {taxcalc-4.2.2.dist-info → taxcalc-4.3.1.dist-info}/LICENSE +0 -0
- {taxcalc-4.2.2.dist-info → taxcalc-4.3.1.dist-info}/entry_points.txt +0 -0
- {taxcalc-4.2.2.dist-info → taxcalc-4.3.1.dist-info}/top_level.txt +0 -0
taxcalc/tests/test_policy.py
CHANGED
@@ -43,7 +43,7 @@ def test_incorrect_class_instantiation():
|
|
43
43
|
Test incorrect instantiation of Policy class object.
|
44
44
|
"""
|
45
45
|
with pytest.raises(ValueError):
|
46
|
-
Policy(gfactors=
|
46
|
+
Policy(gfactors=[])
|
47
47
|
|
48
48
|
|
49
49
|
def test_correct_class_instantiation():
|
@@ -54,7 +54,7 @@ def test_correct_class_instantiation():
|
|
54
54
|
assert pol
|
55
55
|
pol.implement_reform({})
|
56
56
|
with pytest.raises(pt.ValidationError):
|
57
|
-
pol.implement_reform(
|
57
|
+
pol.implement_reform([])
|
58
58
|
with pytest.raises(pt.ValidationError):
|
59
59
|
pol.implement_reform({2099: {'II_em': 99000}})
|
60
60
|
pol.set_year(2019)
|
@@ -621,7 +621,7 @@ def test_section_titles(tests_path):
|
|
621
621
|
structured like the VALID_SECTION dictionary (see below) and
|
622
622
|
extracted from the specified html_text.
|
623
623
|
"""
|
624
|
-
sdict =
|
624
|
+
sdict = {}
|
625
625
|
for line in md_text.splitlines():
|
626
626
|
# This is shown as an empty case in current law policy and
|
627
627
|
# validation.
|
@@ -647,7 +647,6 @@ def test_section_titles(tests_path):
|
|
647
647
|
'As A Percent Of Deductible Expenses')
|
648
648
|
cgqd_tax_same = ('Tax All Capital Gains And Dividends The Same '
|
649
649
|
'As Regular Taxable Income')
|
650
|
-
# pylint: disable=bad-continuation
|
651
650
|
valid_dict = {
|
652
651
|
'': { # empty section_1 implies parameter not displayed in Tax-Brain
|
653
652
|
'': 0
|
@@ -737,11 +736,11 @@ def test_section_titles(tests_path):
|
|
737
736
|
}
|
738
737
|
# check validity of parameter section titles in policy_current_law.json
|
739
738
|
path = os.path.join(tests_path, '..', 'policy_current_law.json')
|
740
|
-
with open(path, 'r') as clpfile:
|
739
|
+
with open(path, 'r', encoding='utf-8') as clpfile:
|
741
740
|
clpdict = json.load(clpfile)
|
742
741
|
clpdict.pop("schema", None)
|
743
742
|
# ... make sure ever clpdict section title is in valid_dict
|
744
|
-
clp_dict =
|
743
|
+
clp_dict = {} # dictionary of clp section titles structured like valid
|
745
744
|
for pname in clpdict:
|
746
745
|
param = clpdict[pname]
|
747
746
|
assert isinstance(param, dict)
|
@@ -754,28 +753,28 @@ def test_section_titles(tests_path):
|
|
754
753
|
if sec2title not in clp_dict[sec1title]:
|
755
754
|
clp_dict[sec1title][sec2title] = 0
|
756
755
|
# ... make sure every valid_dict section title is in clpdict
|
757
|
-
for sec1title in valid_dict:
|
758
|
-
assert isinstance(
|
756
|
+
for sec1title, secdict in valid_dict.items():
|
757
|
+
assert isinstance(secdict, dict)
|
759
758
|
assert sec1title in clp_dict
|
760
|
-
for sec2title in
|
759
|
+
for sec2title in secdict:
|
761
760
|
assert sec2title in clp_dict[sec1title]
|
762
761
|
# check validity of parameter section titles in docs/uguide.htmx skeleton
|
763
762
|
path = os.path.join(tests_path, '..', '..', 'docs', 'guide',
|
764
763
|
'policy_params.md')
|
765
|
-
with open(path, 'r') as md_file:
|
764
|
+
with open(path, 'r', encoding='utf-8') as md_file:
|
766
765
|
md_text = md_file.read()
|
767
766
|
md_dict = generate_section_dictionary(md_text)
|
768
767
|
# ... make sure every md_dict section title is in valid_dict
|
769
|
-
for sec1title in md_dict:
|
770
|
-
assert isinstance(
|
768
|
+
for sec1title,secdict in md_dict.items():
|
769
|
+
assert isinstance(secdict, dict)
|
771
770
|
assert sec1title in valid_dict
|
772
|
-
for sec2title in
|
771
|
+
for sec2title in secdict:
|
773
772
|
assert sec2title in valid_dict[sec1title]
|
774
773
|
# ... make sure every valid_dict section title is in md_dict
|
775
|
-
for sec1title in valid_dict:
|
776
|
-
assert isinstance(
|
774
|
+
for sec1title, secdict in valid_dict.items():
|
775
|
+
assert isinstance(secdict, dict)
|
777
776
|
assert sec1title in md_dict
|
778
|
-
for sec2title in
|
777
|
+
for sec2title in secdict:
|
779
778
|
assert sec2title in md_dict[sec1title]
|
780
779
|
|
781
780
|
|
@@ -785,7 +784,7 @@ def test_description_punctuation(tests_path):
|
|
785
784
|
"""
|
786
785
|
# read JSON file into a dictionary
|
787
786
|
path = os.path.join(tests_path, '..', 'policy_current_law.json')
|
788
|
-
with open(path, 'r') as jsonfile:
|
787
|
+
with open(path, 'r', encoding='utf-8') as jsonfile:
|
789
788
|
dct = json.load(jsonfile)
|
790
789
|
dct.pop("schema", None)
|
791
790
|
all_desc_ok = True
|
@@ -931,8 +930,8 @@ def test_index_offset_reform():
|
|
931
930
|
policy2 = Policy()
|
932
931
|
policy2.implement_reform(reform2) # caused T-C crash before PR#2364
|
933
932
|
# extract from policy1 and policy2 the parameter values of CTC_c
|
934
|
-
pvalue1 =
|
935
|
-
pvalue2 =
|
933
|
+
pvalue1 = {}
|
934
|
+
pvalue2 = {}
|
936
935
|
for cyr in [2019, 2020, 2021]:
|
937
936
|
policy1.set_year(cyr)
|
938
937
|
pvalue1[cyr] = policy1.CTC_c[0]
|
@@ -945,8 +944,7 @@ def test_index_offset_reform():
|
|
945
944
|
# ... indexing of CTC_c begins shows up first in 2021 parameter values
|
946
945
|
assert pvalue1[2021] > pvalue1[2020]
|
947
946
|
assert pvalue2[2021] > pvalue2[2020]
|
948
|
-
# ... calculate expected pvalue2[2021] from
|
949
|
-
indexrate1 = pvalue1[2021] / pvalue1[2020] - 1.
|
947
|
+
# ... calculate expected pvalue2[2021] from inflation rates and offset
|
950
948
|
syear = Policy.JSON_START_YEAR
|
951
949
|
expindexrate = cpiu_rates[2020 - syear] + offset
|
952
950
|
expvalue = round(pvalue2[2020] * (1. + expindexrate), 2)
|
@@ -1032,525 +1030,509 @@ def test_raise_errors_regression():
|
|
1032
1030
|
assert pol.errors
|
1033
1031
|
|
1034
1032
|
|
1035
|
-
|
1033
|
+
def test_simple_adj():
|
1036
1034
|
"""
|
1037
|
-
Test
|
1038
|
-
|
1039
|
-
Each test implements a Tax-Calculator style reform and a pt styled
|
1040
|
-
reform, checks that the updated values are equal, and then, tests that
|
1041
|
-
values were extended and indexed (or not indexed) correctly.
|
1035
|
+
Test updating a 2D parameter that is indexed to inflation.
|
1042
1036
|
"""
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1049
|
-
pol1.implement_reform(
|
1050
|
-
{
|
1051
|
-
"EITC_c": {
|
1052
|
-
2020: [10000, 10001, 10002, 10003],
|
1053
|
-
2023: [20000, 20001, 20002, 20003],
|
1054
|
-
}
|
1055
|
-
}
|
1056
|
-
)
|
1057
|
-
|
1058
|
-
pol2 = Policy()
|
1059
|
-
pol2.adjust(
|
1060
|
-
{
|
1061
|
-
"EITC_c": [
|
1062
|
-
{"year": 2020, "EIC": "0kids", "value": 10000},
|
1063
|
-
{"year": 2020, "EIC": "1kid", "value": 10001},
|
1064
|
-
{"year": 2020, "EIC": "2kids", "value": 10002},
|
1065
|
-
{"year": 2020, "EIC": "3+kids", "value": 10003},
|
1066
|
-
{"year": 2023, "EIC": "0kids", "value": 20000},
|
1067
|
-
{"year": 2023, "EIC": "1kid", "value": 20001},
|
1068
|
-
{"year": 2023, "EIC": "2kids", "value": 20002},
|
1069
|
-
{"year": 2023, "EIC": "3+kids", "value": 20003},
|
1070
|
-
]
|
1071
|
-
}
|
1072
|
-
)
|
1073
|
-
cmp_policy_objs(pol1, pol2)
|
1074
|
-
|
1075
|
-
pol0 = Policy()
|
1076
|
-
pol0.set_year(2019)
|
1077
|
-
pol2.set_year(2019)
|
1078
|
-
|
1079
|
-
assert np.allclose(pol0.EITC_c, pol2.EITC_c)
|
1080
|
-
|
1081
|
-
pol2.set_state(year=[2020, 2021, 2022, 2023, 2024])
|
1082
|
-
val2020 = np.array([[10000, 10001, 10002, 10003]])
|
1083
|
-
val2023 = np.array([[20000, 20001, 20002, 20003]])
|
1084
|
-
|
1085
|
-
exp = np.vstack([
|
1086
|
-
val2020,
|
1087
|
-
val2020 * (1 + pol2.inflation_rates(year=2020)),
|
1088
|
-
(
|
1089
|
-
val2020 * (1 + pol2.inflation_rates(year=2020))
|
1090
|
-
).round(2) * (1 + pol2.inflation_rates(year=2021)),
|
1091
|
-
val2023,
|
1092
|
-
val2023 * (1 + pol2.inflation_rates(year=2023)),
|
1093
|
-
]).round(2)
|
1094
|
-
np.testing.assert_allclose(pol2.EITC_c, exp)
|
1095
|
-
|
1096
|
-
def test_adj_without_index_1(self):
|
1097
|
-
"""
|
1098
|
-
Test update indexed parameter after turning off its
|
1099
|
-
indexed status.
|
1100
|
-
"""
|
1101
|
-
pol1 = Policy()
|
1102
|
-
pol1.implement_reform(
|
1103
|
-
{
|
1104
|
-
"EITC_c": {
|
1105
|
-
2020: [10000, 10001, 10002, 10003],
|
1106
|
-
2023: [20000, 20001, 20002, 20003],
|
1107
|
-
},
|
1108
|
-
"EITC_c-indexed": {2019: False},
|
1109
|
-
}
|
1110
|
-
)
|
1111
|
-
|
1112
|
-
pol2 = Policy()
|
1113
|
-
pol2.adjust(
|
1114
|
-
{
|
1115
|
-
"EITC_c": [
|
1116
|
-
{"year": 2020, "EIC": "0kids", "value": 10000},
|
1117
|
-
{"year": 2020, "EIC": "1kid", "value": 10001},
|
1118
|
-
{"year": 2020, "EIC": "2kids", "value": 10002},
|
1119
|
-
{"year": 2020, "EIC": "3+kids", "value": 10003},
|
1120
|
-
{"year": 2023, "EIC": "0kids", "value": 20000},
|
1121
|
-
{"year": 2023, "EIC": "1kid", "value": 20001},
|
1122
|
-
{"year": 2023, "EIC": "2kids", "value": 20002},
|
1123
|
-
{"year": 2023, "EIC": "3+kids", "value": 20003},
|
1124
|
-
],
|
1125
|
-
"EITC_c-indexed": [{"year": 2019, "value": False}],
|
1037
|
+
pol1 = Policy()
|
1038
|
+
pol1.implement_reform(
|
1039
|
+
{
|
1040
|
+
"EITC_c": {
|
1041
|
+
2020: [10000, 10001, 10002, 10003],
|
1042
|
+
2023: [20000, 20001, 20002, 20003],
|
1126
1043
|
}
|
1127
|
-
|
1128
|
-
|
1044
|
+
}
|
1045
|
+
)
|
1046
|
+
pol2 = Policy()
|
1047
|
+
pol2.adjust(
|
1048
|
+
{
|
1049
|
+
"EITC_c": [
|
1050
|
+
{"year": 2020, "EIC": "0kids", "value": 10000},
|
1051
|
+
{"year": 2020, "EIC": "1kid", "value": 10001},
|
1052
|
+
{"year": 2020, "EIC": "2kids", "value": 10002},
|
1053
|
+
{"year": 2020, "EIC": "3+kids", "value": 10003},
|
1054
|
+
{"year": 2023, "EIC": "0kids", "value": 20000},
|
1055
|
+
{"year": 2023, "EIC": "1kid", "value": 20001},
|
1056
|
+
{"year": 2023, "EIC": "2kids", "value": 20002},
|
1057
|
+
{"year": 2023, "EIC": "3+kids", "value": 20003},
|
1058
|
+
]
|
1059
|
+
}
|
1060
|
+
)
|
1061
|
+
cmp_policy_objs(pol1, pol2)
|
1129
1062
|
|
1130
|
-
|
1131
|
-
|
1132
|
-
|
1063
|
+
pol0 = Policy()
|
1064
|
+
pol0.set_year(2019)
|
1065
|
+
pol2.set_year(2019)
|
1133
1066
|
|
1134
|
-
|
1067
|
+
assert np.allclose(pol0.EITC_c, pol2.EITC_c)
|
1135
1068
|
|
1136
|
-
|
1069
|
+
pol2.set_state(year=[2020, 2021, 2022, 2023, 2024])
|
1070
|
+
val2020 = np.array([[10000, 10001, 10002, 10003]])
|
1071
|
+
val2023 = np.array([[20000, 20001, 20002, 20003]])
|
1137
1072
|
|
1138
|
-
|
1139
|
-
|
1073
|
+
exp = np.vstack([
|
1074
|
+
val2020,
|
1075
|
+
val2020 * (1 + pol2.inflation_rates(year=2020)),
|
1076
|
+
(
|
1077
|
+
val2020 * (1 + pol2.inflation_rates(year=2020))
|
1078
|
+
).round(2) * (1 + pol2.inflation_rates(year=2021)),
|
1079
|
+
val2023,
|
1080
|
+
val2023 * (1 + pol2.inflation_rates(year=2023)),
|
1081
|
+
]).round(2)
|
1082
|
+
np.testing.assert_allclose(pol2.EITC_c, exp)
|
1140
1083
|
|
1141
|
-
exp = np.vstack([
|
1142
|
-
val2020,
|
1143
|
-
val2020,
|
1144
|
-
val2020,
|
1145
|
-
val2023,
|
1146
|
-
val2023,
|
1147
|
-
]).round(2)
|
1148
|
-
np.testing.assert_allclose(pol2.EITC_c, exp)
|
1149
1084
|
|
1150
|
-
|
1151
|
-
|
1152
|
-
|
1153
|
-
|
1154
|
-
|
1155
|
-
|
1156
|
-
|
1157
|
-
{
|
1158
|
-
|
1159
|
-
|
1160
|
-
|
1161
|
-
|
1162
|
-
|
1163
|
-
|
1164
|
-
|
1085
|
+
def test_adj_without_index_1():
|
1086
|
+
"""
|
1087
|
+
Test update indexed parameter after turning off its indexed status.
|
1088
|
+
"""
|
1089
|
+
pol1 = Policy()
|
1090
|
+
pol1.implement_reform(
|
1091
|
+
{
|
1092
|
+
"EITC_c": {
|
1093
|
+
2020: [10000, 10001, 10002, 10003],
|
1094
|
+
2023: [20000, 20001, 20002, 20003],
|
1095
|
+
},
|
1096
|
+
"EITC_c-indexed": {2019: False},
|
1097
|
+
}
|
1098
|
+
)
|
1099
|
+
pol2 = Policy()
|
1100
|
+
pol2.adjust(
|
1101
|
+
{
|
1102
|
+
"EITC_c": [
|
1103
|
+
{"year": 2020, "EIC": "0kids", "value": 10000},
|
1104
|
+
{"year": 2020, "EIC": "1kid", "value": 10001},
|
1105
|
+
{"year": 2020, "EIC": "2kids", "value": 10002},
|
1106
|
+
{"year": 2020, "EIC": "3+kids", "value": 10003},
|
1107
|
+
{"year": 2023, "EIC": "0kids", "value": 20000},
|
1108
|
+
{"year": 2023, "EIC": "1kid", "value": 20001},
|
1109
|
+
{"year": 2023, "EIC": "2kids", "value": 20002},
|
1110
|
+
{"year": 2023, "EIC": "3+kids", "value": 20003},
|
1111
|
+
],
|
1112
|
+
"EITC_c-indexed": [{"year": 2019, "value": False}],
|
1113
|
+
}
|
1114
|
+
)
|
1115
|
+
cmp_policy_objs(pol1, pol2)
|
1165
1116
|
|
1166
|
-
|
1167
|
-
|
1168
|
-
|
1169
|
-
"EITC_c": [
|
1170
|
-
{"year": 2020, "EIC": "0kids", "value": 10000},
|
1171
|
-
{"year": 2020, "EIC": "1kid", "value": 10001},
|
1172
|
-
{"year": 2020, "EIC": "2kids", "value": 10002},
|
1173
|
-
{"year": 2020, "EIC": "3+kids", "value": 10003},
|
1174
|
-
{"year": 2023, "EIC": "0kids", "value": 20000},
|
1175
|
-
{"year": 2023, "EIC": "1kid", "value": 20001},
|
1176
|
-
{"year": 2023, "EIC": "2kids", "value": 20002},
|
1177
|
-
{"year": 2023, "EIC": "3+kids", "value": 20003},
|
1178
|
-
],
|
1179
|
-
"EITC_c-indexed": [{"year": 2022, "value": False}],
|
1180
|
-
}
|
1181
|
-
)
|
1182
|
-
cmp_policy_objs(pol1, pol2)
|
1117
|
+
pol0 = Policy()
|
1118
|
+
pol0.set_year(2019)
|
1119
|
+
pol2.set_year(2019)
|
1183
1120
|
|
1184
|
-
|
1185
|
-
pol0.set_year(2019)
|
1186
|
-
pol2.set_year(2019)
|
1121
|
+
assert np.allclose(pol0.EITC_c, pol2.EITC_c)
|
1187
1122
|
|
1188
|
-
|
1123
|
+
pol2.set_state(year=[2020, 2021, 2022, 2023, 2024])
|
1189
1124
|
|
1190
|
-
|
1125
|
+
val2020 = np.array([[10000, 10001, 10002, 10003]])
|
1126
|
+
val2023 = np.array([[20000, 20001, 20002, 20003]])
|
1191
1127
|
|
1192
|
-
|
1193
|
-
|
1128
|
+
exp = np.vstack([
|
1129
|
+
val2020,
|
1130
|
+
val2020,
|
1131
|
+
val2020,
|
1132
|
+
val2023,
|
1133
|
+
val2023,
|
1134
|
+
]).round(2)
|
1135
|
+
np.testing.assert_allclose(pol2.EITC_c, exp)
|
1194
1136
|
|
1195
|
-
exp = np.vstack([
|
1196
|
-
val2020,
|
1197
|
-
val2020 * (1 + pol2.inflation_rates(year=2020)),
|
1198
|
-
(
|
1199
|
-
val2020 * (1 + pol2.inflation_rates(year=2020))
|
1200
|
-
).round(2) * (1 + pol2.inflation_rates(year=2021)),
|
1201
|
-
val2023,
|
1202
|
-
val2023,
|
1203
|
-
]).round(2)
|
1204
|
-
np.testing.assert_allclose(pol2.EITC_c, exp)
|
1205
1137
|
|
1206
|
-
|
1207
|
-
|
1208
|
-
|
1209
|
-
|
1210
|
-
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1214
|
-
|
1215
|
-
|
1216
|
-
|
1217
|
-
|
1218
|
-
{
|
1219
|
-
|
1220
|
-
|
1221
|
-
|
1222
|
-
|
1223
|
-
|
1138
|
+
def test_adj_without_index_2():
|
1139
|
+
"""
|
1140
|
+
Test updating an indexed parameter, making it unindexed,
|
1141
|
+
and then adjusting it again.
|
1142
|
+
"""
|
1143
|
+
pol1 = Policy()
|
1144
|
+
pol1.implement_reform(
|
1145
|
+
{
|
1146
|
+
"EITC_c": {
|
1147
|
+
2020: [10000, 10001, 10002, 10003],
|
1148
|
+
2023: [20000, 20001, 20002, 20003],
|
1149
|
+
},
|
1150
|
+
"EITC_c-indexed": {2022: False},
|
1151
|
+
}
|
1152
|
+
)
|
1153
|
+
pol2 = Policy()
|
1154
|
+
pol2.adjust(
|
1155
|
+
{
|
1156
|
+
"EITC_c": [
|
1157
|
+
{"year": 2020, "EIC": "0kids", "value": 10000},
|
1158
|
+
{"year": 2020, "EIC": "1kid", "value": 10001},
|
1159
|
+
{"year": 2020, "EIC": "2kids", "value": 10002},
|
1160
|
+
{"year": 2020, "EIC": "3+kids", "value": 10003},
|
1161
|
+
{"year": 2023, "EIC": "0kids", "value": 20000},
|
1162
|
+
{"year": 2023, "EIC": "1kid", "value": 20001},
|
1163
|
+
{"year": 2023, "EIC": "2kids", "value": 20002},
|
1164
|
+
{"year": 2023, "EIC": "3+kids", "value": 20003},
|
1165
|
+
],
|
1166
|
+
"EITC_c-indexed": [{"year": 2022, "value": False}],
|
1167
|
+
}
|
1168
|
+
)
|
1169
|
+
cmp_policy_objs(pol1, pol2)
|
1224
1170
|
|
1225
|
-
|
1226
|
-
|
1227
|
-
|
1228
|
-
exp = np.array([
|
1229
|
-
pol0.CTC_c[0],
|
1230
|
-
2000,
|
1231
|
-
2000 * (1 + pol2.inflation_rates(year=2022))
|
1232
|
-
]).round(2)
|
1171
|
+
pol0 = Policy()
|
1172
|
+
pol0.set_year(2019)
|
1173
|
+
pol2.set_year(2019)
|
1233
1174
|
|
1234
|
-
|
1175
|
+
assert np.allclose(pol0.EITC_c, pol2.EITC_c)
|
1235
1176
|
|
1236
|
-
|
1237
|
-
"""
|
1238
|
-
Test applying the parameter_indexing_CPI_offset parameter
|
1239
|
-
without any other parameters.
|
1240
|
-
"""
|
1241
|
-
pol1 = Policy()
|
1242
|
-
pol1.implement_reform(
|
1243
|
-
{"parameter_indexing_CPI_offset": {2021: -0.001}}
|
1244
|
-
)
|
1177
|
+
pol2.set_state(year=[2020, 2021, 2022, 2023, 2024])
|
1245
1178
|
|
1246
|
-
|
1247
|
-
|
1248
|
-
{"parameter_indexing_CPI_offset": [
|
1249
|
-
{"year": 2021, "value": -0.001}
|
1250
|
-
]}
|
1251
|
-
)
|
1179
|
+
val2020 = np.array([[10000, 10001, 10002, 10003]])
|
1180
|
+
val2023 = np.array([[20000, 20001, 20002, 20003]])
|
1252
1181
|
|
1253
|
-
|
1182
|
+
exp = np.vstack([
|
1183
|
+
val2020,
|
1184
|
+
val2020 * (1 + pol2.inflation_rates(year=2020)),
|
1185
|
+
(
|
1186
|
+
val2020 * (1 + pol2.inflation_rates(year=2020))
|
1187
|
+
).round(2) * (1 + pol2.inflation_rates(year=2021)),
|
1188
|
+
val2023,
|
1189
|
+
val2023,
|
1190
|
+
]).round(2)
|
1191
|
+
np.testing.assert_allclose(pol2.EITC_c, exp)
|
1254
1192
|
|
1255
|
-
pol0 = Policy()
|
1256
|
-
pol0.implement_reform({"parameter_indexing_CPI_offset": {2021: 0}})
|
1257
1193
|
|
1258
|
-
|
1259
|
-
|
1194
|
+
def test_activate_index():
|
1195
|
+
"""
|
1196
|
+
Test changing a non-indexed parameter to an indexed parameter.
|
1197
|
+
"""
|
1198
|
+
pol1 = Policy()
|
1199
|
+
pol1.implement_reform({
|
1200
|
+
"CTC_c": {2022: 2000},
|
1201
|
+
"CTC_c-indexed": {2022: True}
|
1202
|
+
})
|
1203
|
+
pol2 = Policy()
|
1204
|
+
pol2.adjust(
|
1205
|
+
{
|
1206
|
+
"CTC_c": [{"year": 2022, "value": 2000}],
|
1207
|
+
"CTC_c-indexed": [{"year": 2022, "value": True}],
|
1208
|
+
}
|
1209
|
+
)
|
1210
|
+
cmp_policy_objs(pol1, pol2)
|
1260
1211
|
|
1261
|
-
|
1212
|
+
pol0 = Policy()
|
1213
|
+
pol0.set_year(year=2021)
|
1214
|
+
pol2.set_state(year=[2021, 2022, 2023])
|
1215
|
+
exp = np.array([
|
1216
|
+
pol0.CTC_c[0],
|
1217
|
+
2000,
|
1218
|
+
2000 * (1 + pol2.inflation_rates(year=2022))
|
1219
|
+
]).round(2)
|
1262
1220
|
|
1263
|
-
|
1264
|
-
exp_rates[start_ix:] -= pol2._parameter_indexing_CPI_offset[start_ix:]
|
1265
|
-
np.testing.assert_allclose(init_rates, exp_rates)
|
1221
|
+
np.testing.assert_allclose(pol2.CTC_c, exp)
|
1266
1222
|
|
1267
|
-
# make sure values prior to 2021 were not affected.
|
1268
|
-
cmp_policy_objs(pol0, pol2, year_range=range(pol2.start_year, 2021))
|
1269
1223
|
|
1270
|
-
|
1271
|
-
|
1272
|
-
|
1273
|
-
|
1274
|
-
|
1224
|
+
def test_apply_cpi_offset():
|
1225
|
+
"""
|
1226
|
+
Test applying the parameter_indexing_CPI_offset parameter
|
1227
|
+
without any other parameters.
|
1228
|
+
"""
|
1229
|
+
pol1 = Policy()
|
1230
|
+
pol1.implement_reform(
|
1231
|
+
{"parameter_indexing_CPI_offset": {2021: -0.001}}
|
1232
|
+
)
|
1233
|
+
pol2 = Policy()
|
1234
|
+
pol2.adjust(
|
1235
|
+
{"parameter_indexing_CPI_offset": [
|
1236
|
+
{"year": 2021, "value": -0.001}
|
1237
|
+
]}
|
1238
|
+
)
|
1239
|
+
cmp_policy_objs(pol1, pol2)
|
1275
1240
|
|
1276
|
-
|
1277
|
-
|
1278
|
-
Test changing a parameter's indexed status multiple times.
|
1279
|
-
"""
|
1280
|
-
pol1 = Policy()
|
1281
|
-
pol1.implement_reform(
|
1282
|
-
{
|
1283
|
-
"II_em": {2016: 6000, 2018: 7500, 2020: 9000},
|
1284
|
-
"II_em-indexed": {2016: False, 2018: True},
|
1285
|
-
}
|
1286
|
-
)
|
1241
|
+
pol0 = Policy()
|
1242
|
+
pol0.implement_reform({"parameter_indexing_CPI_offset": {2021: 0}})
|
1287
1243
|
|
1288
|
-
|
1289
|
-
|
1290
|
-
{
|
1291
|
-
"II_em": [
|
1292
|
-
{"year": 2016, "value": 6000},
|
1293
|
-
{"year": 2018, "value": 7500},
|
1294
|
-
{"year": 2020, "value": 9000},
|
1295
|
-
],
|
1296
|
-
"II_em-indexed": [
|
1297
|
-
{"year": 2016, "value": False},
|
1298
|
-
{"year": 2018, "value": True},
|
1299
|
-
],
|
1300
|
-
}
|
1301
|
-
)
|
1244
|
+
init_rates = pol0.inflation_rates()
|
1245
|
+
new_rates = pol2.inflation_rates()
|
1302
1246
|
|
1303
|
-
|
1247
|
+
start_ix = 2021 - pol2.start_year
|
1304
1248
|
|
1305
|
-
|
1306
|
-
|
1307
|
-
|
1308
|
-
pol2.II_em[0], pol2.II_em[1]
|
1309
|
-
)
|
1249
|
+
exp_rates = copy.deepcopy(new_rates)
|
1250
|
+
exp_rates[start_ix:] -= pol2._parameter_indexing_CPI_offset[start_ix:]
|
1251
|
+
np.testing.assert_allclose(init_rates, exp_rates)
|
1310
1252
|
|
1311
|
-
|
1312
|
-
|
1313
|
-
np.testing.assert_equal(
|
1314
|
-
(pol2.II_em[1] / pol2.II_em[0] - 1).round(4),
|
1315
|
-
pol2.inflation_rates(year=2018),
|
1316
|
-
)
|
1253
|
+
# make sure values prior to 2021 were not affected.
|
1254
|
+
cmp_policy_objs(pol0, pol2, year_range=range(pol2.start_year, 2021))
|
1317
1255
|
|
1318
|
-
|
1319
|
-
|
1320
|
-
|
1321
|
-
|
1322
|
-
|
1323
|
-
|
1324
|
-
)
|
1256
|
+
test_year = Policy.LAST_KNOWN_YEAR
|
1257
|
+
pol2.set_state(year=[test_year, test_year + 1])
|
1258
|
+
np.testing.assert_equal(
|
1259
|
+
(pol2.EITC_c[1] / pol2.EITC_c[0] - 1).round(4),
|
1260
|
+
(pol0.inflation_rates(year=test_year) + (-0.001)).round(4),
|
1261
|
+
)
|
1325
1262
|
|
1326
|
-
def test_multiple_cpi_swaps2(self):
|
1327
|
-
"""
|
1328
|
-
Test changing the indexed status of multiple parameters multiple
|
1329
|
-
times.
|
1330
|
-
"""
|
1331
|
-
pol1 = Policy()
|
1332
|
-
pol1.implement_reform(
|
1333
|
-
{
|
1334
|
-
"II_em": {2016: 6000, 2018: 7500, 2020: 9000},
|
1335
|
-
"II_em-indexed": {2016: False, 2018: True},
|
1336
|
-
"SS_Earnings_c": {2016: 300000, 2018: 500000},
|
1337
|
-
"SS_Earnings_c-indexed": {2017: False, 2019: True},
|
1338
|
-
"AMT_em-indexed": {2017: False, 2020: True},
|
1339
|
-
}
|
1340
|
-
)
|
1341
1263
|
|
1342
|
-
|
1343
|
-
|
1344
|
-
|
1345
|
-
|
1346
|
-
|
1347
|
-
|
1348
|
-
|
1349
|
-
|
1350
|
-
|
1351
|
-
|
1352
|
-
|
1353
|
-
|
1354
|
-
|
1355
|
-
|
1356
|
-
|
1357
|
-
"
|
1358
|
-
|
1359
|
-
|
1360
|
-
|
1361
|
-
|
1362
|
-
"
|
1363
|
-
|
1364
|
-
|
1365
|
-
|
1366
|
-
|
1367
|
-
|
1264
|
+
def test_multiple_cpi_swaps():
|
1265
|
+
"""
|
1266
|
+
Test changing a parameter's indexed status multiple times.
|
1267
|
+
"""
|
1268
|
+
pol1 = Policy()
|
1269
|
+
pol1.implement_reform(
|
1270
|
+
{
|
1271
|
+
"II_em": {2016: 6000, 2018: 7500, 2020: 9000},
|
1272
|
+
"II_em-indexed": {2016: False, 2018: True},
|
1273
|
+
}
|
1274
|
+
)
|
1275
|
+
pol2 = Policy()
|
1276
|
+
pol2.adjust(
|
1277
|
+
{
|
1278
|
+
"II_em": [
|
1279
|
+
{"year": 2016, "value": 6000},
|
1280
|
+
{"year": 2018, "value": 7500},
|
1281
|
+
{"year": 2020, "value": 9000},
|
1282
|
+
],
|
1283
|
+
"II_em-indexed": [
|
1284
|
+
{"year": 2016, "value": False},
|
1285
|
+
{"year": 2018, "value": True},
|
1286
|
+
],
|
1287
|
+
}
|
1288
|
+
)
|
1289
|
+
cmp_policy_objs(pol1, pol2)
|
1368
1290
|
|
1369
|
-
|
1291
|
+
# check inflation is not applied.
|
1292
|
+
pol2.set_state(year=[2016, 2017])
|
1293
|
+
np.testing.assert_equal(
|
1294
|
+
pol2.II_em[0], pol2.II_em[1]
|
1295
|
+
)
|
1370
1296
|
|
1371
|
-
|
1372
|
-
|
1373
|
-
|
1374
|
-
|
1375
|
-
|
1376
|
-
|
1377
|
-
)
|
1297
|
+
# check inflation rate is applied.
|
1298
|
+
pol2.set_state(year=[2018, 2019])
|
1299
|
+
np.testing.assert_equal(
|
1300
|
+
(pol2.II_em[1] / pol2.II_em[0] - 1).round(4),
|
1301
|
+
pol2.inflation_rates(year=2018),
|
1302
|
+
)
|
1378
1303
|
|
1379
|
-
|
1380
|
-
|
1381
|
-
|
1382
|
-
|
1383
|
-
)
|
1304
|
+
# check inflation rate applied for rest of window.
|
1305
|
+
window = list(range(2020, pol2.end_year + 1))
|
1306
|
+
pol2.set_state(year=window)
|
1307
|
+
np.testing.assert_equal(
|
1308
|
+
(pol2.II_em[1:] / pol2.II_em[:-1] - 1).round(4),
|
1309
|
+
[pol2.inflation_rates(year=year) for year in window[:-1]],
|
1310
|
+
)
|
1384
1311
|
|
1385
|
-
# check inflation rate applied for rest of window.
|
1386
|
-
window = list(range(2019, pol2.end_year + 1))
|
1387
|
-
pol2.set_state(year=window)
|
1388
|
-
np.testing.assert_equal(
|
1389
|
-
(pol2.SS_Earnings_c[1:] / pol2.SS_Earnings_c[:-1] - 1).round(4),
|
1390
|
-
[pol2.wage_growth_rates(year=year) for year in window[:-1]],
|
1391
|
-
)
|
1392
1312
|
|
1393
|
-
|
1394
|
-
|
1395
|
-
|
1396
|
-
|
1397
|
-
|
1398
|
-
|
1399
|
-
|
1400
|
-
|
1401
|
-
|
1402
|
-
|
1403
|
-
|
1404
|
-
|
1405
|
-
|
1406
|
-
|
1407
|
-
|
1408
|
-
|
1409
|
-
|
1410
|
-
|
1411
|
-
|
1313
|
+
def test_multiple_cpi_swaps2():
|
1314
|
+
"""
|
1315
|
+
Test changing the indexed status of multiple parameters multiple times.
|
1316
|
+
"""
|
1317
|
+
pol1 = Policy()
|
1318
|
+
pol1.implement_reform(
|
1319
|
+
{
|
1320
|
+
"II_em": {2016: 6000, 2018: 7500, 2020: 9000},
|
1321
|
+
"II_em-indexed": {2016: False, 2018: True},
|
1322
|
+
"SS_Earnings_c": {2016: 300000, 2018: 500000},
|
1323
|
+
"SS_Earnings_c-indexed": {2017: False, 2019: True},
|
1324
|
+
"AMT_em-indexed": {2017: False, 2020: True},
|
1325
|
+
}
|
1326
|
+
)
|
1327
|
+
pol2 = Policy()
|
1328
|
+
pol2.adjust(
|
1329
|
+
{
|
1330
|
+
"SS_Earnings_c": [
|
1331
|
+
{"year": 2016, "value": 300000},
|
1332
|
+
{"year": 2018, "value": 500000},
|
1333
|
+
],
|
1334
|
+
"SS_Earnings_c-indexed": [
|
1335
|
+
{"year": 2017, "value": False},
|
1336
|
+
{"year": 2019, "value": True},
|
1337
|
+
],
|
1338
|
+
"AMT_em-indexed": [
|
1339
|
+
{"year": 2017, "value": False},
|
1340
|
+
{"year": 2020, "value": True},
|
1341
|
+
],
|
1342
|
+
"II_em": [
|
1343
|
+
{"year": 2016, "value": 6000},
|
1344
|
+
{"year": 2018, "value": 7500},
|
1345
|
+
{"year": 2020, "value": 9000},
|
1346
|
+
],
|
1347
|
+
"II_em-indexed": [
|
1348
|
+
{"year": 2016, "value": False},
|
1349
|
+
{"year": 2018, "value": True},
|
1350
|
+
],
|
1351
|
+
}
|
1352
|
+
)
|
1353
|
+
cmp_policy_objs(pol1, pol2)
|
1354
|
+
|
1355
|
+
# Test SS_Earnings_c
|
1356
|
+
# check inflation is still applied from 2016 to 2017.
|
1357
|
+
pol2.set_state(year=[2016, 2017])
|
1358
|
+
np.testing.assert_equal(
|
1359
|
+
(pol2.SS_Earnings_c[1] / pol2.SS_Earnings_c[0] - 1).round(4),
|
1360
|
+
pol2.wage_growth_rates(year=2016),
|
1361
|
+
)
|
1412
1362
|
|
1413
|
-
|
1414
|
-
|
1415
|
-
|
1416
|
-
|
1417
|
-
|
1418
|
-
)
|
1363
|
+
# check inflation rate is not applied after adjustment in 2018.
|
1364
|
+
pol2.set_state(year=[2018, 2019])
|
1365
|
+
np.testing.assert_equal(
|
1366
|
+
pol2.SS_Earnings_c[0], pol2.SS_Earnings_c[1]
|
1367
|
+
)
|
1419
1368
|
|
1420
|
-
|
1421
|
-
|
1422
|
-
|
1423
|
-
|
1424
|
-
|
1425
|
-
)
|
1369
|
+
# check inflation rate applied for rest of window.
|
1370
|
+
window = list(range(2019, pol2.end_year + 1))
|
1371
|
+
pol2.set_state(year=window)
|
1372
|
+
np.testing.assert_equal(
|
1373
|
+
(pol2.SS_Earnings_c[1:] / pol2.SS_Earnings_c[:-1] - 1).round(4),
|
1374
|
+
[pol2.wage_growth_rates(year=year) for year in window[:-1]],
|
1375
|
+
)
|
1426
1376
|
|
1427
|
-
|
1428
|
-
|
1429
|
-
|
1377
|
+
# Test AMT
|
1378
|
+
# Check values for 2017 through 2020 are equal.
|
1379
|
+
pol2.set_state(year=[2017, 2018, 2019, 2020])
|
1380
|
+
for i in (1, 2, 3):
|
1430
1381
|
np.testing.assert_equal(
|
1431
|
-
|
1432
|
-
[pol2.inflation_rates(year=year) for year in window[:-1]],
|
1433
|
-
)
|
1434
|
-
|
1435
|
-
def test_adj_CPI_offset_and_index_status(self):
|
1436
|
-
"""
|
1437
|
-
Test changing parameter_indexing_CPI_offset and another
|
1438
|
-
parameter simultaneously.
|
1439
|
-
"""
|
1440
|
-
pol1 = Policy()
|
1441
|
-
pol1.implement_reform({
|
1442
|
-
"CTC_c-indexed": {2020: True},
|
1443
|
-
"parameter_indexing_CPI_offset": {2020: -0.005}},
|
1444
|
-
)
|
1445
|
-
|
1446
|
-
pol2 = Policy()
|
1447
|
-
pol2.adjust(
|
1448
|
-
{
|
1449
|
-
"parameter_indexing_CPI_offset":
|
1450
|
-
[{"year": 2020, "value": -0.005}],
|
1451
|
-
"CTC_c-indexed": [{"year": 2020, "value": True}],
|
1452
|
-
}
|
1382
|
+
pol2.AMT_em[0], pol2.AMT_em[i]
|
1453
1383
|
)
|
1454
1384
|
|
1455
|
-
|
1456
|
-
|
1457
|
-
|
1458
|
-
|
1459
|
-
|
1460
|
-
|
1461
|
-
|
1462
|
-
|
1463
|
-
|
1464
|
-
|
1465
|
-
|
1385
|
+
# check inflation rate applied for rest of window.
|
1386
|
+
window = list(range(2020, pol2.end_year + 1))
|
1387
|
+
pol2.set_state(year=window)
|
1388
|
+
# repeat inflation rates accross matrix so they can be compared to the
|
1389
|
+
# rates derived from AMT_em, a 5 * N matrix.
|
1390
|
+
exp_rates = [pol2.inflation_rates(year=year) for year in window[:-1]]
|
1391
|
+
exp_rates = np.tile([exp_rates], (5, 1)).transpose()
|
1392
|
+
np.testing.assert_equal(
|
1393
|
+
(pol2.AMT_em[1:] / pol2.AMT_em[:-1] - 1).round(4),
|
1394
|
+
exp_rates,
|
1395
|
+
)
|
1466
1396
|
|
1467
|
-
|
1468
|
-
|
1469
|
-
|
1470
|
-
|
1471
|
-
|
1397
|
+
# Test II_em
|
1398
|
+
# check inflation is not applied.
|
1399
|
+
pol2.set_state(year=[2016, 2017])
|
1400
|
+
np.testing.assert_equal(
|
1401
|
+
pol2.II_em[0], pol2.II_em[1]
|
1402
|
+
)
|
1472
1403
|
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1404
|
+
# check inflation rate is applied.
|
1405
|
+
pol2.set_state(year=[2018, 2019])
|
1406
|
+
np.testing.assert_equal(
|
1407
|
+
(pol2.II_em[1] / pol2.II_em[0] - 1).round(4),
|
1408
|
+
pol2.inflation_rates(year=2018),
|
1409
|
+
)
|
1478
1410
|
|
1479
|
-
|
1480
|
-
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1485
|
-
|
1486
|
-
"II_brk7": [{"value": 445400, "MARS": "single", "year": 2020}],
|
1487
|
-
}
|
1488
|
-
)
|
1411
|
+
# check inflation rate applied for rest of window.
|
1412
|
+
window = list(range(2020, pol2.end_year + 1))
|
1413
|
+
pol2.set_state(year=window)
|
1414
|
+
np.testing.assert_equal(
|
1415
|
+
(pol2.II_em[1:] / pol2.II_em[:-1] - 1).round(4),
|
1416
|
+
[pol2.inflation_rates(year=year) for year in window[:-1]],
|
1417
|
+
)
|
1489
1418
|
|
1490
|
-
# Check no difference prior to 2020
|
1491
|
-
pol0 = Policy()
|
1492
|
-
cmp_policy_objs(
|
1493
|
-
pol0,
|
1494
|
-
pol,
|
1495
|
-
year_range=range(pol.start_year, 2019 + 1),
|
1496
|
-
)
|
1497
1419
|
|
1498
|
-
|
1499
|
-
|
1500
|
-
|
1501
|
-
|
1502
|
-
|
1503
|
-
|
1504
|
-
|
1505
|
-
|
1506
|
-
|
1507
|
-
|
1420
|
+
def test_adj_CPI_offset_and_index_status():
|
1421
|
+
"""
|
1422
|
+
Test changing parameter_indexing_CPI_offset and another
|
1423
|
+
parameter simultaneously.
|
1424
|
+
"""
|
1425
|
+
pol1 = Policy()
|
1426
|
+
pol1.implement_reform({
|
1427
|
+
"CTC_c-indexed": {2020: True},
|
1428
|
+
"parameter_indexing_CPI_offset": {2020: -0.005}},
|
1429
|
+
)
|
1430
|
+
pol2 = Policy()
|
1431
|
+
pol2.adjust(
|
1432
|
+
{
|
1433
|
+
"parameter_indexing_CPI_offset":
|
1434
|
+
[{"year": 2020, "value": -0.005}],
|
1435
|
+
"CTC_c-indexed": [{"year": 2020, "value": True}],
|
1436
|
+
}
|
1437
|
+
)
|
1438
|
+
cmp_policy_objs(pol1, pol2)
|
1439
|
+
|
1440
|
+
# Check no difference prior to 2020
|
1441
|
+
pol0 = Policy()
|
1442
|
+
pol0.implement_reform({"parameter_indexing_CPI_offset": {2020: 0}})
|
1443
|
+
cmp_policy_objs(
|
1444
|
+
pol0,
|
1445
|
+
pol2,
|
1446
|
+
year_range=range(pol2.start_year, 2020 + 1),
|
1447
|
+
exclude=["parameter_indexing_CPI_offset"]
|
1448
|
+
)
|
1508
1449
|
|
1509
|
-
|
1510
|
-
|
1511
|
-
|
1512
|
-
|
1513
|
-
|
1514
|
-
)
|
1450
|
+
pol2.set_state(year=[2021, 2022])
|
1451
|
+
np.testing.assert_equal(
|
1452
|
+
(pol2.CTC_c[1] / pol2.CTC_c[0] - 1).round(4),
|
1453
|
+
round(pol0.inflation_rates(year=2021) + (-0.005), 4),
|
1454
|
+
)
|
1515
1455
|
|
1516
|
-
def test_indexed_status_parsing(self):
|
1517
|
-
pol1 = Policy()
|
1518
1456
|
|
1519
|
-
|
1457
|
+
def test_adj_related_parameters_and_index_status():
|
1458
|
+
"""
|
1459
|
+
Test changing two related parameters simulataneously and
|
1460
|
+
one of their indexed statuses.
|
1461
|
+
"""
|
1462
|
+
pol = Policy()
|
1463
|
+
pol.adjust(
|
1464
|
+
{
|
1465
|
+
"II_brk7-indexed": [{"year": 2020, "value": True}],
|
1466
|
+
# Update II_brk5 in 2026 to make reform valid after reset.
|
1467
|
+
"II_brk5": [{"value": 330000, "MARS": "single", "year": 2026}],
|
1468
|
+
"II_brk6": [{"value": 316700, "MARS": "single", "year": 2020}],
|
1469
|
+
"II_brk7": [{"value": 445400, "MARS": "single", "year": 2020}],
|
1470
|
+
}
|
1471
|
+
)
|
1520
1472
|
|
1521
|
-
|
1522
|
-
|
1473
|
+
# Check no difference prior to 2020
|
1474
|
+
pol0 = Policy()
|
1475
|
+
cmp_policy_objs(
|
1476
|
+
pol0,
|
1477
|
+
pol,
|
1478
|
+
year_range=range(pol.start_year, 2019 + 1),
|
1479
|
+
)
|
1523
1480
|
|
1524
|
-
|
1481
|
+
res = (
|
1482
|
+
(pol.sel["II_brk6"]["MARS"] == "single")
|
1483
|
+
& (pol.sel["II_brk6"]["year"] == 2020)
|
1484
|
+
)
|
1485
|
+
assert res.isel[0]["value"] == [316700]
|
1486
|
+
res = (
|
1487
|
+
(pol.sel["II_brk7"]["MARS"] == "single")
|
1488
|
+
& (pol.sel["II_brk7"]["year"] == 2020)
|
1489
|
+
)
|
1490
|
+
assert res.isel[0]["value"] == [445400]
|
1525
1491
|
|
1526
|
-
|
1527
|
-
|
1492
|
+
II_brk7 = pol.to_array("II_brk7", year=[2021, 2022])
|
1493
|
+
II_brk7_single = II_brk7[:, 0]
|
1494
|
+
np.testing.assert_equal(
|
1495
|
+
(II_brk7_single[1] / II_brk7_single[0] - 1).round(4),
|
1496
|
+
pol.inflation_rates(year=2021),
|
1497
|
+
)
|
1528
1498
|
|
1529
|
-
def test_cpi_offset_does_not_affect_wage_indexed_params(self):
|
1530
|
-
"""
|
1531
|
-
Test adjusting parameter_indexing_CPI_offset does not affect unknown
|
1532
|
-
values of wage indexed parameters like SS_Earnings_c.
|
1533
|
-
"""
|
1534
|
-
base_reform = {
|
1535
|
-
"parameter_indexing_CPI_offset": {2021: -0.001},
|
1536
|
-
"SS_Earnings_c": {2024: 300000},
|
1537
|
-
}
|
1538
1499
|
|
1539
|
-
|
1540
|
-
|
1500
|
+
def test_indexed_status_parsing():
|
1501
|
+
"""
|
1502
|
+
Test parsing.
|
1503
|
+
"""
|
1504
|
+
pol1 = Policy()
|
1505
|
+
pol1.implement_reform({"EITC_c-indexed": {pol1.start_year: False}})
|
1506
|
+
pol2 = Policy()
|
1507
|
+
pol2.adjust({"EITC_c-indexed": False})
|
1508
|
+
cmp_policy_objs(pol1, pol2)
|
1541
1509
|
|
1542
|
-
|
1543
|
-
|
1544
|
-
pol1.implement_reform(dict(base_reform, SS_Earnings_c={2025: 500000}))
|
1510
|
+
with pytest.raises(pt.ValidationError):
|
1511
|
+
pol2.adjust({"EITC_c-indexed": 123})
|
1545
1512
|
|
1546
|
-
exp_before_2025 = pol0.to_array(
|
1547
|
-
"SS_Earnings_c", year=list(range(2021, 2024 + 1))
|
1548
|
-
)
|
1549
|
-
act_before_2025 = pol1.to_array(
|
1550
|
-
"SS_Earnings_c", year=list(range(2021, 2024 + 1))
|
1551
|
-
)
|
1552
1513
|
|
1553
|
-
|
1514
|
+
def test_cpi_offset_does_not_affect_wage_indexed_params():
|
1515
|
+
"""
|
1516
|
+
Test adjusting parameter_indexing_CPI_offset does not affect unknown
|
1517
|
+
values of wage indexed parameters like SS_Earnings_c.
|
1518
|
+
"""
|
1519
|
+
base_reform = {
|
1520
|
+
"parameter_indexing_CPI_offset": {2021: -0.001},
|
1521
|
+
"SS_Earnings_c": {2024: 300000},
|
1522
|
+
}
|
1523
|
+
pol0 = Policy()
|
1524
|
+
pol0.implement_reform(base_reform)
|
1525
|
+
pol1 = Policy()
|
1526
|
+
pol1.implement_reform(base_reform)
|
1527
|
+
pol1.implement_reform(dict(base_reform, SS_Earnings_c={2025: 500000}))
|
1528
|
+
|
1529
|
+
exp_before_2025 = pol0.to_array(
|
1530
|
+
"SS_Earnings_c", year=list(range(2021, 2024 + 1))
|
1531
|
+
)
|
1532
|
+
act_before_2025 = pol1.to_array(
|
1533
|
+
"SS_Earnings_c", year=list(range(2021, 2024 + 1))
|
1534
|
+
)
|
1535
|
+
np.testing.assert_equal(act_before_2025, exp_before_2025)
|
1554
1536
|
|
1555
1537
|
|
1556
1538
|
def test_two_sets_of_tax_brackets():
|