taxcalc 5.2.0__py3-none-any.whl → 6.0.0__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 -3
- taxcalc/calcfunctions.py +2 -2
- taxcalc/calculator.py +4 -4
- taxcalc/cli/tc.py +16 -19
- taxcalc/data.py +2 -3
- taxcalc/decorators.py +9 -8
- taxcalc/growfactors.py +2 -1
- taxcalc/policy.py +6 -23
- taxcalc/policy_current_law.json +31 -631
- taxcalc/records.py +78 -82
- taxcalc/records_variables.json +106 -106
- taxcalc/reforms/ARPA.out.csv +9 -9
- taxcalc/taxcalcio.py +101 -77
- taxcalc/tests/conftest.py +20 -15
- taxcalc/tests/puf_var_correl_coeffs_2016.csv +24 -24
- taxcalc/tests/puf_var_wght_means_by_year.csv +11 -11
- taxcalc/tests/pufcsv_agg_expect.csv +20 -20
- taxcalc/tests/pufcsv_mtr_expect.txt +21 -21
- taxcalc/tests/reforms.json +3 -1
- taxcalc/tests/reforms_expect.csv +54 -54
- taxcalc/tests/test_4package.py +8 -9
- taxcalc/tests/test_calculator.py +55 -18
- taxcalc/tests/test_consumption.py +2 -2
- taxcalc/tests/test_cpscsv.py +2 -24
- taxcalc/tests/test_data.py +11 -3
- taxcalc/tests/test_decorators.py +57 -52
- taxcalc/tests/test_growdiff.py +2 -2
- taxcalc/tests/test_parameters.py +101 -53
- taxcalc/tests/test_policy.py +154 -154
- taxcalc/tests/test_records.py +144 -9
- taxcalc/tests/test_reforms.py +104 -104
- taxcalc/tests/test_taxcalcio.py +13 -62
- taxcalc/utils.py +3 -3
- {taxcalc-5.2.0.dist-info → taxcalc-6.0.0.dist-info}/METADATA +3 -6
- {taxcalc-5.2.0.dist-info → taxcalc-6.0.0.dist-info}/RECORD +39 -46
- taxcalc/puf_ratios.csv +0 -26
- taxcalc/puf_weights.csv.gz +0 -0
- taxcalc/reforms/clp.out.csv +0 -10
- taxcalc/tests/test_compare.py +0 -330
- taxcalc/tests/test_compatible_data.py +0 -334
- taxcalc/tests/test_puf_var_stats.py +0 -194
- taxcalc/tests/test_pufcsv.py +0 -328
- {taxcalc-5.2.0.dist-info → taxcalc-6.0.0.dist-info}/WHEEL +0 -0
- {taxcalc-5.2.0.dist-info → taxcalc-6.0.0.dist-info}/entry_points.txt +0 -0
- {taxcalc-5.2.0.dist-info → taxcalc-6.0.0.dist-info}/licenses/LICENSE +0 -0
- {taxcalc-5.2.0.dist-info → taxcalc-6.0.0.dist-info}/top_level.txt +0 -0
taxcalc/tests/test_policy.py
CHANGED
@@ -54,12 +54,12 @@ def test_incorrect_implement_reform_usage():
|
|
54
54
|
with pytest.raises(paramtools.ValidationError):
|
55
55
|
pol.implement_reform([])
|
56
56
|
with pytest.raises(paramtools.ValidationError):
|
57
|
-
pol.implement_reform({2099: {
|
57
|
+
pol.implement_reform({2099: {"II_em": 99000}})
|
58
58
|
pol.set_year(2019)
|
59
59
|
with pytest.raises(paramtools.ValidationError):
|
60
|
-
pol.implement_reform({2018: {
|
60
|
+
pol.implement_reform({2018: {"II_em": 99000}})
|
61
61
|
with pytest.raises(paramtools.ValidationError):
|
62
|
-
pol.implement_reform({2020: {
|
62
|
+
pol.implement_reform({2020: {"II_em": -1000}})
|
63
63
|
|
64
64
|
|
65
65
|
@pytest.mark.local
|
@@ -90,8 +90,8 @@ def test_json_reform_url():
|
|
90
90
|
}
|
91
91
|
}
|
92
92
|
"""
|
93
|
-
reform_url = (
|
94
|
-
|
93
|
+
reform_url = ("https://raw.githubusercontent.com/PSLmodels/"
|
94
|
+
"Tax-Calculator/master/taxcalc/reforms/ptaxes0.json")
|
95
95
|
params_str = Policy.read_json_reform(reform_str)
|
96
96
|
params_url = Policy.read_json_reform(reform_url)
|
97
97
|
assert params_str == params_url
|
@@ -192,7 +192,7 @@ def test_constant_inflation_rate_with_reform():
|
|
192
192
|
fyr = 2034
|
193
193
|
ryr = fyr - 1
|
194
194
|
reform = {
|
195
|
-
|
195
|
+
"II_em": {(ryr - 3): 1000, # to avoid divide-by-zero under TCJA
|
196
196
|
ryr: 20000}
|
197
197
|
}
|
198
198
|
pol.implement_reform(reform)
|
@@ -218,7 +218,7 @@ def test_variable_inflation_rate_with_reform():
|
|
218
218
|
assert pol._II_em[2013 - syr] == 3900
|
219
219
|
# implement reform in 2020 which is two years before the last year, 2022
|
220
220
|
reform = {
|
221
|
-
|
221
|
+
"II_em": {2018: 1000, # to avoid divide-by-zero under TCJA
|
222
222
|
2020: 20000}
|
223
223
|
}
|
224
224
|
pol.implement_reform(reform)
|
@@ -258,14 +258,14 @@ def test_multi_year_reform():
|
|
258
258
|
wfactor[syr + i] = 1.0 + wratelist[i]
|
259
259
|
# specify multi-year reform using a param:year:value-fomatted dictionary
|
260
260
|
reform = {
|
261
|
-
|
261
|
+
"SS_Earnings_c": {2016: 300000,
|
262
262
|
2017: 500000,
|
263
263
|
2019: 700000},
|
264
|
-
|
264
|
+
"SS_Earnings_c-indexed": {2017: False,
|
265
265
|
2019: True},
|
266
|
-
|
266
|
+
"EITC_c": {2016: [900, 5000, 8000, 9000],
|
267
267
|
2019: [1200, 7000, 10000, 12000]},
|
268
|
-
|
268
|
+
"II_em": {2016: 7000,
|
269
269
|
2019: 9000}
|
270
270
|
}
|
271
271
|
# implement multi-year reform
|
@@ -289,7 +289,7 @@ def check_eitc_c(ppo, reform, ifactor):
|
|
289
289
|
generated by the test_multi_year_reform() function above.
|
290
290
|
"""
|
291
291
|
actual = {}
|
292
|
-
arr = getattr(ppo,
|
292
|
+
arr = getattr(ppo, "_EITC_c")
|
293
293
|
alen = len(arr[0])
|
294
294
|
for i in range(0, ppo.num_years):
|
295
295
|
actual[ppo.start_year + i] = arr[i]
|
@@ -299,13 +299,13 @@ def check_eitc_c(ppo, reform, ifactor):
|
|
299
299
|
atol=0.01, rtol=0.0)
|
300
300
|
assert np.allclose(actual[2015], [503, 3359, 5548, 6242],
|
301
301
|
atol=0.01, rtol=0.0)
|
302
|
-
e2016 = reform[
|
302
|
+
e2016 = reform["EITC_c"][2016]
|
303
303
|
assert np.allclose(actual[2016], e2016, atol=0.01, rtol=0.0)
|
304
304
|
e2017 = [ifactor[2016] * actual[2016][j] for j in range(0, alen)]
|
305
305
|
assert np.allclose(actual[2017], e2017, atol=0.01, rtol=0.0)
|
306
306
|
e2018 = [ifactor[2017] * actual[2017][j] for j in range(0, alen)]
|
307
307
|
assert np.allclose(actual[2018], e2018, atol=0.01, rtol=0.0)
|
308
|
-
e2019 = reform[
|
308
|
+
e2019 = reform["EITC_c"][2019]
|
309
309
|
assert np.allclose(actual[2019], e2019, atol=0.01, rtol=0.0)
|
310
310
|
e2020 = [ifactor[2019] * actual[2019][j] for j in range(0, alen)]
|
311
311
|
assert np.allclose(actual[2020], e2020, atol=0.01, rtol=0.0)
|
@@ -321,19 +321,19 @@ def check_ii_em(ppo, reform, ifactor):
|
|
321
321
|
generated by the test_multi_year_reform() function above.
|
322
322
|
"""
|
323
323
|
actual = {}
|
324
|
-
arr = getattr(ppo,
|
324
|
+
arr = getattr(ppo, "_II_em")
|
325
325
|
for i in range(0, ppo.num_years):
|
326
326
|
actual[ppo.start_year + i] = arr[i]
|
327
327
|
assert actual[2013] == 3900
|
328
328
|
assert actual[2014] == 3950
|
329
329
|
assert actual[2015] == 4000
|
330
|
-
e2016 = reform[
|
330
|
+
e2016 = reform["II_em"][2016]
|
331
331
|
assert actual[2016] == e2016
|
332
332
|
e2017 = ifactor[2016] * actual[2016]
|
333
333
|
assert np.allclose([actual[2017]], [e2017], atol=0.01, rtol=0.0)
|
334
334
|
e2018 = ifactor[2017] * actual[2017]
|
335
335
|
assert np.allclose([actual[2018]], [e2018], atol=0.01, rtol=0.0)
|
336
|
-
e2019 = reform[
|
336
|
+
e2019 = reform["II_em"][2019]
|
337
337
|
assert actual[2019] == e2019
|
338
338
|
e2020 = ifactor[2019] * actual[2019]
|
339
339
|
assert np.allclose([actual[2020]], [e2020], atol=0.01, rtol=0.0)
|
@@ -349,19 +349,19 @@ def check_ss_earnings_c(ppo, reform, wfactor):
|
|
349
349
|
generated by the test_multi_year_reform() function above.
|
350
350
|
"""
|
351
351
|
actual = {}
|
352
|
-
arr = getattr(ppo,
|
352
|
+
arr = getattr(ppo, "_SS_Earnings_c")
|
353
353
|
for i in range(0, ppo.num_years):
|
354
354
|
actual[ppo.start_year + i] = arr[i]
|
355
355
|
assert actual[2013] == 113700
|
356
356
|
assert actual[2014] == 117000
|
357
357
|
assert actual[2015] == 118500
|
358
|
-
e2016 = reform[
|
358
|
+
e2016 = reform["SS_Earnings_c"][2016]
|
359
359
|
assert actual[2016] == e2016
|
360
|
-
e2017 = reform[
|
360
|
+
e2017 = reform["SS_Earnings_c"][2017]
|
361
361
|
assert actual[2017] == e2017
|
362
362
|
e2018 = actual[2017] # no indexing after 2017
|
363
363
|
assert actual[2018] == e2018
|
364
|
-
e2019 = reform[
|
364
|
+
e2019 = reform["SS_Earnings_c"][2019]
|
365
365
|
assert actual[2019] == e2019
|
366
366
|
e2020 = wfactor[2019] * actual[2019] # indexing after 2019
|
367
367
|
assert np.allclose([actual[2020]], [e2020], atol=0.01, rtol=0.0)
|
@@ -384,7 +384,7 @@ def test_implement_reform_raises_on_no_year():
|
|
384
384
|
"""
|
385
385
|
Test that implement_reform raises error for missing year.
|
386
386
|
"""
|
387
|
-
reform = {
|
387
|
+
reform = {"STD_Aged": [1400, 1200, 1400, 1400, 1400]}
|
388
388
|
ppo = Policy()
|
389
389
|
with pytest.raises(paramtools.ValidationError):
|
390
390
|
ppo.implement_reform(reform)
|
@@ -395,7 +395,7 @@ def test_implement_reform_raises_on_early_year():
|
|
395
395
|
Test that implement_reform raises error for early year.
|
396
396
|
"""
|
397
397
|
ppo = Policy()
|
398
|
-
reform = {
|
398
|
+
reform = {"STD_Aged": {2010: [1400, 1100, 1100, 1400, 1400]}}
|
399
399
|
with pytest.raises(paramtools.ValidationError):
|
400
400
|
ppo.implement_reform(reform)
|
401
401
|
|
@@ -405,7 +405,7 @@ def test_reform_with_default_indexed():
|
|
405
405
|
Test that implement_reform indexes after first reform year.
|
406
406
|
"""
|
407
407
|
ppo = Policy()
|
408
|
-
reform = {
|
408
|
+
reform = {"II_em": {2015: 4300}}
|
409
409
|
ppo.implement_reform(reform)
|
410
410
|
# II_em has a default indexing status of true, so
|
411
411
|
# in 2016 its value should be greater than 4300
|
@@ -418,7 +418,7 @@ def test_reform_makes_no_changes_before_year():
|
|
418
418
|
Test that implement_reform makes no changes before first reform year.
|
419
419
|
"""
|
420
420
|
ppo = Policy()
|
421
|
-
reform = {
|
421
|
+
reform = {"II_em": {2015: 4400}, "II_em-indexed": {2015: True}}
|
422
422
|
ppo.implement_reform(reform)
|
423
423
|
ppo.set_year(2015)
|
424
424
|
assert np.allclose(ppo._II_em[:3], np.array([3900, 3950, 4400]),
|
@@ -519,7 +519,7 @@ def test_pop_the_cap_reform():
|
|
519
519
|
assert mte[2015 - syr] == 118500
|
520
520
|
assert mte[2016 - syr] == 118500
|
521
521
|
# specify a "pop the cap" reform that eliminates MTE cap in 2016
|
522
|
-
reform = {
|
522
|
+
reform = {"SS_Earnings_c": {2016: 9e99}}
|
523
523
|
ppo.implement_reform(reform)
|
524
524
|
mte = ppo._SS_Earnings_c
|
525
525
|
assert mte[2015 - syr] == 118500
|
@@ -535,13 +535,13 @@ def test_order_of_indexing_and_level_reforms():
|
|
535
535
|
# specify two reforms that raises the MTE and stops its indexing in 2015
|
536
536
|
reforms = [
|
537
537
|
{
|
538
|
-
|
539
|
-
|
538
|
+
"SS_Earnings_c": {2015: 500000},
|
539
|
+
"SS_Earnings_c-indexed": {2015: False}
|
540
540
|
},
|
541
541
|
# now reverse the order of the two reform provisions
|
542
542
|
{
|
543
|
-
|
544
|
-
|
543
|
+
"SS_Earnings_c-indexed": {2015: False},
|
544
|
+
"SS_Earnings_c": {2015: 500000}
|
545
545
|
}
|
546
546
|
]
|
547
547
|
# specify two Policy objects
|
@@ -572,12 +572,12 @@ def test_misspecified_reform_dictionary():
|
|
572
572
|
"""
|
573
573
|
# specify apparently the same reform in two different ways, forgetting
|
574
574
|
# that Python dictionaries have unique keys
|
575
|
-
reform1 = {
|
575
|
+
reform1 = {"II_em": {2019: 1000, 2020: 2000}}
|
576
576
|
# pylint: disable=duplicate-key
|
577
|
-
reform2 = {
|
577
|
+
reform2 = {"II_em": {2019: 1000}, "II_em": {2020: 2000}}
|
578
578
|
# these two reform dictionaries are not the same: the second
|
579
|
-
#
|
580
|
-
# the first
|
579
|
+
# "II_em" key value for 2020 in reform2 OVERWRITES and REPLACES
|
580
|
+
# the first "II_em" key value for 2019 in reform2
|
581
581
|
assert reform1 != reform2
|
582
582
|
|
583
583
|
|
@@ -596,114 +596,114 @@ def test_section_titles(tests_path):
|
|
596
596
|
for line in md_text.splitlines():
|
597
597
|
# This is shown as an empty case in current law policy and
|
598
598
|
# validation.
|
599
|
-
if line.startswith(
|
600
|
-
sdict[
|
601
|
-
sdict[
|
599
|
+
if line.startswith("## Other Parameters (not in Tax-Brain webapp"):
|
600
|
+
sdict[""] = {}
|
601
|
+
sdict[""][""] = 0
|
602
602
|
continue
|
603
|
-
sec2line = line.startswith(
|
604
|
-
sec1line = line.startswith(
|
603
|
+
sec2line = line.startswith("### ")
|
604
|
+
sec1line = line.startswith("## ")
|
605
605
|
# Create outer-layer dictionary entry for sec1.
|
606
606
|
if sec1line:
|
607
|
-
sec1 = line.replace(
|
607
|
+
sec1 = line.replace("##", "", 1).strip()
|
608
608
|
sdict[sec1] = {}
|
609
609
|
# Create inner dictionary entry for sec1-sec2.
|
610
610
|
# Note that sec1 will have been defined from a previous loop.
|
611
611
|
if sec2line:
|
612
|
-
sec2 = line.replace(
|
612
|
+
sec2 = line.replace("###", "", 1).strip()
|
613
613
|
sdict[sec1][sec2] = 0
|
614
614
|
return sdict
|
615
615
|
# begin main logic of test_section_titles
|
616
616
|
# specify expected section titles ordered as on the Tax-Brain webapp
|
617
|
-
cgqd_tax_same = (
|
618
|
-
|
617
|
+
cgqd_tax_same = ("Tax All Capital Gains And Dividends The Same "
|
618
|
+
"As Regular Taxable Income")
|
619
619
|
valid_dict = {
|
620
|
-
|
621
|
-
|
620
|
+
"": { # empty section_1 implies parameter not displayed in Tax-Brain
|
621
|
+
"": 0
|
622
622
|
},
|
623
|
-
|
624
|
-
|
623
|
+
"Parameter Indexing": {
|
624
|
+
"Offsets": 0
|
625
625
|
},
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
626
|
+
"Payroll Taxes": {
|
627
|
+
"Social Security FICA": 0,
|
628
|
+
"Medicare FICA": 0,
|
629
|
+
"Additional Medicare FICA": 0
|
630
630
|
},
|
631
|
-
|
632
|
-
|
631
|
+
"Social Security Taxability": {
|
632
|
+
"Social Security Benefit Taxability": 0,
|
633
633
|
},
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
634
|
+
"Above The Line Deductions": {
|
635
|
+
"Misc. Adjustment Haircuts": 0,
|
636
|
+
"Misc. Exclusions": 0,
|
637
|
+
"Child And Elderly Care": 0
|
638
638
|
},
|
639
|
-
|
640
|
-
|
641
|
-
#
|
642
|
-
|
643
|
-
|
639
|
+
"Personal Exemptions": {
|
640
|
+
"Personal And Dependent Exemption Amount": 0,
|
641
|
+
# "Personal Exemption Phaseout Starting Income": 0,
|
642
|
+
"Personal Exemption Phaseout Rate": 0,
|
643
|
+
"Repeal for Dependents Under Age 18": 0
|
644
644
|
},
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
#
|
645
|
+
"Standard Deduction": {
|
646
|
+
"Standard Deduction Amount": 0,
|
647
|
+
"Additional Standard Deduction For Blind And Aged": 0
|
648
|
+
# "Standard Deduction For Dependents": 0
|
649
649
|
},
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
650
|
+
"Nonrefundable Credits": {
|
651
|
+
"Misc. Credit Limits": 0,
|
652
|
+
"Child And Dependent Care": 0,
|
653
|
+
"Personal Nonrefundable Credit": 0
|
654
654
|
},
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
655
|
+
"Child/Dependent Credits": {
|
656
|
+
"Child Tax Credit": 0,
|
657
|
+
"Additional Child Tax Credit": 0,
|
658
|
+
"Other Dependent Tax Credit": 0
|
659
659
|
},
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
660
|
+
"Itemized Deductions": {
|
661
|
+
"Medical Expenses": 0,
|
662
|
+
"State And Local Income And Sales Taxes": 0,
|
663
|
+
"State, Local, And Foreign Real Estate Taxes": 0,
|
664
|
+
"State And Local Taxes And Real Estate Taxes": 0,
|
665
|
+
"Interest Paid": 0,
|
666
|
+
"Charity": 0,
|
667
|
+
"Casualty": 0,
|
668
|
+
"Miscellaneous": 0,
|
669
|
+
"Itemized Deduction Limitation": 0, # Pease
|
670
|
+
"Ceiling On The Amount Of Itemized Deductions Allowed": 0 # ID_c
|
671
671
|
},
|
672
|
-
|
673
|
-
|
674
|
-
|
672
|
+
"Capital Gains And Dividends": {
|
673
|
+
"Regular - Long Term Capital Gains And Qualified Dividends": 0,
|
674
|
+
"AMT - Long Term Capital Gains And Qualified Dividends": 0,
|
675
675
|
cgqd_tax_same: 0
|
676
676
|
},
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
677
|
+
"Personal Income": {
|
678
|
+
"Regular: Non-AMT": 0,
|
679
|
+
"Pass-Through": 0,
|
680
|
+
"Alternative Minimum Tax": 0
|
681
681
|
},
|
682
|
-
|
683
|
-
|
682
|
+
"Other Taxes": {
|
683
|
+
"Net Investment Income Tax": 0
|
684
684
|
},
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
685
|
+
"Refundable Credits": {
|
686
|
+
"Earned Income Tax Credit": 0,
|
687
|
+
"New Refundable Child Tax Credit": 0,
|
688
|
+
"Personal Refundable Credit": 0,
|
689
|
+
"Refundable Payroll Tax Credit": 0
|
690
690
|
},
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
691
|
+
"Surtaxes": {
|
692
|
+
"New Minimum Tax": 0,
|
693
|
+
"New AGI Surtax": 0,
|
694
|
+
"Lump-Sum Tax": 0
|
695
695
|
},
|
696
|
-
|
697
|
-
|
698
|
-
|
696
|
+
"Universal Basic Income": {
|
697
|
+
"UBI Benefits": 0,
|
698
|
+
"UBI Taxability": 0
|
699
699
|
},
|
700
|
-
|
701
|
-
|
700
|
+
"Benefits": {
|
701
|
+
"Benefit Repeal": 0,
|
702
702
|
}
|
703
703
|
}
|
704
704
|
# check validity of parameter section titles in policy_current_law.json
|
705
|
-
path = os.path.join(tests_path,
|
706
|
-
with open(path,
|
705
|
+
path = os.path.join(tests_path, "..", "policy_current_law.json")
|
706
|
+
with open(path, "r", encoding="utf-8") as clpfile:
|
707
707
|
clpdict = json.load(clpfile)
|
708
708
|
clpdict.pop("schema", None)
|
709
709
|
# ... make sure ever clpdict section title is in valid_dict
|
@@ -711,9 +711,9 @@ def test_section_titles(tests_path):
|
|
711
711
|
for pname in clpdict:
|
712
712
|
param = clpdict[pname]
|
713
713
|
assert isinstance(param, dict)
|
714
|
-
sec1title = param[
|
714
|
+
sec1title = param["section_1"]
|
715
715
|
assert sec1title in valid_dict
|
716
|
-
sec2title = param[
|
716
|
+
sec2title = param["section_2"]
|
717
717
|
assert sec2title in valid_dict[sec1title]
|
718
718
|
if sec1title not in clp_dict:
|
719
719
|
clp_dict[sec1title] = {}
|
@@ -726,9 +726,9 @@ def test_section_titles(tests_path):
|
|
726
726
|
for sec2title in secdict:
|
727
727
|
assert sec2title in clp_dict[sec1title]
|
728
728
|
# check validity of parameter section titles in docs/uguide.htmx skeleton
|
729
|
-
path = os.path.join(tests_path,
|
730
|
-
|
731
|
-
with open(path,
|
729
|
+
path = os.path.join(tests_path, "..", "..", "docs", "guide",
|
730
|
+
"policy_params.md")
|
731
|
+
with open(path, "r", encoding="utf-8") as md_file:
|
732
732
|
md_text = md_file.read()
|
733
733
|
md_dict = generate_section_dictionary(md_text)
|
734
734
|
# ... make sure every md_dict section title is in valid_dict
|
@@ -750,17 +750,17 @@ def test_description_punctuation(tests_path):
|
|
750
750
|
Check that each description ends in a period.
|
751
751
|
"""
|
752
752
|
# read JSON file into a dictionary
|
753
|
-
path = os.path.join(tests_path,
|
754
|
-
with open(path,
|
753
|
+
path = os.path.join(tests_path, "..", "policy_current_law.json")
|
754
|
+
with open(path, "r", encoding="utf-8") as jsonfile:
|
755
755
|
dct = json.load(jsonfile)
|
756
756
|
dct.pop("schema", None)
|
757
757
|
all_desc_ok = True
|
758
758
|
for param in dct.keys():
|
759
|
-
if not dct[param][
|
759
|
+
if not dct[param]["description"].endswith("."):
|
760
760
|
all_desc_ok = False
|
761
|
-
print(
|
761
|
+
print("param,description=",
|
762
762
|
str(param),
|
763
|
-
dct[param][
|
763
|
+
dct[param]["description"])
|
764
764
|
assert all_desc_ok
|
765
765
|
|
766
766
|
|
@@ -769,8 +769,8 @@ def test_get_index_rate():
|
|
769
769
|
Test Parameters.get_index_rate.
|
770
770
|
"""
|
771
771
|
pol = Policy()
|
772
|
-
wgrates = pol.get_index_rate(
|
773
|
-
pirates = pol.get_index_rate(
|
772
|
+
wgrates = pol.get_index_rate("SS_Earnings_c", 2017)
|
773
|
+
pirates = pol.get_index_rate("II_em", 2017)
|
774
774
|
assert isinstance(wgrates, np.float64)
|
775
775
|
assert wgrates == pol.wage_growth_rates(2017)
|
776
776
|
assert pirates == pol.inflation_rates(2017)
|
@@ -784,11 +784,11 @@ def test_reform_with_removed_parameter(monkeypatch):
|
|
784
784
|
Try to use removed parameter in a reform.
|
785
785
|
"""
|
786
786
|
policy1 = Policy()
|
787
|
-
reform1 = {
|
787
|
+
reform1 = {"FilerCredit_c": {2020: 1000}}
|
788
788
|
with pytest.raises(paramtools.ValidationError):
|
789
789
|
policy1.implement_reform(reform1)
|
790
790
|
policy2 = Policy()
|
791
|
-
reform2 = {
|
791
|
+
reform2 = {"FilerCredit_c-indexed": {2020: True}}
|
792
792
|
with pytest.raises(paramtools.ValidationError):
|
793
793
|
policy2.implement_reform(reform2)
|
794
794
|
|
@@ -805,7 +805,7 @@ def test_reform_with_out_of_range_error():
|
|
805
805
|
Try to use out-of-range values versus other parameter values in a reform.
|
806
806
|
"""
|
807
807
|
pol = Policy()
|
808
|
-
reform = {
|
808
|
+
reform = {"SS_thd2": {2020: [20000, 20000, 20000, 20000, 20000]}}
|
809
809
|
pol.implement_reform(reform, raise_errors=False)
|
810
810
|
assert pol.parameter_errors
|
811
811
|
|
@@ -815,12 +815,12 @@ def test_reform_with_warning():
|
|
815
815
|
Try to use warned out-of-range parameter value in reform.
|
816
816
|
"""
|
817
817
|
exp_warnings = {
|
818
|
-
|
819
|
-
|
818
|
+
"ID_Medical_frt": [
|
819
|
+
"ID_Medical_frt[year=2020] 0.05 < min 0.075 "
|
820
820
|
]
|
821
821
|
}
|
822
822
|
pol = Policy()
|
823
|
-
reform = {
|
823
|
+
reform = {"ID_Medical_frt": {2020: 0.05}}
|
824
824
|
|
825
825
|
pol.implement_reform(reform, print_warnings=True)
|
826
826
|
assert pol.warnings == exp_warnings
|
@@ -838,17 +838,17 @@ def test_reform_with_scalar_vector_errors():
|
|
838
838
|
Test catching scalar-vector confusion.
|
839
839
|
"""
|
840
840
|
policy1 = Policy()
|
841
|
-
reform1 = {
|
841
|
+
reform1 = {"SS_thd2": {2020: 30000}}
|
842
842
|
with pytest.raises(paramtools.ValidationError):
|
843
843
|
policy1.implement_reform(reform1)
|
844
844
|
|
845
845
|
policy2 = Policy()
|
846
|
-
reform2 = {
|
846
|
+
reform2 = {"ID_Medical_frt": {2020: [0.08]}}
|
847
847
|
with pytest.raises(paramtools.ValidationError):
|
848
848
|
policy2.implement_reform(reform2)
|
849
849
|
|
850
850
|
policy3 = Policy()
|
851
|
-
reform3 = {
|
851
|
+
reform3 = {"ID_Medical_frt": [{"year": 2020, "value": [0.08]}]}
|
852
852
|
with pytest.raises(paramtools.ValidationError):
|
853
853
|
policy3.adjust(reform3)
|
854
854
|
|
@@ -867,20 +867,20 @@ def test_reform_with_scalar_vector_errors():
|
|
867
867
|
def test_index_offset_reform():
|
868
868
|
"""
|
869
869
|
Test a reform that includes both a change in parameter_indexing_CPI_offset
|
870
|
-
and a change in a variable
|
870
|
+
and a change in a variable"s indexed status in the same year.
|
871
871
|
"""
|
872
872
|
# create policy0 to extract inflation rates before any
|
873
873
|
# parameter_indexing_CPI_offset
|
874
874
|
policy0 = Policy()
|
875
|
-
policy0.implement_reform({
|
875
|
+
policy0.implement_reform({"parameter_indexing_CPI_offset": {2017: 0}})
|
876
876
|
cpiu_rates = policy0.inflation_rates()
|
877
877
|
|
878
|
-
reform1 = {
|
878
|
+
reform1 = {"ODC_c-indexed": {2020: True}}
|
879
879
|
policy1 = Policy()
|
880
880
|
policy1.implement_reform(reform1)
|
881
881
|
offset = -0.005
|
882
|
-
reform2 = {
|
883
|
-
|
882
|
+
reform2 = {"ODC_c-indexed": {2020: True},
|
883
|
+
"parameter_indexing_CPI_offset": {2020: offset}}
|
884
884
|
policy2 = Policy()
|
885
885
|
policy2.implement_reform(reform2)
|
886
886
|
# extract from policy1 and policy2 the parameter values of ODC_c
|
@@ -911,8 +911,8 @@ def test_cpi_offset_affect_on_prior_years():
|
|
911
911
|
Test that parameter_indexing_CPI_offset does not have affect
|
912
912
|
on inflation rates in earlier years.
|
913
913
|
"""
|
914
|
-
reform1 = {
|
915
|
-
reform2 = {
|
914
|
+
reform1 = {"parameter_indexing_CPI_offset": {2022: 0}}
|
915
|
+
reform2 = {"parameter_indexing_CPI_offset": {2022: -0.005}}
|
916
916
|
p1 = Policy()
|
917
917
|
p2 = Policy()
|
918
918
|
p1.implement_reform(reform1)
|
@@ -940,11 +940,11 @@ def test_cpi_offset_on_reverting_params():
|
|
940
940
|
Test that params that revert to their pre-TCJA values
|
941
941
|
in 2026 revert if a parameter_indexing_CPI_offset is specified.
|
942
942
|
"""
|
943
|
-
reform0 = {
|
944
|
-
reform1 = {
|
945
|
-
|
946
|
-
reform2 = {
|
947
|
-
|
943
|
+
reform0 = {"parameter_indexing_CPI_offset": {2020: -0.001}}
|
944
|
+
reform1 = {"STD": {2017: [6350, 12700, 6350, 9350, 12700]},
|
945
|
+
"parameter_indexing_CPI_offset": {2020: -0.001}}
|
946
|
+
reform2 = {"STD": {2020: [10000, 20000, 10000, 10000, 20000]},
|
947
|
+
"parameter_indexing_CPI_offset": {2020: -0.001}}
|
948
948
|
|
949
949
|
p0 = Policy()
|
950
950
|
p1 = Policy()
|
@@ -1221,7 +1221,7 @@ def test_apply_cpi_offset():
|
|
1221
1221
|
|
1222
1222
|
def test_multiple_cpi_swaps():
|
1223
1223
|
"""
|
1224
|
-
Test changing a parameter
|
1224
|
+
Test changing a parameter"s indexed status multiple times.
|
1225
1225
|
"""
|
1226
1226
|
pol1 = Policy()
|
1227
1227
|
pol1.implement_reform(
|
@@ -1499,8 +1499,8 @@ def test_ext_plus_odc1_reform(tests_path):
|
|
1499
1499
|
"""
|
1500
1500
|
# specify baseline policy, bas, as the extend-TCJA reform
|
1501
1501
|
bas = Policy()
|
1502
|
-
filename = os.path.join(tests_path,
|
1503
|
-
with open(filename,
|
1502
|
+
filename = os.path.join(tests_path, "..", "reforms", "ext.json")
|
1503
|
+
with open(filename, "r", encoding="utf-8") as rfile:
|
1504
1504
|
ext_text = rfile.read()
|
1505
1505
|
bas.implement_reform(Policy.read_json_reform(ext_text))
|
1506
1506
|
assert not bas.parameter_errors
|
@@ -1509,13 +1509,13 @@ def test_ext_plus_odc1_reform(tests_path):
|
|
1509
1509
|
ref.implement_reform(Policy.read_json_reform(ext_text))
|
1510
1510
|
odc1_reform = {
|
1511
1511
|
# one possible other-dependent-credit revision to extend-TCJA reform
|
1512
|
-
|
1512
|
+
"ODC_c": {
|
1513
1513
|
2026: 1000.00,
|
1514
1514
|
2027: 1000.00,
|
1515
1515
|
2028: 1000.00,
|
1516
1516
|
2029: 1000.00,
|
1517
1517
|
},
|
1518
|
-
|
1518
|
+
"ODC_c-indexed": {2029: True},
|
1519
1519
|
}
|
1520
1520
|
ref.implement_reform(odc1_reform)
|
1521
1521
|
assert not ref.parameter_errors
|
@@ -1559,8 +1559,8 @@ def test_ext_plus_odc2_reform(tests_path):
|
|
1559
1559
|
"""
|
1560
1560
|
# specify baseline policy, bas, as the extend-TCJA reform
|
1561
1561
|
bas = Policy()
|
1562
|
-
filename = os.path.join(tests_path,
|
1563
|
-
with open(filename,
|
1562
|
+
filename = os.path.join(tests_path, "..", "reforms", "ext.json")
|
1563
|
+
with open(filename, "r", encoding="utf-8") as rfile:
|
1564
1564
|
ext_text = rfile.read()
|
1565
1565
|
bas.implement_reform(Policy.read_json_reform(ext_text))
|
1566
1566
|
assert not bas.parameter_errors
|
@@ -1569,15 +1569,15 @@ def test_ext_plus_odc2_reform(tests_path):
|
|
1569
1569
|
ref.implement_reform(Policy.read_json_reform(ext_text))
|
1570
1570
|
odc2_reform = {
|
1571
1571
|
# one possible other-dependent-credit revision to extend-TCJA reform
|
1572
|
-
|
1572
|
+
"ODC_c": {
|
1573
1573
|
2026: 600.00,
|
1574
1574
|
2027: 600.00,
|
1575
1575
|
2028: 600.00,
|
1576
1576
|
2029: 800.00,
|
1577
1577
|
},
|
1578
|
-
|
1579
|
-
|
1580
|
-
|
1578
|
+
"ODC_c-indexed": {2029: True},
|
1579
|
+
"ACTC_c": {2029: 1750},
|
1580
|
+
"ACTC_c-indexed": {2029: False},
|
1581
1581
|
}
|
1582
1582
|
ref.implement_reform(odc2_reform)
|
1583
1583
|
assert not ref.parameter_errors
|