taxcalc 5.2.0__py3-none-any.whl → 5.3.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.
Files changed (42) hide show
  1. taxcalc/__init__.py +3 -3
  2. taxcalc/calcfunctions.py +2 -2
  3. taxcalc/calculator.py +3 -3
  4. taxcalc/cli/tc.py +15 -11
  5. taxcalc/data.py +1 -1
  6. taxcalc/decorators.py +9 -8
  7. taxcalc/growfactors.py +2 -1
  8. taxcalc/policy.py +6 -5
  9. taxcalc/policy_current_law.json +31 -631
  10. taxcalc/puf_ratios.csv +24 -24
  11. taxcalc/puf_weights.csv.gz +0 -0
  12. taxcalc/reforms/ARPA.out.csv +9 -9
  13. taxcalc/taxcalcio.py +41 -26
  14. taxcalc/tests/conftest.py +1 -1
  15. taxcalc/tests/puf_var_correl_coeffs_2016.csv +24 -24
  16. taxcalc/tests/puf_var_wght_means_by_year.csv +11 -11
  17. taxcalc/tests/pufcsv_agg_expect.csv +20 -20
  18. taxcalc/tests/pufcsv_mtr_expect.txt +21 -21
  19. taxcalc/tests/reforms.json +3 -1
  20. taxcalc/tests/reforms_expect.csv +48 -48
  21. taxcalc/tests/test_4package.py +8 -9
  22. taxcalc/tests/test_calculator.py +151 -151
  23. taxcalc/tests/test_compare.py +2 -2
  24. taxcalc/tests/test_consumption.py +2 -2
  25. taxcalc/tests/test_cpscsv.py +2 -2
  26. taxcalc/tests/test_decorators.py +57 -52
  27. taxcalc/tests/test_growdiff.py +2 -2
  28. taxcalc/tests/test_parameters.py +59 -53
  29. taxcalc/tests/test_policy.py +154 -154
  30. taxcalc/tests/test_puf_var_stats.py +1 -1
  31. taxcalc/tests/test_pufcsv.py +3 -3
  32. taxcalc/tests/test_records.py +5 -1
  33. taxcalc/tests/test_reforms.py +101 -99
  34. taxcalc/tests/test_taxcalcio.py +10 -4
  35. taxcalc/utils.py +3 -3
  36. {taxcalc-5.2.0.dist-info → taxcalc-5.3.0.dist-info}/METADATA +3 -6
  37. {taxcalc-5.2.0.dist-info → taxcalc-5.3.0.dist-info}/RECORD +41 -42
  38. taxcalc/reforms/clp.out.csv +0 -10
  39. {taxcalc-5.2.0.dist-info → taxcalc-5.3.0.dist-info}/WHEEL +0 -0
  40. {taxcalc-5.2.0.dist-info → taxcalc-5.3.0.dist-info}/entry_points.txt +0 -0
  41. {taxcalc-5.2.0.dist-info → taxcalc-5.3.0.dist-info}/licenses/LICENSE +0 -0
  42. {taxcalc-5.2.0.dist-info → taxcalc-5.3.0.dist-info}/top_level.txt +0 -0
@@ -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: {'II_em': 99000}})
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: {'II_em': 99000}})
60
+ pol.implement_reform({2018: {"II_em": 99000}})
61
61
  with pytest.raises(paramtools.ValidationError):
62
- pol.implement_reform({2020: {'II_em': -1000}})
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 = ('https://raw.githubusercontent.com/PSLmodels/'
94
- 'Tax-Calculator/master/taxcalc/reforms/ptaxes0.json')
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
- 'II_em': {(ryr - 3): 1000, # to avoid divide-by-zero under TCJA
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
- 'II_em': {2018: 1000, # to avoid divide-by-zero under TCJA
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
- 'SS_Earnings_c': {2016: 300000,
261
+ "SS_Earnings_c": {2016: 300000,
262
262
  2017: 500000,
263
263
  2019: 700000},
264
- 'SS_Earnings_c-indexed': {2017: False,
264
+ "SS_Earnings_c-indexed": {2017: False,
265
265
  2019: True},
266
- 'EITC_c': {2016: [900, 5000, 8000, 9000],
266
+ "EITC_c": {2016: [900, 5000, 8000, 9000],
267
267
  2019: [1200, 7000, 10000, 12000]},
268
- 'II_em': {2016: 7000,
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, '_EITC_c')
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['EITC_c'][2016]
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['EITC_c'][2019]
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, '_II_em')
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['II_em'][2016]
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['II_em'][2019]
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, '_SS_Earnings_c')
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['SS_Earnings_c'][2016]
358
+ e2016 = reform["SS_Earnings_c"][2016]
359
359
  assert actual[2016] == e2016
360
- e2017 = reform['SS_Earnings_c'][2017]
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['SS_Earnings_c'][2019]
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 = {'STD_Aged': [1400, 1200, 1400, 1400, 1400]}
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 = {'STD_Aged': {2010: [1400, 1100, 1100, 1400, 1400]}}
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 = {'II_em': {2015: 4300}}
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 = {'II_em': {2015: 4400}, 'II_em-indexed': {2015: True}}
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 = {'SS_Earnings_c': {2016: 9e99}}
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
- 'SS_Earnings_c': {2015: 500000},
539
- 'SS_Earnings_c-indexed': {2015: False}
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
- 'SS_Earnings_c-indexed': {2015: False},
544
- 'SS_Earnings_c': {2015: 500000}
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 = {'II_em': {2019: 1000, 2020: 2000}}
575
+ reform1 = {"II_em": {2019: 1000, 2020: 2000}}
576
576
  # pylint: disable=duplicate-key
577
- reform2 = {'II_em': {2019: 1000}, 'II_em': {2020: 2000}}
577
+ reform2 = {"II_em": {2019: 1000}, "II_em": {2020: 2000}}
578
578
  # these two reform dictionaries are not the same: the second
579
- # 'II_em' key value for 2020 in reform2 OVERWRITES and REPLACES
580
- # the first 'II_em' key value for 2019 in reform2
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('## Other Parameters (not in Tax-Brain webapp'):
600
- sdict[''] = {}
601
- sdict[''][''] = 0
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('##', '', 1).strip()
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('###', '', 1).strip()
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 = ('Tax All Capital Gains And Dividends The Same '
618
- 'As Regular Taxable Income')
617
+ cgqd_tax_same = ("Tax All Capital Gains And Dividends The Same "
618
+ "As Regular Taxable Income")
619
619
  valid_dict = {
620
- '': { # empty section_1 implies parameter not displayed in Tax-Brain
621
- '': 0
620
+ "": { # empty section_1 implies parameter not displayed in Tax-Brain
621
+ "": 0
622
622
  },
623
- 'Parameter Indexing': {
624
- 'Offsets': 0
623
+ "Parameter Indexing": {
624
+ "Offsets": 0
625
625
  },
626
- 'Payroll Taxes': {
627
- 'Social Security FICA': 0,
628
- 'Medicare FICA': 0,
629
- 'Additional Medicare FICA': 0
626
+ "Payroll Taxes": {
627
+ "Social Security FICA": 0,
628
+ "Medicare FICA": 0,
629
+ "Additional Medicare FICA": 0
630
630
  },
631
- 'Social Security Taxability': {
632
- 'Social Security Benefit Taxability': 0,
631
+ "Social Security Taxability": {
632
+ "Social Security Benefit Taxability": 0,
633
633
  },
634
- 'Above The Line Deductions': {
635
- 'Misc. Adjustment Haircuts': 0,
636
- 'Misc. Exclusions': 0,
637
- 'Child And Elderly Care': 0
634
+ "Above The Line Deductions": {
635
+ "Misc. Adjustment Haircuts": 0,
636
+ "Misc. Exclusions": 0,
637
+ "Child And Elderly Care": 0
638
638
  },
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
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
- 'Standard Deduction': {
646
- 'Standard Deduction Amount': 0,
647
- 'Additional Standard Deduction For Blind And Aged': 0
648
- # 'Standard Deduction For Dependents': 0
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
- 'Nonrefundable Credits': {
651
- 'Misc. Credit Limits': 0,
652
- 'Child And Dependent Care': 0,
653
- 'Personal Nonrefundable Credit': 0
650
+ "Nonrefundable Credits": {
651
+ "Misc. Credit Limits": 0,
652
+ "Child And Dependent Care": 0,
653
+ "Personal Nonrefundable Credit": 0
654
654
  },
655
- 'Child/Dependent Credits': {
656
- 'Child Tax Credit': 0,
657
- 'Additional Child Tax Credit': 0,
658
- 'Other Dependent Tax Credit': 0
655
+ "Child/Dependent Credits": {
656
+ "Child Tax Credit": 0,
657
+ "Additional Child Tax Credit": 0,
658
+ "Other Dependent Tax Credit": 0
659
659
  },
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
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
- 'Capital Gains And Dividends': {
673
- 'Regular - Long Term Capital Gains And Qualified Dividends': 0,
674
- 'AMT - Long Term Capital Gains And Qualified Dividends': 0,
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
- 'Personal Income': {
678
- 'Regular: Non-AMT': 0,
679
- 'Pass-Through': 0,
680
- 'Alternative Minimum Tax': 0
677
+ "Personal Income": {
678
+ "Regular: Non-AMT": 0,
679
+ "Pass-Through": 0,
680
+ "Alternative Minimum Tax": 0
681
681
  },
682
- 'Other Taxes': {
683
- 'Net Investment Income Tax': 0
682
+ "Other Taxes": {
683
+ "Net Investment Income Tax": 0
684
684
  },
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
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
- 'Surtaxes': {
692
- 'New Minimum Tax': 0,
693
- 'New AGI Surtax': 0,
694
- 'Lump-Sum Tax': 0
691
+ "Surtaxes": {
692
+ "New Minimum Tax": 0,
693
+ "New AGI Surtax": 0,
694
+ "Lump-Sum Tax": 0
695
695
  },
696
- 'Universal Basic Income': {
697
- 'UBI Benefits': 0,
698
- 'UBI Taxability': 0
696
+ "Universal Basic Income": {
697
+ "UBI Benefits": 0,
698
+ "UBI Taxability": 0
699
699
  },
700
- 'Benefits': {
701
- 'Benefit Repeal': 0,
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, '..', 'policy_current_law.json')
706
- with open(path, 'r', encoding='utf-8') as clpfile:
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['section_1']
714
+ sec1title = param["section_1"]
715
715
  assert sec1title in valid_dict
716
- sec2title = param['section_2']
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, '..', '..', 'docs', 'guide',
730
- 'policy_params.md')
731
- with open(path, 'r', encoding='utf-8') as md_file:
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, '..', 'policy_current_law.json')
754
- with open(path, 'r', encoding='utf-8') as jsonfile:
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]['description'].endswith('.'):
759
+ if not dct[param]["description"].endswith("."):
760
760
  all_desc_ok = False
761
- print('param,description=',
761
+ print("param,description=",
762
762
  str(param),
763
- dct[param]['description'])
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('SS_Earnings_c', 2017)
773
- pirates = pol.get_index_rate('II_em', 2017)
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 = {'FilerCredit_c': {2020: 1000}}
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 = {'FilerCredit_c-indexed': {2020: True}}
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 = {'SS_thd2': {2020: [20000, 20000, 20000, 20000, 20000]}}
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
- 'ID_Medical_frt': [
819
- 'ID_Medical_frt[year=2020] 0.05 < min 0.075 '
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 = {'ID_Medical_frt': {2020: 0.05}}
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 = {'SS_thd2': {2020: 30000}}
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 = {'ID_Medical_frt': {2020: [0.08]}}
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 = {'ID_Medical_frt': [{"year": 2020, "value": [0.08]}]}
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's indexed status in the same year.
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({'parameter_indexing_CPI_offset': {2017: 0}})
875
+ policy0.implement_reform({"parameter_indexing_CPI_offset": {2017: 0}})
876
876
  cpiu_rates = policy0.inflation_rates()
877
877
 
878
- reform1 = {'ODC_c-indexed': {2020: True}}
878
+ reform1 = {"ODC_c-indexed": {2020: True}}
879
879
  policy1 = Policy()
880
880
  policy1.implement_reform(reform1)
881
881
  offset = -0.005
882
- reform2 = {'ODC_c-indexed': {2020: True},
883
- 'parameter_indexing_CPI_offset': {2020: offset}}
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 = {'parameter_indexing_CPI_offset': {2022: 0}}
915
- reform2 = {'parameter_indexing_CPI_offset': {2022: -0.005}}
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 = {'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}}
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's indexed status multiple times.
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, '..', 'reforms', 'ext.json')
1503
- with open(filename, 'r', encoding='utf-8') as rfile:
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
- 'ODC_c': {
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
- 'ODC_c-indexed': {2029: True},
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, '..', 'reforms', 'ext.json')
1563
- with open(filename, 'r', encoding='utf-8') as rfile:
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
- 'ODC_c': {
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
- 'ODC_c-indexed': {2029: True},
1579
- 'ACTC_c': {2029: 1750},
1580
- 'ACTC_c-indexed': {2029: False},
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
@@ -66,7 +66,7 @@ def create_base_table(test_path):
66
66
  # create table_dict with sorted read vars followed by sorted calc vars
67
67
  table_dict = {}
68
68
  for var in sorted(read_vars):
69
- if "taxdata_puf" in read_var_dict['read'][var]['availability']:
69
+ if 'taxdata_puf' in read_var_dict['read'][var]['availability']:
70
70
  table_dict[var] = read_var_dict['read'][var]['desc']
71
71
  else:
72
72
  pass