taxcalc 4.3.5__py3-none-any.whl → 4.4.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.
Files changed (47) hide show
  1. taxcalc/__init__.py +1 -1
  2. taxcalc/calcfunctions.py +326 -171
  3. taxcalc/calculator.py +35 -34
  4. taxcalc/cli/tc.py +6 -7
  5. taxcalc/consumption.py +14 -9
  6. taxcalc/data.py +8 -8
  7. taxcalc/decorators.py +3 -3
  8. taxcalc/growdiff.py +6 -6
  9. taxcalc/growfactors.py +1 -1
  10. taxcalc/parameters.py +91 -47
  11. taxcalc/policy.py +23 -7
  12. taxcalc/records.py +1 -0
  13. taxcalc/records_variables.json +6 -0
  14. taxcalc/reforms/ext.json +1 -1
  15. taxcalc/taxcalcio.py +88 -73
  16. taxcalc/tests/cmpi_cps_expect.txt +6 -6
  17. taxcalc/tests/cmpi_puf_expect.txt +6 -6
  18. taxcalc/tests/conftest.py +42 -41
  19. taxcalc/tests/test_4package.py +47 -3
  20. taxcalc/tests/test_benefits.py +9 -8
  21. taxcalc/tests/test_calcfunctions.py +55 -38
  22. taxcalc/tests/test_calculator.py +14 -10
  23. taxcalc/tests/test_compare.py +44 -50
  24. taxcalc/tests/test_compatible_data.py +9 -7
  25. taxcalc/tests/test_consumption.py +41 -22
  26. taxcalc/tests/test_cpscsv.py +81 -31
  27. taxcalc/tests/test_data.py +31 -24
  28. taxcalc/tests/test_decorators.py +84 -32
  29. taxcalc/tests/test_growdiff.py +20 -19
  30. taxcalc/tests/test_growfactors.py +8 -8
  31. taxcalc/tests/test_parameters.py +54 -58
  32. taxcalc/tests/test_policy.py +16 -14
  33. taxcalc/tests/test_puf_var_stats.py +14 -14
  34. taxcalc/tests/test_pufcsv.py +40 -40
  35. taxcalc/tests/test_records.py +73 -60
  36. taxcalc/tests/test_reforms.py +34 -31
  37. taxcalc/tests/test_responses.py +4 -4
  38. taxcalc/tests/test_taxcalcio.py +76 -62
  39. taxcalc/tests/test_utils.py +78 -46
  40. taxcalc/utils.py +49 -42
  41. taxcalc/validation/taxsim35/taxsim_emulation.json +1 -5
  42. {taxcalc-4.3.5.dist-info → taxcalc-4.4.1.dist-info}/METADATA +23 -11
  43. {taxcalc-4.3.5.dist-info → taxcalc-4.4.1.dist-info}/RECORD +47 -47
  44. {taxcalc-4.3.5.dist-info → taxcalc-4.4.1.dist-info}/WHEEL +1 -1
  45. {taxcalc-4.3.5.dist-info → taxcalc-4.4.1.dist-info}/LICENSE +0 -0
  46. {taxcalc-4.3.5.dist-info → taxcalc-4.4.1.dist-info}/entry_points.txt +0 -0
  47. {taxcalc-4.3.5.dist-info → taxcalc-4.4.1.dist-info}/top_level.txt +0 -0
taxcalc/parameters.py CHANGED
@@ -1,13 +1,14 @@
1
+ """
2
+ Tax-Calculator abstract base parameter class based on paramtools package.
3
+ """
4
+
1
5
  import os
2
6
  import copy
3
7
  from collections import defaultdict
4
8
  from typing import Union, Mapping, Any, List
5
-
9
+ import numpy as np
6
10
  import marshmallow as ma
7
11
  import paramtools as pt
8
- import numpy as np
9
-
10
- from taxcalc.growfactors import GrowFactors
11
12
 
12
13
 
13
14
  class CompatibleDataSchema(ma.Schema):
@@ -64,8 +65,8 @@ class Parameters(pt.Parameters):
64
65
  Check out the ParamTools
65
66
  `documentation <https://paramtools.dev/api/reference.html>`_
66
67
  for more information on these inherited methods.
67
-
68
68
  """
69
+ # pylint: disable=too-many-instance-attributes
69
70
  defaults = None
70
71
  array_first = True
71
72
  label_to_extend = "year"
@@ -83,6 +84,8 @@ class Parameters(pt.Parameters):
83
84
 
84
85
  def __init__(self, start_year=None, num_years=None, last_known_year=None,
85
86
  removed=None, redefined=None, wage_indexed=None, **kwargs):
87
+ # pylint: disable=too-many-arguments,too-many-positional-arguments
88
+
86
89
  # In case we need to wait for this to be called from the
87
90
  # initialize method for legacy reasons.
88
91
  if not start_year or not num_years:
@@ -98,19 +101,16 @@ class Parameters(pt.Parameters):
98
101
  self.DEFAULTS_FILE_PATH,
99
102
  self.DEFAULTS_FILE_NAME
100
103
  )
101
-
104
+ last_budget_year = start_year + num_years - 1
102
105
  if last_known_year is None:
103
106
  self._last_known_year = start_year
104
107
  else:
105
108
  assert last_known_year >= start_year
106
- assert last_known_year <= self.LAST_BUDGET_YEAR
109
+ assert last_known_year <= last_budget_year
107
110
  self._last_known_year = last_known_year
108
-
109
111
  self._removed_params = removed or self.REMOVED_PARAMS
110
112
  self._redefined_params = redefined or self.REDEFINED_PARAMS
111
-
112
113
  self._wage_indexed = wage_indexed or self.WAGE_INDEXED_PARAMS
113
-
114
114
  if (
115
115
  (start_year or self.JSON_START_YEAR) and
116
116
  "initial_state" not in kwargs
@@ -118,10 +118,18 @@ class Parameters(pt.Parameters):
118
118
  kwargs["initial_state"] = {
119
119
  "year": start_year or self.JSON_START_YEAR
120
120
  }
121
+ # update defaults to correspond to user-defined parameter years
122
+ self.defaults = super().get_defaults()
123
+ label = self.defaults["schema"]["labels"]["year"]
124
+ label["validators"]["range"]["max"] = last_budget_year
121
125
  super().__init__(**kwargs)
122
126
 
123
- def adjust(
124
- self, params_or_path, print_warnings=True, raise_errors=True, **kwargs
127
+ def adjust( # pylint: disable=arguments-differ
128
+ # pylint warning W0221 is:
129
+ # Number of parameters was 6 in 'Parameters.adjust' and
130
+ # is now 5 in overriding 'Parameters.adjust' method
131
+ self, params_or_path,
132
+ print_warnings=True, raise_errors=True, **kwargs
125
133
  ):
126
134
  """
127
135
  Update parameter values using a ParamTools styled adjustment.
@@ -135,8 +143,10 @@ class Parameters(pt.Parameters):
135
143
 
136
144
  {
137
145
  "standard_deduction": [
138
- {"year": 2024, "marital_status": "single", "value": 10000.0},
139
- {"year": 2024, "marital_status": "joint", "value": 10000.0}
146
+ {"year": 2024, "marital_status": "single",
147
+ "value": 10000.0},
148
+ {"year": 2024, "marital_status": "joint",
149
+ "value": 10000.0}
140
150
  ],
141
151
  "ss_rate": [{"year": 2024, "value": 0.2}]}
142
152
  }
@@ -153,7 +163,7 @@ class Parameters(pt.Parameters):
153
163
  adjustment : Dict
154
164
  Parsed paremeter dictionary
155
165
 
156
- """ # noqa
166
+ """
157
167
  if print_warnings:
158
168
  _data = copy.deepcopy(self._data)
159
169
  kwargs["ignore_warnings"] = False
@@ -176,13 +186,15 @@ class Parameters(pt.Parameters):
176
186
  except pt.ValidationError as ve:
177
187
  if self.errors and raise_errors:
178
188
  raise ve
179
- elif self.errors and not raise_errors:
189
+ if self.errors and not raise_errors:
180
190
  return {}
181
191
  if print_warnings:
182
192
  print("WARNING:")
183
193
  print(self.warnings)
184
194
  kwargs["ignore_warnings"] = True
195
+ # pylint: disable=possibly-used-before-assignment
185
196
  self._data = _data
197
+ # pylint: enable=possibly-used-before-assignment
186
198
  _warnings = copy.deepcopy(self._warnings)
187
199
  self._warnings = {}
188
200
  self._errors = {}
@@ -241,6 +253,8 @@ class Parameters(pt.Parameters):
241
253
  wiped out after the year in which the value is adjusted for the
242
254
  same hard-coding reason.
243
255
  """
256
+ # pylint: disable=too-many-statements,too-many-locals,too-many-branches
257
+
244
258
  # Temporarily turn off extra ops during the intermediary adjustments
245
259
  # so that expensive and unnecessary operations are not run.
246
260
  label_to_extend = self.label_to_extend
@@ -309,7 +323,7 @@ class Parameters(pt.Parameters):
309
323
  self.delete(to_delete, **kwargs)
310
324
 
311
325
  # 1.b For all others, these are years after last_known_year.
312
- last_known_year = max(cpi_min_year["year"], self._last_known_year)
326
+ # last_known_year=max(cpi_min_year["year"],self._last_known_year)
313
327
  # calculate 2026 value, using new inflation rates, for parameters
314
328
  # that revert to their pre-TCJA values.
315
329
  long_params = ['II_brk7', 'II_brk6', 'II_brk5', 'II_brk4',
@@ -361,7 +375,15 @@ class Parameters(pt.Parameters):
361
375
  ):
362
376
  continue
363
377
  if self._data[param].get("indexed", False):
364
- to_delete[param] = self.sel[param]["_auto"] == True # noqa
378
+ # pylint: disable=singleton-comparison
379
+ to_delete[param] = self.sel[param]["_auto"] == True
380
+ # pylint warning message:
381
+ # Comparison 'self.sel[param]['_auto'] == True' should
382
+ # be 'self.sel[param]['_auto'] is True' if checking for
383
+ # the singleton value True, or
384
+ # 'bool(self.sel[param]['_auto'])' if testing for
385
+ # truthiness
386
+ # pylint: enable=singleton-comparison
365
387
  needs_reset.append(param)
366
388
 
367
389
  self.delete(to_delete, **kwargs)
@@ -404,13 +426,14 @@ class Parameters(pt.Parameters):
404
426
  min_index_change_year, strict=False
405
427
  )
406
428
 
407
- if len(list(vos)):
429
+ if list(vos):
408
430
  min_adj_year = min(vos, key=lambda vo: vo["year"])[
409
431
  "year"
410
432
  ]
411
433
  self.delete(
412
434
  {
413
- base_param: self.sel[base_param]["year"] > min_adj_year # noqa
435
+ base_param:
436
+ self.sel[base_param]["year"] > min_adj_year
414
437
  }
415
438
  )
416
439
  super().adjust({base_param: vos}, **kwargs)
@@ -481,40 +504,45 @@ class Parameters(pt.Parameters):
481
504
  )
482
505
  return adj
483
506
 
484
- def get_index_rate(self, param, label_to_extend_val):
507
+ def get_index_rate(self, param, lte_val):
485
508
  """
486
509
  Initalize indexing data and return the indexing rate value
487
- depending on the parameter name and label_to_extend_val, the value of
488
- label_to_extend.
510
+ depending on the parameter name and lte_val (that is, the
511
+ label_to_extend_val), the value of label_to_extend.
489
512
  Returns: rate to use for indexing.
490
513
  """
491
514
  if not self._inflation_rates or not self._wage_growth_rates:
492
515
  self.set_rates()
493
516
  if param in self._wage_indexed:
494
- return self.wage_growth_rates(year=label_to_extend_val)
495
- else:
496
- return self.inflation_rates(year=label_to_extend_val)
517
+ return self.wage_growth_rates(year=lte_val)
518
+ return self.inflation_rates(year=lte_val)
497
519
 
498
520
  def set_rates(self):
499
521
  """
500
- This method is implemented by classes inheriting
501
- Parameters.
522
+ This method is implemented by classes inheriting Parameters.
502
523
  """
503
524
  raise NotImplementedError()
504
525
 
505
526
  def wage_growth_rates(self, year=None):
527
+ """
528
+ Return wage growth rates used in parameter indexing.
529
+ """
506
530
  if year is not None:
507
531
  syr = max(self.start_year, self._gfactors.first_year)
508
532
  return self._wage_growth_rates[year - syr]
509
533
  return self._wage_growth_rates or []
510
534
 
511
535
  def inflation_rates(self, year=None):
536
+ """
537
+ Return price inflation rates used in parameter indexing.
538
+ """
512
539
  if year is not None:
513
540
  syr = max(self.start_year, self._gfactors.first_year)
514
541
  return self._inflation_rates[year - syr]
515
542
  return self._inflation_rates or []
516
543
 
517
- # alias methods below
544
+ # alias methods below:
545
+
518
546
  def initialize(self, start_year, num_years, last_known_year=None,
519
547
  removed=None, redefined=None, wage_indexed=None,
520
548
  **kwargs):
@@ -522,13 +550,15 @@ class Parameters(pt.Parameters):
522
550
  Legacy method for initializing a Parameters instance. Projects
523
551
  should use the __init__ method in the future.
524
552
  """
525
- # case where project hasn't been initialized yet.
553
+ # pylint: disable=too-many-arguments,too-many-positional-arguments
554
+ # Handle case where project hasn't been initialized yet
526
555
  if getattr(self, "_data", None) is None:
527
556
  return Parameters.__init__(
528
557
  self, start_year, num_years, last_known_year=last_known_year,
529
558
  removed=removed, redefined=redefined,
530
559
  wage_indexed=wage_indexed, **kwargs
531
560
  )
561
+ return None # pragma: no cover
532
562
 
533
563
  def _update(self, revision, print_warnings, raise_errors):
534
564
  """
@@ -552,13 +582,16 @@ class Parameters(pt.Parameters):
552
582
 
553
583
  {
554
584
  "standard_deduction": [
555
- {"year": 2024, "marital_status": "single", "value": 10000.0},
556
- {"year": 2024, "marital_status": "joint", "value": 10000.0}
585
+ {"year": 2024, "marital_status": "single",
586
+ "value": 10000.0},
587
+ {"year": 2024, "marital_status": "joint",
588
+ "value": 10000.0}
557
589
  ],
558
590
  "ss_rate": [{"year": 2024, "value": 0.2}]}
559
591
  }
560
592
 
561
- """ # noqa: E501
593
+ """
594
+ # pylint: disable=too-many-branches
562
595
  if not isinstance(revision, dict):
563
596
  raise pt.ValidationError(
564
597
  {"errors": {"schema": "Revision must be a dictionary."}},
@@ -650,30 +683,37 @@ class Parameters(pt.Parameters):
650
683
  )
651
684
 
652
685
  def set_year(self, year):
686
+ """Specify parameter year"""
653
687
  self.set_state(year=year)
654
688
 
655
689
  @property
656
690
  def current_year(self):
691
+ """Propery docstring"""
657
692
  return self.label_grid["year"][0]
658
693
 
659
694
  @property
660
695
  def start_year(self):
696
+ """Propery docstring"""
661
697
  return self._stateless_label_grid["year"][0]
662
698
 
663
699
  @property
664
700
  def end_year(self):
701
+ """Propery docstring"""
665
702
  return self._stateless_label_grid["year"][-1]
666
703
 
667
704
  @property
668
705
  def num_years(self):
706
+ """Propery docstring"""
669
707
  return self.end_year - self.start_year + 1
670
708
 
671
709
  @property
672
710
  def parameter_warnings(self):
711
+ """Propery docstring"""
673
712
  return self.errors or {}
674
713
 
675
714
  @property
676
715
  def parameter_errors(self):
716
+ """Propery docstring"""
677
717
  return self.errors or {}
678
718
 
679
719
  @staticmethod
@@ -697,14 +737,17 @@ class Parameters(pt.Parameters):
697
737
 
698
738
  Some examples of valid links are:
699
739
 
700
- - HTTP: ``https://raw.githubusercontent.com/PSLmodels/Tax-Calculator/master/taxcalc/reforms/2017_law.json``
740
+ - HTTP: ``https://raw.githubusercontent.com/PSLmodels/Tax-Calculator/
741
+ master/taxcalc/reforms/2017_law.json``
701
742
 
702
- - Github API: ``github://PSLmodels:Tax-Calculator@master/taxcalc/reforms/2017_law.json``
743
+ - Github API: ``github://PSLmodels:Tax-Calculator@master/taxcalc/
744
+ reforms/2017_law.json``
703
745
 
704
746
  Checkout the ParamTools
705
- `docs <https://paramtools.dev/_modules/paramtools/parameters.html#Parameters.read_params>`_
747
+ `docs <https://paramtools.dev/_modules/paramtools/
748
+ parameters.html#Parameters.read_params>`_
706
749
  for more information on valid file URLs.
707
- """ # noqa
750
+ """
708
751
  # embedded function used only in _read_json_revision staticmethod
709
752
  def convert_year_to_int(syr_dict):
710
753
  """
@@ -712,10 +755,10 @@ class Parameters(pt.Parameters):
712
755
  keys, into a dictionary with the same structure but having integer
713
756
  years as secondary keys.
714
757
  """
715
- iyr_dict = dict()
758
+ iyr_dict = {}
716
759
  for pkey, sdict in syr_dict.items():
717
760
  assert isinstance(pkey, str)
718
- iyr_dict[pkey] = dict()
761
+ iyr_dict[pkey] = {}
719
762
  assert isinstance(sdict, dict)
720
763
  for skey, val in sdict.items():
721
764
  assert isinstance(skey, str)
@@ -725,7 +768,7 @@ class Parameters(pt.Parameters):
725
768
  # end of embedded function
726
769
  # process the main function arguments
727
770
  if obj is None:
728
- return dict()
771
+ return {}
729
772
 
730
773
  full_dict = pt.read_json(obj)
731
774
 
@@ -742,6 +785,9 @@ class Parameters(pt.Parameters):
742
785
  return convert_year_to_int(single_dict)
743
786
 
744
787
  def metadata(self):
788
+ """
789
+ Return parameter specification.
790
+ """
745
791
  return self.specification(meta_data=True, use_state=False)
746
792
 
747
793
  @staticmethod
@@ -751,7 +797,7 @@ class Parameters(pt.Parameters):
751
797
  assumed to have a param:year:value format.
752
798
  """
753
799
  assert isinstance(revision, dict)
754
- years = list()
800
+ years = []
755
801
  for _, paramdata in revision.items():
756
802
  assert isinstance(paramdata, dict)
757
803
  for year, _ in paramdata.items():
@@ -773,8 +819,7 @@ class Parameters(pt.Parameters):
773
819
  return self.to_array(
774
820
  attr[1:], year=list(range(self.start_year, self.end_year + 1))
775
821
  )
776
- else:
777
- raise AttributeError(f"{attr} not definied.")
822
+ raise AttributeError(f"{attr} is not defined.")
778
823
 
779
824
 
780
825
  TaxcalcReform = Union[str, Mapping[int, Any]]
@@ -814,7 +859,6 @@ def is_paramtools_format(params: Union[TaxcalcReform, ParamToolsAdjustment]):
814
859
  for data in params.values():
815
860
  if isinstance(data, dict):
816
861
  return False # taxcalc reform
817
- else:
818
- # Not doing a specific check to see if the value is a list
819
- # since it could be a list or just a scalar value.
820
- return True
862
+ # Not doing a specific check to see if the value is a list
863
+ # since it could be a list or just a scalar value.
864
+ return True
taxcalc/policy.py CHANGED
@@ -24,6 +24,9 @@ class Policy(Parameters):
24
24
  gfactors: GrowFactors class instance
25
25
  containing price inflation rates and wage growth rates
26
26
 
27
+ last_budget_year: integer
28
+ user-defined last parameter extrapolation year
29
+
27
30
  Raises
28
31
  ------
29
32
  ValueError:
@@ -39,9 +42,16 @@ class Policy(Parameters):
39
42
  JSON_START_YEAR = 2013 # remains the same unless earlier data added
40
43
  LAST_KNOWN_YEAR = 2025 # last year for which indexed param vals are known
41
44
  # should increase LAST_KNOWN_YEAR by one every calendar year
42
- LAST_BUDGET_YEAR = 2034 # last extrapolation year
45
+ LAST_BUDGET_YEAR = 2034 # default value of last extrapolation year
43
46
  # should increase LAST_BUDGET_YEAR by one every calendar year
44
- DEFAULT_NUM_YEARS = LAST_BUDGET_YEAR - JSON_START_YEAR + 1
47
+
48
+ @staticmethod
49
+ def number_of_years(last_budget_year=LAST_BUDGET_YEAR):
50
+ """
51
+ Static method returns number of policy parameters years given
52
+ user-defined last_budget_year.
53
+ """
54
+ return last_budget_year - Policy.JSON_START_YEAR + 1
45
55
 
46
56
  # NOTE: the following three data structures use internal parameter names:
47
57
  # (1) specify which Policy parameters have been removed or renamed
@@ -80,7 +90,10 @@ class Policy(Parameters):
80
90
  # (3) specify which Policy parameters are wage (rather than price) indexed
81
91
  WAGE_INDEXED_PARAMS = ['SS_Earnings_c', 'SS_Earnings_thd']
82
92
 
83
- def __init__(self, gfactors=None, **kwargs):
93
+ def __init__(self,
94
+ gfactors=None,
95
+ last_budget_year=LAST_BUDGET_YEAR,
96
+ **kwargs):
84
97
  # put JSON contents of DEFAULTS_FILE_NAME into self._vals dictionary
85
98
  super().__init__()
86
99
  # handle gfactors argument
@@ -92,7 +105,7 @@ class Policy(Parameters):
92
105
  raise ValueError('gfactors is not None or a GrowFactors instance')
93
106
  # read default parameters and initialize
94
107
  syr = Policy.JSON_START_YEAR
95
- nyrs = Policy.DEFAULT_NUM_YEARS
108
+ nyrs = Policy.number_of_years(last_budget_year)
96
109
  self._inflation_rates = None
97
110
  self._wage_growth_rates = None
98
111
  self.initialize(syr, nyrs, Policy.LAST_KNOWN_YEAR,
@@ -101,7 +114,10 @@ class Policy(Parameters):
101
114
  Policy.WAGE_INDEXED_PARAMS, **kwargs)
102
115
 
103
116
  @staticmethod
104
- def tmd_constructor(growfactors: Path | GrowFactors): # pragma: no cover
117
+ def tmd_constructor(
118
+ growfactors: Path | GrowFactors,
119
+ last_budget_year=LAST_BUDGET_YEAR,
120
+ ): # pragma: no cover
105
121
  """
106
122
  Static method returns a Policy object instantiated with TMD
107
123
  input data. This convenience method works in a analogous way
@@ -112,7 +128,7 @@ class Policy(Parameters):
112
128
  growfactors = GrowFactors(growfactors_filename=str(growfactors))
113
129
  else:
114
130
  assert isinstance(growfactors, GrowFactors)
115
- return Policy(gfactors=growfactors)
131
+ return Policy(gfactors=growfactors, last_budget_year=last_budget_year)
116
132
 
117
133
  @staticmethod
118
134
  def read_json_reform(obj):
@@ -142,7 +158,7 @@ class Policy(Parameters):
142
158
  Policy.DEFAULTS_FILE_PATH,
143
159
  Policy.DEFAULTS_FILE_NAME
144
160
  )
145
- with open(path, 'r', encoding='utf-8') as f:
161
+ with open(path, 'r', encoding='utf-8') as f:
146
162
  defaults = json.loads(f.read()) # pylint: disable=protected-access
147
163
  return [k for k in defaults if k != "schema"]
148
164
 
taxcalc/records.py CHANGED
@@ -136,6 +136,7 @@ class Records(Data):
136
136
  adjust_ratios=PUF_RATIOS_FILENAME,
137
137
  exact_calculations=False,
138
138
  weights_scale=0.01):
139
+ # pylint: disable=too-many-positional-arguments
139
140
  # pylint: disable=no-member,too-many-branches
140
141
  if isinstance(weights, str):
141
142
  weights = os.path.join(Records.CODE_PATH, weights)
@@ -842,6 +842,12 @@
842
842
  "form": {"2013-2013": "1040 line 46 minus 1040 line 55",
843
843
  "2014-2016": "1040 line 47 minus 1040 line 56"}
844
844
  },
845
+ "c32800": {
846
+ "type": "float",
847
+ "desc": "Child and dependent care expenses capped by policy (not by earnings)",
848
+ "form": {"2013-2013": "1040 line 48",
849
+ "2014-2016": "1040 line 49"}
850
+ },
845
851
  "c07180": {
846
852
  "type": "float",
847
853
  "desc": "Nonrefundable credit for child and dependent care expenses from Form 2441",
taxcalc/reforms/ext.json CHANGED
@@ -1,5 +1,5 @@
1
1
  // REFORM TO EXTEND TEMPORARY TCJA PROVISIONS BEYOND 2025
2
- // USING TAX-CALCULATOR 4.3.5
2
+ // USING TAX-CALCULATOR 4.4.0
3
3
  // WITH 2025-to-2026 INDEXING FACTOR = 1.024900
4
4
  // AND 2028-to-2029 INDEXING FACTOR = 1.021800
5
5
  {