taxcalc 4.3.5__py3-none-any.whl → 4.4.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 +1 -1
- taxcalc/consumption.py +5 -5
- taxcalc/growdiff.py +5 -10
- taxcalc/parameters.py +7 -6
- taxcalc/policy.py +22 -6
- taxcalc/reforms/ext.json +1 -1
- taxcalc/taxcalcio.py +39 -29
- taxcalc/tests/test_4package.py +42 -0
- taxcalc/tests/test_calculator.py +3 -4
- taxcalc/tests/test_consumption.py +5 -6
- taxcalc/tests/test_cpscsv.py +49 -1
- taxcalc/tests/test_growdiff.py +5 -7
- taxcalc/tests/test_policy.py +2 -2
- {taxcalc-4.3.5.dist-info → taxcalc-4.4.0.dist-info}/METADATA +5 -7
- {taxcalc-4.3.5.dist-info → taxcalc-4.4.0.dist-info}/RECORD +19 -19
- {taxcalc-4.3.5.dist-info → taxcalc-4.4.0.dist-info}/LICENSE +0 -0
- {taxcalc-4.3.5.dist-info → taxcalc-4.4.0.dist-info}/WHEEL +0 -0
- {taxcalc-4.3.5.dist-info → taxcalc-4.4.0.dist-info}/entry_points.txt +0 -0
- {taxcalc-4.3.5.dist-info → taxcalc-4.4.0.dist-info}/top_level.txt +0 -0
taxcalc/__init__.py
CHANGED
taxcalc/consumption.py
CHANGED
@@ -20,7 +20,8 @@ class Consumption(Parameters):
|
|
20
20
|
|
21
21
|
Parameters
|
22
22
|
----------
|
23
|
-
|
23
|
+
last_budget_year: integer
|
24
|
+
user-defined last parameter extrapolation year
|
24
25
|
|
25
26
|
Returns
|
26
27
|
-------
|
@@ -28,14 +29,13 @@ class Consumption(Parameters):
|
|
28
29
|
"""
|
29
30
|
|
30
31
|
JSON_START_YEAR = Policy.JSON_START_YEAR
|
31
|
-
DEFAULT_NUM_YEARS = Policy.DEFAULT_NUM_YEARS
|
32
32
|
DEFAULTS_FILE_NAME = 'consumption.json'
|
33
33
|
DEFAULTS_FILE_PATH = os.path.abspath(os.path.dirname(__file__))
|
34
34
|
|
35
|
-
def __init__(self):
|
35
|
+
def __init__(self, last_budget_year=Policy.LAST_BUDGET_YEAR):
|
36
36
|
super().__init__()
|
37
|
-
|
38
|
-
|
37
|
+
nyrs = Policy.number_of_years(last_budget_year)
|
38
|
+
self.initialize(Consumption.JSON_START_YEAR, nyrs)
|
39
39
|
|
40
40
|
@staticmethod
|
41
41
|
def read_json_update(obj):
|
taxcalc/growdiff.py
CHANGED
@@ -20,7 +20,8 @@ class GrowDiff(Parameters):
|
|
20
20
|
|
21
21
|
Parameters
|
22
22
|
----------
|
23
|
-
|
23
|
+
last_budget_year: integer
|
24
|
+
user-defined last parameter extrapolation year
|
24
25
|
|
25
26
|
Returns
|
26
27
|
-------
|
@@ -28,14 +29,13 @@ class GrowDiff(Parameters):
|
|
28
29
|
"""
|
29
30
|
|
30
31
|
JSON_START_YEAR = Policy.JSON_START_YEAR
|
31
|
-
DEFAULT_NUM_YEARS = Policy.DEFAULT_NUM_YEARS
|
32
32
|
DEFAULTS_FILE_NAME = 'growdiff.json'
|
33
33
|
DEFAULTS_FILE_PATH = os.path.abspath(os.path.dirname(__file__))
|
34
34
|
|
35
|
-
def __init__(self):
|
35
|
+
def __init__(self, last_budget_year=Policy.LAST_BUDGET_YEAR):
|
36
36
|
super().__init__()
|
37
|
-
|
38
|
-
|
37
|
+
nyrs = Policy.number_of_years(last_budget_year)
|
38
|
+
self.initialize(GrowDiff.JSON_START_YEAR, nyrs)
|
39
39
|
|
40
40
|
@staticmethod
|
41
41
|
def read_json_update(obj, topkey):
|
@@ -81,8 +81,3 @@ class GrowDiff(Parameters):
|
|
81
81
|
cyr = i + self.start_year
|
82
82
|
diff_array = getattr(self, _gfvn)
|
83
83
|
growfactors.update(gfvn, cyr, diff_array[i])
|
84
|
-
|
85
|
-
def set_rates(self):
|
86
|
-
"""
|
87
|
-
Unimplemented base class method that is not used here.
|
88
|
-
"""
|
taxcalc/parameters.py
CHANGED
@@ -98,19 +98,16 @@ class Parameters(pt.Parameters):
|
|
98
98
|
self.DEFAULTS_FILE_PATH,
|
99
99
|
self.DEFAULTS_FILE_NAME
|
100
100
|
)
|
101
|
-
|
101
|
+
last_budget_year = start_year + num_years - 1
|
102
102
|
if last_known_year is None:
|
103
103
|
self._last_known_year = start_year
|
104
104
|
else:
|
105
105
|
assert last_known_year >= start_year
|
106
|
-
assert last_known_year <=
|
106
|
+
assert last_known_year <= last_budget_year
|
107
107
|
self._last_known_year = last_known_year
|
108
|
-
|
109
108
|
self._removed_params = removed or self.REMOVED_PARAMS
|
110
109
|
self._redefined_params = redefined or self.REDEFINED_PARAMS
|
111
|
-
|
112
110
|
self._wage_indexed = wage_indexed or self.WAGE_INDEXED_PARAMS
|
113
|
-
|
114
111
|
if (
|
115
112
|
(start_year or self.JSON_START_YEAR) and
|
116
113
|
"initial_state" not in kwargs
|
@@ -118,6 +115,10 @@ class Parameters(pt.Parameters):
|
|
118
115
|
kwargs["initial_state"] = {
|
119
116
|
"year": start_year or self.JSON_START_YEAR
|
120
117
|
}
|
118
|
+
# update defaults to correspond to user-defined parameter years
|
119
|
+
self.defaults = super().get_defaults()
|
120
|
+
label = self.defaults["schema"]["labels"]["year"]
|
121
|
+
label["validators"]["range"]["max"] = last_budget_year
|
121
122
|
super().__init__(**kwargs)
|
122
123
|
|
123
124
|
def adjust(
|
@@ -774,7 +775,7 @@ class Parameters(pt.Parameters):
|
|
774
775
|
attr[1:], year=list(range(self.start_year, self.end_year + 1))
|
775
776
|
)
|
776
777
|
else:
|
777
|
-
raise AttributeError(f"{attr} not
|
778
|
+
raise AttributeError(f"{attr} is not defined.")
|
778
779
|
|
779
780
|
|
780
781
|
TaxcalcReform = Union[str, Mapping[int, Any]]
|
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
|
-
|
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,
|
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.
|
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(
|
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):
|
taxcalc/reforms/ext.json
CHANGED
taxcalc/taxcalcio.py
CHANGED
@@ -249,6 +249,35 @@ class TaxCalcIO():
|
|
249
249
|
# pylint: disable=too-many-arguments,too-many-locals
|
250
250
|
# pylint: disable=too-many-statements,too-many-branches
|
251
251
|
self.errmsg = ''
|
252
|
+
# instantiate base and reform GrowFactors objects
|
253
|
+
if self.tmd_input_data:
|
254
|
+
gfactors_base = GrowFactors(self.tmd_gfactor) # pragma: no cover
|
255
|
+
gfactors_ref = GrowFactors(self.tmd_gfactor) # pragma: no cover
|
256
|
+
else:
|
257
|
+
gfactors_base = GrowFactors()
|
258
|
+
gfactors_ref = GrowFactors()
|
259
|
+
# check tax_year validity
|
260
|
+
max_tax_year = gfactors_base.last_year
|
261
|
+
if tax_year > max_tax_year:
|
262
|
+
msg = f'TAXYEAR={tax_year} is greater than {max_tax_year}'
|
263
|
+
self.errmsg += f'ERROR: {msg}\n'
|
264
|
+
if self.puf_input_data:
|
265
|
+
min_tax_year = max( # pragma: no cover
|
266
|
+
Policy.JSON_START_YEAR, Records.PUFCSV_YEAR)
|
267
|
+
elif self.cps_input_data:
|
268
|
+
min_tax_year = max(
|
269
|
+
Policy.JSON_START_YEAR, Records.CPSCSV_YEAR)
|
270
|
+
elif self.tmd_input_data:
|
271
|
+
min_tax_year = max( # pragma: no cover
|
272
|
+
Policy.JSON_START_YEAR, Records.TMDCSV_YEAR)
|
273
|
+
else:
|
274
|
+
min_tax_year = Policy.JSON_START_YEAR
|
275
|
+
if tax_year < min_tax_year:
|
276
|
+
msg = f'TAXYEAR={tax_year} is less than {min_tax_year}'
|
277
|
+
self.errmsg += f'ERROR: {msg}\n'
|
278
|
+
# tax_year out of valid range means cannot proceed with calculations
|
279
|
+
if self.errmsg:
|
280
|
+
return
|
252
281
|
# get policy parameter dictionary from --baseline file
|
253
282
|
basedict = Calculator.read_json_param_objects(baseline, None)
|
254
283
|
# get assumption sub-dictionaries
|
@@ -264,35 +293,29 @@ class TaxCalcIO():
|
|
264
293
|
# remember parameters for reform documentation
|
265
294
|
self.param_dict = paramdict
|
266
295
|
self.policy_dicts = policydicts
|
296
|
+
# set last_b_year
|
297
|
+
last_b_year = max(tax_year, Policy.LAST_BUDGET_YEAR)
|
267
298
|
# create gdiff_baseline object
|
268
|
-
gdiff_baseline = GrowDiff()
|
299
|
+
gdiff_baseline = GrowDiff(last_budget_year=last_b_year)
|
269
300
|
try:
|
270
301
|
gdiff_baseline.update_growdiff(paramdict['growdiff_baseline'])
|
271
302
|
except paramtools.ValidationError as valerr_msg:
|
272
303
|
self.errmsg += valerr_msg.__str__()
|
273
|
-
#
|
274
|
-
if self.tmd_input_data:
|
275
|
-
gfactors_base = GrowFactors(self.tmd_gfactor) # pragma: no cover
|
276
|
-
else:
|
277
|
-
gfactors_base = GrowFactors()
|
304
|
+
# apply gdiff_baseline to gfactor_base
|
278
305
|
gdiff_baseline.apply_to(gfactors_base)
|
279
306
|
# specify gdiff_response object
|
280
|
-
gdiff_response = GrowDiff()
|
307
|
+
gdiff_response = GrowDiff(last_budget_year=last_b_year)
|
281
308
|
try:
|
282
309
|
gdiff_response.update_growdiff(paramdict['growdiff_response'])
|
283
310
|
except paramtools.ValidationError as valerr_msg:
|
284
311
|
self.errmsg += valerr_msg.__str__()
|
285
|
-
#
|
286
|
-
if self.tmd_input_data:
|
287
|
-
gfactors_ref = GrowFactors(self.tmd_gfactor) # pragma: no cover
|
288
|
-
else:
|
289
|
-
gfactors_ref = GrowFactors()
|
312
|
+
# apply gdiff_baseline and gdiff_response to gfactor_ref
|
290
313
|
gdiff_baseline.apply_to(gfactors_ref)
|
291
314
|
gdiff_response.apply_to(gfactors_ref)
|
292
315
|
self.gf_reform = copy.deepcopy(gfactors_ref)
|
293
316
|
# create Policy objects:
|
294
317
|
# ... the baseline Policy object
|
295
|
-
base = Policy(gfactors=gfactors_base)
|
318
|
+
base = Policy(gfactors=gfactors_base, last_budget_year=last_b_year)
|
296
319
|
try:
|
297
320
|
base.implement_reform(basedict['policy'],
|
298
321
|
print_warnings=True,
|
@@ -303,7 +326,7 @@ class TaxCalcIO():
|
|
303
326
|
self.errmsg += valerr_msg.__str__()
|
304
327
|
# ... the reform Policy object
|
305
328
|
if self.specified_reform:
|
306
|
-
pol = Policy(gfactors=gfactors_ref)
|
329
|
+
pol = Policy(gfactors=gfactors_ref, last_budget_year=last_b_year)
|
307
330
|
for poldict in policydicts:
|
308
331
|
try:
|
309
332
|
pol.implement_reform(poldict,
|
@@ -316,22 +339,13 @@ class TaxCalcIO():
|
|
316
339
|
except paramtools.ValidationError as valerr_msg:
|
317
340
|
self.errmsg += valerr_msg.__str__()
|
318
341
|
else:
|
319
|
-
pol = Policy(gfactors=gfactors_base)
|
342
|
+
pol = Policy(gfactors=gfactors_base, last_budget_year=last_b_year)
|
320
343
|
# create Consumption object
|
321
|
-
con = Consumption()
|
344
|
+
con = Consumption(last_budget_year=last_b_year)
|
322
345
|
try:
|
323
346
|
con.update_consumption(paramdict['consumption'])
|
324
347
|
except paramtools.ValidationError as valerr_msg:
|
325
348
|
self.errmsg += valerr_msg.__str__()
|
326
|
-
# check for valid tax_year value
|
327
|
-
if tax_year < pol.start_year:
|
328
|
-
msg = 'tax_year {} less than policy.start_year {}'
|
329
|
-
msg = msg.format(tax_year, pol.start_year)
|
330
|
-
self.errmsg += 'ERROR: {}\n'.format(msg)
|
331
|
-
if tax_year > pol.end_year:
|
332
|
-
msg = 'tax_year {} greater than policy.end_year {}'
|
333
|
-
msg = msg.format(tax_year, pol.end_year)
|
334
|
-
self.errmsg += 'ERROR: {}\n'.format(msg)
|
335
349
|
# any errors imply cannot proceed with calculations
|
336
350
|
if self.errmsg:
|
337
351
|
return
|
@@ -388,10 +402,6 @@ class TaxCalcIO():
|
|
388
402
|
adjust_ratios=None,
|
389
403
|
exact_calculations=exact_calculations)
|
390
404
|
recs_base = copy.deepcopy(recs)
|
391
|
-
if tax_year < recs.data_year:
|
392
|
-
msg = 'tax_year {} less than records.data_year {}'
|
393
|
-
msg = msg.format(tax_year, recs.data_year)
|
394
|
-
self.errmsg += 'ERROR: {}\n'.format(msg)
|
395
405
|
# create Calculator objects
|
396
406
|
self.calc = Calculator(policy=pol, records=recs,
|
397
407
|
verbose=True,
|
taxcalc/tests/test_4package.py
CHANGED
@@ -10,6 +10,34 @@ import re
|
|
10
10
|
import subprocess
|
11
11
|
import yaml
|
12
12
|
import pytest
|
13
|
+
import ast
|
14
|
+
|
15
|
+
|
16
|
+
def extract_install_requires(setup_py_content):
|
17
|
+
"""
|
18
|
+
Extract the install_requires list from a setup.py file content.
|
19
|
+
|
20
|
+
Args:
|
21
|
+
setup_py_content (str): The full content of the setup.py file
|
22
|
+
|
23
|
+
Returns:
|
24
|
+
list: A list of package requirements
|
25
|
+
"""
|
26
|
+
# Use regex to find the install_requires list
|
27
|
+
match = re.search(r'"install_requires"\s*:\s*\[([^\]]+)\]', setup_py_content, re.DOTALL)
|
28
|
+
|
29
|
+
if match:
|
30
|
+
# Extract the contents of the list and split into packages
|
31
|
+
packages_str = match.group(1)
|
32
|
+
# Use ast.literal_eval to safely parse the string representations
|
33
|
+
packages = [
|
34
|
+
ast.literal_eval(f'{pkg.strip()}')
|
35
|
+
for pkg in packages_str.split(',')
|
36
|
+
if pkg.strip()
|
37
|
+
]
|
38
|
+
return packages
|
39
|
+
|
40
|
+
return []
|
13
41
|
|
14
42
|
|
15
43
|
@pytest.mark.local
|
@@ -38,6 +66,7 @@ def test_for_consistency(tests_path):
|
|
38
66
|
'coverage',
|
39
67
|
"pip",
|
40
68
|
"jupyter-book",
|
69
|
+
"setuptools"
|
41
70
|
])
|
42
71
|
# read conda.recipe/meta.yaml requirements
|
43
72
|
meta_file = os.path.join(tests_path, '..', '..',
|
@@ -65,3 +94,16 @@ def test_for_consistency(tests_path):
|
|
65
94
|
# confirm that extras in env (relative to run) equal the dev_pkgs set
|
66
95
|
extras = env - run
|
67
96
|
assert extras == dev_pkgs
|
97
|
+
# Read the setup.py file and extract the install_requires list
|
98
|
+
setup_file = os.path.join(tests_path, '..', '..',
|
99
|
+
'setup.py')
|
100
|
+
with open(setup_file, 'r') as f:
|
101
|
+
setup_py_content = f.read()
|
102
|
+
setup = set(extract_install_requires(setup_py_content))
|
103
|
+
# confirm that setup.py
|
104
|
+
print("Setup packages = ", setup)
|
105
|
+
print("Meta packages = ", bld)
|
106
|
+
# if package in both, confirm that the version is the same
|
107
|
+
for pkg in setup.intersection(bld):
|
108
|
+
assert pkg in setup
|
109
|
+
assert pkg in bld
|
taxcalc/tests/test_calculator.py
CHANGED
@@ -74,9 +74,9 @@ def test_make_calculator_with_policy_reform(cps_subsample):
|
|
74
74
|
assert calc.current_year == year
|
75
75
|
assert calc.policy_param('II_em') == 4000
|
76
76
|
assert np.allclose(calc.policy_param('_II_em'),
|
77
|
-
np.array([4000] *
|
77
|
+
np.array([4000] * pol.num_years))
|
78
78
|
exp_STD_Aged = [[1600, 1300, 1300,
|
79
|
-
1600, 1600]] *
|
79
|
+
1600, 1600]] * pol.num_years
|
80
80
|
assert np.allclose(calc.policy_param('_STD_Aged'),
|
81
81
|
np.array(exp_STD_Aged))
|
82
82
|
assert np.allclose(calc.policy_param('STD_Aged'),
|
@@ -100,10 +100,9 @@ def test_make_calculator_with_multiyear_reform(cps_subsample):
|
|
100
100
|
# create a Calculator object using this policy-reform
|
101
101
|
calc = Calculator(policy=pol, records=rec)
|
102
102
|
# check that Policy object embedded in Calculator object is correct
|
103
|
-
assert pol.num_years == Policy.DEFAULT_NUM_YEARS
|
104
103
|
assert calc.current_year == year
|
105
104
|
assert calc.policy_param('II_em') == 3950
|
106
|
-
exp_II_em = [3900, 3950, 5000] + [6000] * (
|
105
|
+
exp_II_em = [3900, 3950, 5000] + [6000] * (pol.num_years - 3)
|
107
106
|
assert np.allclose(calc.policy_param('_II_em'),
|
108
107
|
np.array(exp_II_em))
|
109
108
|
calc.increment_year()
|
@@ -8,9 +8,8 @@ import copy
|
|
8
8
|
from taxcalc import Policy, Records, Calculator, Consumption
|
9
9
|
|
10
10
|
|
11
|
-
def
|
11
|
+
def test_start_year_consistency():
|
12
12
|
assert Consumption.JSON_START_YEAR == Policy.JSON_START_YEAR
|
13
|
-
assert Consumption.DEFAULT_NUM_YEARS == Policy.DEFAULT_NUM_YEARS
|
14
13
|
|
15
14
|
|
16
15
|
def test_validity_of_consumption_vars_set():
|
@@ -31,23 +30,23 @@ def test_update_consumption():
|
|
31
30
|
2015: 0.80}
|
32
31
|
}
|
33
32
|
consump.update_consumption(revision)
|
34
|
-
expected_mpc_e20400 = np.full((
|
33
|
+
expected_mpc_e20400 = np.full((consump.num_years,), 0.06)
|
35
34
|
expected_mpc_e20400[0] = 0.0
|
36
35
|
expected_mpc_e20400[1] = 0.05
|
37
36
|
assert np.allclose(consump._MPC_e20400,
|
38
37
|
expected_mpc_e20400,
|
39
38
|
rtol=0.0)
|
40
39
|
assert np.allclose(consump._MPC_e17500,
|
41
|
-
np.zeros((
|
40
|
+
np.zeros((consump.num_years,)),
|
42
41
|
rtol=0.0)
|
43
|
-
expected_ben_mcare_value = np.full((
|
42
|
+
expected_ben_mcare_value = np.full((consump.num_years,), 0.80)
|
44
43
|
expected_ben_mcare_value[0] = 1.0
|
45
44
|
expected_ben_mcare_value[1] = 0.75
|
46
45
|
assert np.allclose(consump._BEN_mcare_value,
|
47
46
|
expected_ben_mcare_value,
|
48
47
|
rtol=0.0)
|
49
48
|
assert np.allclose(consump._BEN_snap_value,
|
50
|
-
np.ones((
|
49
|
+
np.ones((consump.num_years,)),
|
51
50
|
rtol=0.0)
|
52
51
|
consump.set_year(2015)
|
53
52
|
assert consump.current_year == 2015
|
taxcalc/tests/test_cpscsv.py
CHANGED
@@ -18,7 +18,7 @@ import pytest
|
|
18
18
|
import numpy as np
|
19
19
|
import pandas as pd
|
20
20
|
# pylint: disable=import-error
|
21
|
-
from taxcalc import Policy, Records, Calculator
|
21
|
+
from taxcalc import GrowFactors, GrowDiff, Policy, Records, Calculator
|
22
22
|
|
23
23
|
|
24
24
|
START_YEAR = 2017
|
@@ -161,3 +161,51 @@ def nonsmall_diffs(linelist1, linelist2, small=0.0):
|
|
161
161
|
else:
|
162
162
|
return True
|
163
163
|
return False
|
164
|
+
|
165
|
+
|
166
|
+
def test_flexible_last_budget_year(cps_fullsample):
|
167
|
+
"""
|
168
|
+
Test flexible LAST_BUDGET_YEAR logic using cps.csv file.
|
169
|
+
"""
|
170
|
+
tax_calc_year = Policy.LAST_BUDGET_YEAR - 1
|
171
|
+
growdiff_year = tax_calc_year - 1
|
172
|
+
growdiff_dict = {'AWAGE': {growdiff_year: 0.01, tax_calc_year: 0.0}}
|
173
|
+
|
174
|
+
def default_calculator(growdiff_dictionary):
|
175
|
+
"""
|
176
|
+
Return CPS-based Calculator object using default LAST_BUDGET_YEAR.
|
177
|
+
"""
|
178
|
+
g_factors = GrowFactors()
|
179
|
+
gdiff = GrowDiff()
|
180
|
+
gdiff.update_growdiff(growdiff_dictionary)
|
181
|
+
gdiff.apply_to(g_factors)
|
182
|
+
pol = Policy(gfactors=g_factors)
|
183
|
+
rec = Records.cps_constructor(data=cps_fullsample, gfactors=g_factors)
|
184
|
+
calc = Calculator(policy=pol, records=rec)
|
185
|
+
return calc
|
186
|
+
|
187
|
+
def flexible_calculator(growdiff_dictionary, last_b_year):
|
188
|
+
"""
|
189
|
+
Return CPS-based Calculator object using custom LAST_BUDGET_YEAR.
|
190
|
+
"""
|
191
|
+
g_factors = GrowFactors()
|
192
|
+
gdiff = GrowDiff(last_budget_year=last_b_year)
|
193
|
+
gdiff.update_growdiff(growdiff_dictionary)
|
194
|
+
gdiff.apply_to(g_factors)
|
195
|
+
pol = Policy(gfactors=g_factors, last_budget_year=last_b_year)
|
196
|
+
rec = Records.cps_constructor(data=cps_fullsample, gfactors=g_factors)
|
197
|
+
calc = Calculator(policy=pol, records=rec)
|
198
|
+
return calc
|
199
|
+
|
200
|
+
# begin main test logic
|
201
|
+
cdef = default_calculator(growdiff_dict)
|
202
|
+
cdef.advance_to_year(tax_calc_year)
|
203
|
+
cdef.calc_all()
|
204
|
+
iitax_def = round(cdef.weighted_total('iitax'))
|
205
|
+
|
206
|
+
cflx = flexible_calculator(growdiff_dict, tax_calc_year)
|
207
|
+
cflx.advance_to_year(tax_calc_year)
|
208
|
+
cflx.calc_all()
|
209
|
+
iitax_flx = round(cflx.weighted_total('iitax'))
|
210
|
+
|
211
|
+
assert np.allclose([iitax_flx], [iitax_def])
|
taxcalc/tests/test_growdiff.py
CHANGED
@@ -8,9 +8,8 @@ import pytest
|
|
8
8
|
from taxcalc import GrowDiff, GrowFactors, Policy
|
9
9
|
|
10
10
|
|
11
|
-
def
|
11
|
+
def test_start_year_consistency():
|
12
12
|
assert GrowDiff.JSON_START_YEAR == Policy.JSON_START_YEAR
|
13
|
-
assert GrowDiff.DEFAULT_NUM_YEARS == Policy.DEFAULT_NUM_YEARS
|
14
13
|
|
15
14
|
|
16
15
|
def test_update_and_apply_growdiff():
|
@@ -22,14 +21,13 @@ def test_update_and_apply_growdiff():
|
|
22
21
|
}
|
23
22
|
gdiff.update_growdiff(diffs)
|
24
23
|
expected_wage_diffs = [0.00, 0.01, 0.01, 0.02, 0.02]
|
25
|
-
extra_years =
|
24
|
+
extra_years = gdiff.num_years - len(expected_wage_diffs)
|
26
25
|
expected_wage_diffs.extend([0.02] * extra_years)
|
27
26
|
assert np.allclose(gdiff._AWAGE, expected_wage_diffs, atol=0.0, rtol=0.0)
|
28
27
|
# apply growdiff to GrowFactors instance
|
29
28
|
gf = GrowFactors()
|
30
|
-
syr =
|
31
|
-
|
32
|
-
lyr = syr + nyrs - 1
|
29
|
+
syr = gdiff.start_year
|
30
|
+
lyr = gdiff.end_year
|
33
31
|
pir_pre = gf.price_inflation_rates(syr, lyr)
|
34
32
|
wgr_pre = gf.wage_growth_rates(syr, lyr)
|
35
33
|
gfactors = GrowFactors()
|
@@ -37,7 +35,7 @@ def test_update_and_apply_growdiff():
|
|
37
35
|
pir_pst = gfactors.price_inflation_rates(syr, lyr)
|
38
36
|
wgr_pst = gfactors.wage_growth_rates(syr, lyr)
|
39
37
|
expected_wgr_pst = [wgr_pre[i] + expected_wage_diffs[i]
|
40
|
-
for i in range(0,
|
38
|
+
for i in range(0, gdiff.num_years)]
|
41
39
|
assert np.allclose(pir_pre, pir_pst, atol=0.0, rtol=0.0)
|
42
40
|
assert np.allclose(wgr_pst, expected_wgr_pst, atol=1.0e-9, rtol=0.0)
|
43
41
|
|
taxcalc/tests/test_policy.py
CHANGED
@@ -247,9 +247,9 @@ def test_multi_year_reform():
|
|
247
247
|
Test multi-year reform involving 1D and 2D parameters.
|
248
248
|
"""
|
249
249
|
# specify dimensions of policy Policy object
|
250
|
-
syr = Policy.JSON_START_YEAR
|
251
|
-
nyrs = Policy.DEFAULT_NUM_YEARS
|
252
250
|
pol = Policy()
|
251
|
+
syr = pol.start_year
|
252
|
+
nyrs = pol.num_years
|
253
253
|
iratelist = pol.inflation_rates()
|
254
254
|
ifactor = {}
|
255
255
|
for i in range(0, nyrs):
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: taxcalc
|
3
|
-
Version: 4.
|
3
|
+
Version: 4.4.0
|
4
4
|
Summary: taxcalc
|
5
5
|
Home-page: https://github.com/PSLmodels/Tax-Calculator
|
6
6
|
Download-URL: https://github.com/PSLmodels/Tax-Calculator
|
@@ -18,13 +18,11 @@ Classifier: Programming Language :: Python :: 3.12
|
|
18
18
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
19
19
|
Description-Content-Type: text/markdown
|
20
20
|
License-File: LICENSE
|
21
|
-
Requires-Dist:
|
22
|
-
Requires-Dist:
|
23
|
-
Requires-Dist:
|
24
|
-
Requires-Dist: bokeh
|
21
|
+
Requires-Dist: numpy>=1.26
|
22
|
+
Requires-Dist: pandas>=2.2
|
23
|
+
Requires-Dist: bokeh>=2.4
|
25
24
|
Requires-Dist: numba
|
26
|
-
Requires-Dist:
|
27
|
-
Requires-Dist: paramtools>=0.18.3
|
25
|
+
Requires-Dist: paramtools>=0.19.0
|
28
26
|
|
29
27
|
| | |
|
30
28
|
| --- | --- |
|
@@ -1,25 +1,25 @@
|
|
1
|
-
taxcalc/__init__.py,sha256
|
1
|
+
taxcalc/__init__.py,sha256=_y68pxnYle7BTdgF5NC4QW7aILRcv_R5AaCpXZ4-hjQ,536
|
2
2
|
taxcalc/calcfunctions.py,sha256=VHQ3YgpyhkDIVclM_sR-fRoUJc8afYGjnzfVVx4mDEg,146595
|
3
3
|
taxcalc/calculator.py,sha256=sl2YYR2QH9bEo7cQGhvpTIku1XUt7XdK9krBI8k6Rj8,63908
|
4
4
|
taxcalc/conftest.py,sha256=nO4J7qu1sTHgjqrzhpRMvfMJUrNm6GP_IsSuuDt_MeQ,141
|
5
5
|
taxcalc/consumption.json,sha256=D4Iz625yka_LSlq313hoy01qGtNrpN5QYAHqd9QQfVA,8102
|
6
|
-
taxcalc/consumption.py,sha256=
|
6
|
+
taxcalc/consumption.py,sha256=oY6LifwGFkdEUCCLHrxXB2kTAGz1ymmw9r6mgm40cEw,3403
|
7
7
|
taxcalc/cps.csv.gz,sha256=SS6tSduU_Eu0EJwzpslnmqMsQQQucVMzzITfH-SeV40,9851074
|
8
8
|
taxcalc/cps_weights.csv.gz,sha256=qPkZmVpmVPiRgnTm22VzcfNFAVigcgKVqfm6vjJWR4s,13024268
|
9
9
|
taxcalc/data.py,sha256=KnVxSbYUF-wn_ZKCo1EHOLOVVK6ldis8vL_EB8oSR2c,11723
|
10
10
|
taxcalc/decorators.py,sha256=uCZGHrq90k5Gr5YA_1tuWkCMEiOPbqXp6wxCWp6cDfM,11332
|
11
11
|
taxcalc/growdiff.json,sha256=im6mp7NZfpROismsNTjwLLAwIEltZsFfV6EKFEG3dKo,15037
|
12
|
-
taxcalc/growdiff.py,sha256=
|
12
|
+
taxcalc/growdiff.py,sha256=CaOhGwCihGtvesjkb0PDU98bnhdNult3XE5n5L4Ua8U,2871
|
13
13
|
taxcalc/growfactors.csv,sha256=yAnRpyqckjbUDKYj0e6is_pL_3H0AVtH4-jf8yxlpI0,4681
|
14
14
|
taxcalc/growfactors.py,sha256=MNb2XbAV_RbJDjbZp7iMvC6dHabAe97wdbXWEqdAmaQ,6534
|
15
|
-
taxcalc/parameters.py,sha256=
|
16
|
-
taxcalc/policy.py,sha256=
|
15
|
+
taxcalc/parameters.py,sha256=2U8Pc78qkgViCRAVrmyDJ3EsvAIwxNUgOzkNDJqrKYs,31490
|
16
|
+
taxcalc/policy.py,sha256=tbQVJoKHb4CCWmgaHHFS6CU_Aiy3MsZkF-fFpY_Ws8w,7075
|
17
17
|
taxcalc/policy_current_law.json,sha256=X_Q_gm58mZJRVBm9ABe91IUx7ajpJecZmA5jdq4iDXY,690298
|
18
18
|
taxcalc/puf_ratios.csv,sha256=htfJvGM236MyFTGBHioy_XUL7_LOoFtMlvhyESqrrPE,3439
|
19
19
|
taxcalc/puf_weights.csv.gz,sha256=Chkk3TosWJQjTI6Idpo705By_WyNpzen8J6dR8afVTE,12967455
|
20
20
|
taxcalc/records.py,sha256=ZLgAyzb7lITb7p8Qpj-JO7H03byeIwwn171SmQdaxWs,18208
|
21
21
|
taxcalc/records_variables.json,sha256=SXr0Vl09MS5efy6LbdXHuBH3DcEBwIoga52tyAv_Trk,42755
|
22
|
-
taxcalc/taxcalcio.py,sha256=
|
22
|
+
taxcalc/taxcalcio.py,sha256=cuuMtP8GUJTKUEVEhO3brm1Qpxd37qa2xrGEICdBy0U,35618
|
23
23
|
taxcalc/utils.py,sha256=aNIEYbm37pQoayt_rXrr9iKoodoE-DH8EFL2A0rSokk,62468
|
24
24
|
taxcalc/utilsprvt.py,sha256=iIyWp9-N3_XWjQj2jV2CWnJy7vrNlKB2_vIMwYjgbWY,1323
|
25
25
|
taxcalc/assumptions/ASSUMPTIONS.md,sha256=cFQqWn1nScaladVaQ7xNm1jDY8CsGdLmqZEzUZeRrb8,1917
|
@@ -54,7 +54,7 @@ taxcalc/reforms/Trump2017.json,sha256=DZjCJQZYe98Skyss7z_Jhj8HJld_FPZeQGxwzGgQIn
|
|
54
54
|
taxcalc/reforms/Trump2017.out.csv,sha256=By1quzZONFLQGK5E76mbNNFuORZ8aCGHpD1BR5iwTS8,474
|
55
55
|
taxcalc/reforms/cases.csv,sha256=JQ0LSnNeyl6xSgW5mimGUJMr7xwCWTOpiOpfwx2ETsg,570
|
56
56
|
taxcalc/reforms/clp.out.csv,sha256=qSUdI0LoQFGG6h24eT-249pLEqmxmt7TvLrv1HX_y3Y,475
|
57
|
-
taxcalc/reforms/ext.json,sha256=
|
57
|
+
taxcalc/reforms/ext.json,sha256=9w59aWyDunGXaIXDFYPRqOAeITFDBp4DtyeS5nsWLPQ,3033
|
58
58
|
taxcalc/reforms/growfactors_ext.csv,sha256=E0szWXtgV5jcpiyvREOz1yXw_poPIBC77bBQI1rlFxM,17733
|
59
59
|
taxcalc/reforms/ptaxes0.json,sha256=QkvqCVkI23sF7FvTHqaUYNpEJYuHNChbKwH0mH7Otp4,1718
|
60
60
|
taxcalc/reforms/ptaxes0.out.csv,sha256=DKGsyNWqo-ABUnjFjEGMpqqhmT2WDRGuU6sKTgH_obc,476
|
@@ -83,20 +83,20 @@ taxcalc/tests/pufcsv_agg_expect.csv,sha256=f7rfFW3et6ZZMLENJTuKx8y-3urx6H2JMY31z
|
|
83
83
|
taxcalc/tests/pufcsv_mtr_expect.txt,sha256=xGsUfafzsZ04fFQw162ys-1Mf1CDC_PQ0QZNigS07VY,4265
|
84
84
|
taxcalc/tests/reforms.json,sha256=vGJrvfKJ7h5iAWF-vV9NmY8Z9HP_iereiYiYNcfhBMo,19212
|
85
85
|
taxcalc/tests/reforms_expect.csv,sha256=6m0bSH8S6ReMYdHoQC9iWYuJAof5sZ0OONVBi7zX8JE,1464
|
86
|
-
taxcalc/tests/test_4package.py,sha256=
|
86
|
+
taxcalc/tests/test_4package.py,sha256=Nwtv7xwoidAznt4PW2lhHtAneep4kI3Dm4dcLZV-Q0E,3484
|
87
87
|
taxcalc/tests/test_benefits.py,sha256=cseQyLYxyjBBWJq1yLY0uXzS3FwhIM9oEP4DbZof81M,3387
|
88
88
|
taxcalc/tests/test_calcfunctions.py,sha256=oP-tDlpnR4tkdDgPLue-shU3fWVaX-_BErEm5butDeM,31801
|
89
|
-
taxcalc/tests/test_calculator.py,sha256=
|
89
|
+
taxcalc/tests/test_calculator.py,sha256=ZP9QAdDVlnCKAhsGCTPg7jSa4cF6FNMYVVEt1LpKGfQ,36005
|
90
90
|
taxcalc/tests/test_compare.py,sha256=iYLxopqiKM3H1CHxAbzdi74oydkGb3vq6QgcYVr0qaI,10958
|
91
91
|
taxcalc/tests/test_compatible_data.py,sha256=sG3REUSIL4_yO4JbX3s1pC7SWlvw1gvaswAibB5EiVY,13389
|
92
|
-
taxcalc/tests/test_consumption.py,sha256=
|
93
|
-
taxcalc/tests/test_cpscsv.py,sha256=
|
92
|
+
taxcalc/tests/test_consumption.py,sha256=Zn7_MYEcrIknVqhwrDPbDIAy9VLRNawwkSGRSgDprOM,5889
|
93
|
+
taxcalc/tests/test_cpscsv.py,sha256=5r4XWhCnb8D-cii5GLVsIo_-zNWbcyy5NOz7YKJnNz8,8462
|
94
94
|
taxcalc/tests/test_data.py,sha256=5xIH7wgT2puF29S0sf3w6kxKhdi6OUiIz0Gx8BLFmxI,4094
|
95
95
|
taxcalc/tests/test_decorators.py,sha256=G-zmz78fZ8G6elCuRfe2KFBVOCUFNJHXnF228_FKhvk,8628
|
96
|
-
taxcalc/tests/test_growdiff.py,sha256=
|
96
|
+
taxcalc/tests/test_growdiff.py,sha256=r5BV9PXGNiDflWt9PhnTNmSHITvKmAJr5TQXce5_AYA,3282
|
97
97
|
taxcalc/tests/test_growfactors.py,sha256=8QhU7zk8An3pHUECW0pxbTmE0jzDUo3ayW5eQKKejMQ,2775
|
98
98
|
taxcalc/tests/test_parameters.py,sha256=QtB2_Xtc0jjfDciLjGYJMsKEEqLG8ebT02auq6cMPmU,20536
|
99
|
-
taxcalc/tests/test_policy.py,sha256=
|
99
|
+
taxcalc/tests/test_policy.py,sha256=yGtslbQ3MZhcAiEFiM1zYjTs7hcqI1_t6rRD32DG170,52910
|
100
100
|
taxcalc/tests/test_puf_var_stats.py,sha256=wdJ6Gf3i_VhyLMqFURZdtvD1u8fepP8dsmxuM1H1GGE,7844
|
101
101
|
taxcalc/tests/test_pufcsv.py,sha256=-1EFSlMj_0l5DtN-hUnKJI2q6-Zrq5W1kPiwW-NQIjk,16443
|
102
102
|
taxcalc/tests/test_records.py,sha256=CmYLJOH63vlm4K96z6Q1nzb1bK_F_rPKehZ0MFKTI4o,8323
|
@@ -131,9 +131,9 @@ taxcalc/validation/taxsim35/expected_differences/b21-taxdiffs-expect.csv,sha256=
|
|
131
131
|
taxcalc/validation/taxsim35/expected_differences/c17-taxdiffs-expect.csv,sha256=YhgojbLowH3yujdYu7SGkdvBZmTgpugu4wYc1Be069M,1125
|
132
132
|
taxcalc/validation/taxsim35/expected_differences/c18-taxdiffs-expect.csv,sha256=g9J4BPbTySV-h-RcLvReJq9v1jscgiRSSZzi0taEA-k,1225
|
133
133
|
taxcalc/validation/taxsim35/expected_differences/c19-taxdiffs-expect.csv,sha256=Ceh15N_Xr3L7cpYjzGa-8NLCV3obc8PNHEhE5ZxSPhI,1238
|
134
|
-
taxcalc-4.
|
135
|
-
taxcalc-4.
|
136
|
-
taxcalc-4.
|
137
|
-
taxcalc-4.
|
138
|
-
taxcalc-4.
|
139
|
-
taxcalc-4.
|
134
|
+
taxcalc-4.4.0.dist-info/LICENSE,sha256=m5epLdB-_NXiY7NsEDgcHP4jDtJ4vOlRf5S3Jb-jraY,1299
|
135
|
+
taxcalc-4.4.0.dist-info/METADATA,sha256=_1nU08gaJWjhFpfHRAh9Jti8nIza6t6Xrs0wtz--UL8,3148
|
136
|
+
taxcalc-4.4.0.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
137
|
+
taxcalc-4.4.0.dist-info/entry_points.txt,sha256=a3ZE1piRv683p27fOLdWZvVJXESkoslTOp5iXV7uVco,50
|
138
|
+
taxcalc-4.4.0.dist-info/top_level.txt,sha256=Wh8wTDHkA_cm4dn8IoUCviDyGgVQqwEQKPJnl8z6d4c,8
|
139
|
+
taxcalc-4.4.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|