taxcalc 4.4.1__py3-none-any.whl → 4.6.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/calcfunctions.py +2 -6
- taxcalc/calculator.py +15 -15
- taxcalc/cli/tc.py +192 -109
- taxcalc/consumption.json +1 -1
- taxcalc/cps_weights.csv.gz +0 -0
- taxcalc/growdiff.json +1 -1
- taxcalc/growfactors.csv +26 -25
- taxcalc/policy.py +4 -13
- taxcalc/policy_current_law.json +90 -90
- taxcalc/puf_ratios.csv +15 -14
- taxcalc/puf_weights.csv.gz +0 -0
- taxcalc/reforms/ext.json +25 -22
- taxcalc/taxcalcio.py +285 -298
- taxcalc/tests/conftest.py +1 -1
- taxcalc/tests/cpscsv_agg_expect.csv +22 -22
- taxcalc/tests/puf_var_wght_means_by_year.csv +70 -70
- taxcalc/tests/pufcsv_agg_expect.csv +22 -22
- taxcalc/tests/test_4package.py +1 -0
- taxcalc/tests/test_calculator.py +2 -2
- taxcalc/tests/test_compare.py +1 -1
- taxcalc/tests/test_parameters.py +1 -1
- taxcalc/tests/test_reforms.py +1 -1
- taxcalc/tests/test_taxcalcio.py +86 -107
- taxcalc/utils.py +4 -10
- {taxcalc-4.4.1.dist-info → taxcalc-4.6.0.dist-info}/METADATA +3 -2
- {taxcalc-4.4.1.dist-info → taxcalc-4.6.0.dist-info}/RECORD +31 -31
- {taxcalc-4.4.1.dist-info → taxcalc-4.6.0.dist-info}/WHEEL +1 -1
- {taxcalc-4.4.1.dist-info → taxcalc-4.6.0.dist-info}/entry_points.txt +0 -0
- {taxcalc-4.4.1.dist-info → taxcalc-4.6.0.dist-info/licenses}/LICENSE +0 -0
- {taxcalc-4.4.1.dist-info → taxcalc-4.6.0.dist-info}/top_level.txt +0 -0
taxcalc/__init__.py
CHANGED
taxcalc/calcfunctions.py
CHANGED
@@ -3,11 +3,7 @@ Tax-Calculator functions that calculate payroll and individual income taxes.
|
|
3
3
|
|
4
4
|
These functions are imported into the Calculator class.
|
5
5
|
|
6
|
-
Note: the parameter_indexing_CPI_offset
|
7
|
-
policy parameter that does not appear here; it is used in the policy.py
|
8
|
-
file to possibly adjust the price inflation rate used to index policy
|
9
|
-
parameters (as would be done in a reform that introduces chained-CPI
|
10
|
-
indexing).
|
6
|
+
Note: the parameter_indexing_CPI_offset parameter is no longer used.
|
11
7
|
"""
|
12
8
|
# CODING-STYLE CHECKS:
|
13
9
|
# pycodestyle calcfunctions.py
|
@@ -2059,7 +2055,7 @@ def AMT(e07300, dwks13, standard, f6251, c00100, c18300, taxbc,
|
|
2059
2055
|
e62900: float
|
2060
2056
|
Alternative Minimum Tax foreign tax credit from Form 6251
|
2061
2057
|
e00700: float
|
2062
|
-
|
2058
|
+
Taxable refunds of state and local income taxes
|
2063
2059
|
dwks10: float
|
2064
2060
|
Sum of dwks6 + dwks9
|
2065
2061
|
age_head: int
|
taxcalc/calculator.py
CHANGED
@@ -113,29 +113,29 @@ class Calculator():
|
|
113
113
|
raise ValueError('consumption must be None or Consumption object')
|
114
114
|
if self.__consumption.current_year < self.__policy.current_year:
|
115
115
|
self.__consumption.set_year(self.__policy.current_year)
|
116
|
-
if verbose:
|
117
|
-
if self.__records.IGNORED_VARS:
|
118
|
-
print('Your data include the following unused ' +
|
119
|
-
'variables that will be ignored:')
|
120
|
-
for var in self.__records.IGNORED_VARS:
|
121
|
-
print(' ' +
|
122
|
-
var)
|
123
116
|
current_year_is_data_year = (
|
124
117
|
self.__records.current_year == self.__records.data_year)
|
125
118
|
if sync_years and current_year_is_data_year:
|
126
|
-
if verbose:
|
127
|
-
print('You loaded data for ' +
|
128
|
-
str(self.__records.data_year) + '.')
|
129
119
|
while self.__records.current_year < self.__policy.current_year:
|
130
120
|
self.__records.increment_year()
|
131
121
|
if verbose:
|
132
|
-
print(
|
133
|
-
|
134
|
-
|
122
|
+
print(
|
123
|
+
f'Read input data for {self.__records.data_year}; '
|
124
|
+
'input data were extrapolated to '
|
125
|
+
f'{self.__records.current_year}'
|
126
|
+
)
|
135
127
|
else:
|
136
128
|
if verbose:
|
137
|
-
print(
|
138
|
-
|
129
|
+
print( # pragma: no cover
|
130
|
+
'Read input data that were not extrapolated in any way'
|
131
|
+
)
|
132
|
+
if verbose and self.__records.IGNORED_VARS: # pragma: no cover
|
133
|
+
print(
|
134
|
+
'Input data include the following unused '
|
135
|
+
'variables that will be ignored:'
|
136
|
+
)
|
137
|
+
for var in self.__records.IGNORED_VARS:
|
138
|
+
print(f' {var}')
|
139
139
|
assert self.__policy.current_year == self.__records.current_year
|
140
140
|
assert self.__policy.current_year == self.__consumption.current_year
|
141
141
|
self.__stored_records = None
|
taxcalc/cli/tc.py
CHANGED
@@ -9,6 +9,7 @@ which can be accessed as 'tc' from an installed taxcalc conda package.
|
|
9
9
|
import os
|
10
10
|
import sys
|
11
11
|
import time
|
12
|
+
import sqlite3
|
12
13
|
import argparse
|
13
14
|
import difflib
|
14
15
|
import taxcalc as tc
|
@@ -25,26 +26,31 @@ def cli_tc_main():
|
|
25
26
|
# pylint: disable=too-many-statements,too-many-branches
|
26
27
|
# pylint: disable=too-many-return-statements,too-many-locals
|
27
28
|
|
29
|
+
start_time = time.time()
|
30
|
+
|
28
31
|
# parse command-line arguments:
|
29
|
-
usage_str = 'tc INPUT TAXYEAR {}{}{}{}
|
32
|
+
usage_str = 'tc INPUT TAXYEAR {}{}{}{}'.format(
|
30
33
|
'[--help]\n',
|
31
|
-
(
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
34
|
+
(
|
35
|
+
' '
|
36
|
+
'[--baseline BASELINE] [--reform REFORM] '
|
37
|
+
'[--assump ASSUMP] [--exact]\n'
|
38
|
+
),
|
39
|
+
(
|
40
|
+
' '
|
41
|
+
'[--params] [--tables] [--graphs] '
|
42
|
+
'[--dumpdb] [--dumpvars DUMPVARS]\n'
|
43
|
+
),
|
44
|
+
(
|
45
|
+
' '
|
46
|
+
'[--silent] [--test] [--version] [--usage]'
|
47
|
+
)
|
48
|
+
)
|
39
49
|
parser = argparse.ArgumentParser(
|
40
50
|
prog='',
|
41
51
|
usage=usage_str,
|
42
|
-
description=('Writes
|
43
|
-
'
|
44
|
-
'file, with the OUTPUT computed from the INPUT for the '
|
45
|
-
'TAXYEAR using Tax-Calculator. The OUTPUT file is a '
|
46
|
-
'CSV-formatted file that contains tax information for '
|
47
|
-
'each INPUT filing unit under the reform(s).'))
|
52
|
+
description=('Writes several output files computed from the INPUT '
|
53
|
+
'for the TAXYEAR using Tax-Calculator.'))
|
48
54
|
parser.add_argument('INPUT', nargs='?',
|
49
55
|
help=('INPUT is name of CSV-formatted file that '
|
50
56
|
'contains for each filing unit variables used '
|
@@ -66,7 +72,7 @@ def cli_tc_main():
|
|
66
72
|
help=('REFORM is name of optional JSON reform file. '
|
67
73
|
'A compound reform can be specified using two '
|
68
74
|
'file names separated by a plus (+) character. '
|
69
|
-
'No --reform implies
|
75
|
+
'No --reform implies reform policy is '
|
70
76
|
'current-law policy).'),
|
71
77
|
default=None)
|
72
78
|
parser.add_argument('--assump',
|
@@ -80,6 +86,12 @@ def cli_tc_main():
|
|
80
86
|
'complicate marginal-tax-rate calculations.'),
|
81
87
|
default=False,
|
82
88
|
action="store_true")
|
89
|
+
parser.add_argument('--params',
|
90
|
+
help=('optional flag that causes policy parameter '
|
91
|
+
'values for baseline and reform to be written '
|
92
|
+
'to separate text files.'),
|
93
|
+
default=False,
|
94
|
+
action="store_true")
|
83
95
|
parser.add_argument('--tables',
|
84
96
|
help=('optional flag that causes distributional '
|
85
97
|
'tables to be written to a text file.'),
|
@@ -90,47 +102,33 @@ def cli_tc_main():
|
|
90
102
|
'to HTML files for viewing in browser.'),
|
91
103
|
default=False,
|
92
104
|
action="store_true")
|
93
|
-
parser.add_argument('--
|
94
|
-
help=('optional flag that causes
|
95
|
-
'
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
'all INPUT variables (extrapolated to TAXYEAR) '
|
101
|
-
'and all calculated tax variables for the '
|
102
|
-
'reform, where all the variables are named '
|
103
|
-
'using their internal Tax-Calculator names. '
|
104
|
-
'No --dump option implies OUTPUT contains '
|
105
|
-
'minimal tax output for the reform. NOTE: '
|
106
|
-
'use the --dvars option to point to a file '
|
107
|
-
'containing a custom set of dump variables.'
|
108
|
-
''),
|
105
|
+
parser.add_argument('--dumpdb',
|
106
|
+
help=('optional flag that causes TAXYEAR variable '
|
107
|
+
'values for each tax-unit under both '
|
108
|
+
'baseline and reform policies to be written '
|
109
|
+
'to a SQLite database (where the variables '
|
110
|
+
'included in the database are controlled by '
|
111
|
+
'the --dumpvars option).'),
|
109
112
|
default=False,
|
110
113
|
action="store_true")
|
111
|
-
parser.add_argument('--
|
112
|
-
help=('
|
114
|
+
parser.add_argument('--dumpvars',
|
115
|
+
help=('DUMPVARS is name of optional file containing a '
|
113
116
|
'space-delimited list of variables to include '
|
114
|
-
'in
|
115
|
-
'implies a
|
117
|
+
'in the dump database. No --dumpvars '
|
118
|
+
'implies a minimal set of variables. Valid '
|
119
|
+
'variable names include all variables in the '
|
120
|
+
'records_variables.json file plus mtr_itax and '
|
121
|
+
'mtr_ptax (MTRs wrt taxpayer earnings).'),
|
116
122
|
default=None)
|
117
|
-
parser.add_argument('--
|
118
|
-
help=('optional flag that
|
119
|
-
'
|
120
|
-
'containing same output variables as '
|
121
|
-
'produced by --dump option.'),
|
123
|
+
parser.add_argument('--silent',
|
124
|
+
help=('optional flag that suppresses messages about '
|
125
|
+
'input and output actions.'),
|
122
126
|
default=False,
|
123
127
|
action="store_true")
|
124
|
-
parser.add_argument('--outdir',
|
125
|
-
help=('OUTDIR is name of optional output directory '
|
126
|
-
'in which all output files are written. '
|
127
|
-
'No --outdir implies output files are written '
|
128
|
-
'in the current directory.'),
|
129
|
-
default=None)
|
130
128
|
parser.add_argument('--test',
|
131
129
|
help=('optional flag that conducts installation '
|
132
130
|
'test, writes test result to stdout, '
|
133
|
-
'and quits.'),
|
131
|
+
'and quits leaving the test-related files.'),
|
134
132
|
default=False,
|
135
133
|
action="store_true")
|
136
134
|
parser.add_argument('--version',
|
@@ -138,6 +136,11 @@ def cli_tc_main():
|
|
138
136
|
'release version to stdout and quits.'),
|
139
137
|
default=False,
|
140
138
|
action="store_true")
|
139
|
+
parser.add_argument('--usage',
|
140
|
+
help=('optional flag that writes short usage '
|
141
|
+
'reminder to stdout and quits.'),
|
142
|
+
default=False,
|
143
|
+
action="store_true")
|
141
144
|
args = parser.parse_args()
|
142
145
|
# check Python version
|
143
146
|
pyv = sys.version_info
|
@@ -155,21 +158,33 @@ def cli_tc_main():
|
|
155
158
|
pyver = f'Python 3.{pyv[1]}'
|
156
159
|
sys.stdout.write(f'Tax-Calculator {tc.__version__} on {pyver}\n')
|
157
160
|
return 0
|
161
|
+
# show short usage reminder and quit if --usage option is specified
|
162
|
+
if args.usage:
|
163
|
+
sys.stdout.write(f'USAGE: {usage_str}\n')
|
164
|
+
return 0
|
158
165
|
# write test input and expected output files if --test option is specified
|
159
166
|
if args.test:
|
160
|
-
|
167
|
+
_write_test_files()
|
161
168
|
inputfn = TEST_INPUT_FILENAME
|
162
169
|
taxyear = TEST_TAXYEAR
|
170
|
+
args.dumpdb = True
|
163
171
|
else:
|
164
172
|
inputfn = args.INPUT
|
165
173
|
taxyear = args.TAXYEAR
|
166
174
|
# instantiate TaxCalcIO object and do tax analysis
|
167
|
-
tcio = tc.TaxCalcIO(
|
168
|
-
|
169
|
-
|
170
|
-
|
175
|
+
tcio = tc.TaxCalcIO(
|
176
|
+
input_data=inputfn,
|
177
|
+
tax_year=taxyear,
|
178
|
+
baseline=args.baseline,
|
179
|
+
reform=args.reform,
|
180
|
+
assump=args.assump,
|
181
|
+
silent=args.silent,
|
182
|
+
)
|
171
183
|
if tcio.errmsg:
|
172
|
-
|
184
|
+
if tcio.errmsg.endswith('\n'):
|
185
|
+
sys.stderr.write(tcio.errmsg)
|
186
|
+
else:
|
187
|
+
sys.stderr.write(tcio.errmsg + '\n')
|
173
188
|
sys.stderr.write('USAGE: tc --help\n')
|
174
189
|
return 1
|
175
190
|
aging = (
|
@@ -177,87 +192,155 @@ def cli_tc_main():
|
|
177
192
|
inputfn.endswith('cps.csv') or
|
178
193
|
inputfn.endswith('tmd.csv')
|
179
194
|
)
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
xtime = time.time() - stime
|
189
|
-
sys.stdout.write(f'TIMINGS: init time = {xtime:.2f} secs\n')
|
195
|
+
tcio.init(
|
196
|
+
input_data=inputfn,
|
197
|
+
tax_year=taxyear,
|
198
|
+
baseline=args.baseline,
|
199
|
+
reform=args.reform, assump=args.assump,
|
200
|
+
aging_input_data=aging,
|
201
|
+
exact_calculations=args.exact,
|
202
|
+
)
|
190
203
|
if tcio.errmsg:
|
191
|
-
|
204
|
+
if tcio.errmsg.endswith('\n'):
|
205
|
+
sys.stderr.write(tcio.errmsg)
|
206
|
+
else:
|
207
|
+
sys.stderr.write(tcio.errmsg + '\n')
|
208
|
+
sys.stderr.write('USAGE: tc --help\n')
|
209
|
+
return 1
|
210
|
+
# check args.dumpdb and args.dumpvars consistency
|
211
|
+
if not args.dumpdb and args.dumpvars:
|
212
|
+
msg = 'ERROR: DUMPVARS file specified without --dumpdb option\n'
|
213
|
+
sys.stderr.write(msg)
|
192
214
|
sys.stderr.write('USAGE: tc --help\n')
|
193
215
|
return 1
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
if tcio.errmsg:
|
201
|
-
sys.stderr.write(tcio.errmsg)
|
202
|
-
sys.stderr.write('USAGE: tc --help\n')
|
203
|
-
return 1
|
216
|
+
# construct dumpvars set from dumpvars_str
|
217
|
+
dumpvars_str = ''
|
218
|
+
if args.dumpvars:
|
219
|
+
if os.path.exists(args.dumpvars):
|
220
|
+
with open(args.dumpvars, 'r', encoding='utf-8') as dfile:
|
221
|
+
dumpvars_str = dfile.read()
|
204
222
|
else:
|
205
|
-
msg = 'ERROR:
|
206
|
-
sys.stderr.write(msg
|
223
|
+
msg = f'ERROR: DUMPVARS file {args.dumpvars} does not exist\n'
|
224
|
+
sys.stderr.write(msg)
|
207
225
|
sys.stderr.write('USAGE: tc --help\n')
|
208
226
|
return 1
|
227
|
+
dumpvars_list = tcio.dump_variables(dumpvars_str)
|
228
|
+
if tcio.errmsg:
|
229
|
+
if tcio.errmsg.endswith('\n'):
|
230
|
+
sys.stderr.write(tcio.errmsg)
|
231
|
+
else:
|
232
|
+
sys.stderr.write(tcio.errmsg + '\n')
|
233
|
+
sys.stderr.write('USAGE: tc --help\n')
|
234
|
+
return 1
|
209
235
|
# conduct tax analysis
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
output_sqldb=args.sqldb)
|
218
|
-
if args.timings:
|
219
|
-
xtime = time.time() - stime
|
220
|
-
sys.stdout.write(f'TIMINGS: calc time = {xtime:.2f} secs\n')
|
236
|
+
tcio.analyze(
|
237
|
+
output_params=args.params,
|
238
|
+
output_tables=args.tables,
|
239
|
+
output_graphs=args.graphs,
|
240
|
+
output_dump=args.dumpdb,
|
241
|
+
dump_varlist=dumpvars_list,
|
242
|
+
)
|
221
243
|
# compare test output with expected test output if --test option specified
|
222
244
|
if args.test:
|
223
245
|
retcode = _compare_test_output_files()
|
224
246
|
return retcode
|
247
|
+
if not args.silent:
|
248
|
+
print( # pragma: no cover
|
249
|
+
f'Execution time is {(time.time() - start_time):.1f} seconds'
|
250
|
+
)
|
225
251
|
return 0
|
226
252
|
# end of cli_tc_main function code
|
227
253
|
|
228
254
|
|
229
|
-
|
230
|
-
|
255
|
+
TEST_INPUT_DATA = (
|
256
|
+
'RECID,MARS,XTOT,EIC,e00200,e00200p,e00200s,p23250,e18400,e19800,s006\n'
|
257
|
+
'1, 2, 3, 1, 40000, 40000, 0, 0, 3000, 4000, 1e7\n'
|
258
|
+
'2, 2, 3, 1,200000, 200000, 0, 0, 15000, 20000, 1e7\n'
|
259
|
+
)
|
260
|
+
EXPECTED_TEST_FILENAME = f'test-{str(TEST_TAXYEAR)[2:]}.exp'
|
261
|
+
EXPECTED_TEST_OUTPUT = (
|
262
|
+
'id|itax\n'
|
263
|
+
'1|131.88\n'
|
264
|
+
'2|28879.00\n'
|
265
|
+
)
|
266
|
+
TEST_DUMPDB_FILENAME = f'test-{str(TEST_TAXYEAR)[2:]}-#-#-#.db'
|
267
|
+
TEST_SQLITE_QUERY = """
|
268
|
+
SELECT
|
269
|
+
RECID AS id,
|
270
|
+
ROUND(iitax, 2) AS itax
|
271
|
+
FROM baseline;
|
272
|
+
"""
|
273
|
+
ACTUAL_TEST_FILENAME = f'test-{str(TEST_TAXYEAR)[2:]}.act'
|
274
|
+
TEST_TABULATE_FILENAME = 'test-tabulate.sql'
|
275
|
+
TEST_TABULATE_SQLCODE = (
|
276
|
+
f'-- USAGE: sqlite3 {TEST_DUMPDB_FILENAME} < {TEST_TABULATE_FILENAME}\n'
|
277
|
+
'\n'
|
278
|
+
'-- sepecify base.income_group values\n'
|
279
|
+
'UPDATE base SET income_group =\n'
|
280
|
+
' CASE -- specify the income_group brackets as desired\n'
|
281
|
+
' WHEN expanded_income < 0.0 THEN 0\n'
|
282
|
+
' WHEN expanded_income < 50.0e3 THEN 1\n'
|
283
|
+
' WHEN expanded_income < 100.0e3 THEN 2\n'
|
284
|
+
' WHEN expanded_income < 500.0e3 THEN 3\n'
|
285
|
+
' WHEN expanded_income < 1.0e6 THEN 4\n'
|
286
|
+
' ELSE 5\n'
|
287
|
+
' END;\n'
|
288
|
+
'\n'
|
289
|
+
'-- tabulate baseline and reform iitax for joint filers by income_group\n'
|
290
|
+
'.separator "\t"\n'
|
291
|
+
'.headers on\n'
|
292
|
+
'SELECT\n'
|
293
|
+
' income_group AS g,\n'
|
294
|
+
' COUNT(*) AS units,\n'
|
295
|
+
' ROUND(SUM(b.iitax*s006)*1e-9, 3) AS b_iitax,\n'
|
296
|
+
' ROUND(SUM(r.iitax*s006)*1e-9, 3) AS r_iitax\n'
|
297
|
+
'FROM base JOIN baseline AS b USING(RECID) JOIN reform AS r USING(RECID)\n'
|
298
|
+
'WHERE MARS == 2\n'
|
299
|
+
'GROUP BY income_group;\n'
|
300
|
+
'.headers off\n'
|
301
|
+
'SELECT\n'
|
302
|
+
" 'A' AS g,\n"
|
303
|
+
' COUNT(*) AS units,\n'
|
304
|
+
' ROUND(SUM(b.iitax*s006)*1e-9, 3) AS b_iitax,\n'
|
305
|
+
' ROUND(SUM(r.iitax*s006)*1e-9, 3) AS r_iitax\n'
|
306
|
+
'FROM base JOIN baseline AS b USING(RECID) JOIN reform AS r USING(RECID)\n'
|
307
|
+
'WHERE MARS == 2;\n'
|
308
|
+
'\n'
|
309
|
+
'-- Documentation on the sqlite3 CLI program is available at\n'
|
310
|
+
'-- https://sqlite.org/cli.html\n'
|
311
|
+
)
|
231
312
|
|
232
313
|
|
233
|
-
def
|
314
|
+
def _write_test_files():
|
234
315
|
"""
|
235
316
|
Private function that writes tc --test input and expected output files.
|
236
317
|
"""
|
237
|
-
input_data = (
|
238
|
-
'RECID,MARS,XTOT,EIC,e00200,e00200p,e00200s,p23250,e18400,e19800\n'
|
239
|
-
'1, 2, 3, 1, 40000, 40000, 0, 0, 3000, 4000\n'
|
240
|
-
'2, 2, 3, 1,200000, 200000, 0, 0, 15000, 20000\n'
|
241
|
-
)
|
242
318
|
with open(TEST_INPUT_FILENAME, 'w', encoding='utf-8') as ifile:
|
243
|
-
ifile.write(
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
)
|
249
|
-
with open(EXPECTED_TEST_OUTPUT_FILENAME, 'w', encoding='utf-8') as ofile:
|
250
|
-
ofile.write(expected_output_data)
|
319
|
+
ifile.write(TEST_INPUT_DATA)
|
320
|
+
with open(EXPECTED_TEST_FILENAME, 'w', encoding='utf-8') as ofile:
|
321
|
+
ofile.write(EXPECTED_TEST_OUTPUT)
|
322
|
+
with open(TEST_TABULATE_FILENAME, 'w', encoding='utf-8') as tfile:
|
323
|
+
tfile.write(TEST_TABULATE_SQLCODE)
|
251
324
|
|
252
325
|
|
253
326
|
def _compare_test_output_files():
|
254
327
|
"""
|
255
|
-
Private function that compares expected and actual tc --test
|
328
|
+
Private function that compares expected and actual tc --test results;
|
256
329
|
returns 0 if pass test, otherwise returns 1.
|
257
330
|
"""
|
258
|
-
|
331
|
+
# use TEST_SQLITE_QUERY to extract results from TEST_DUMPDB_FILENAME
|
332
|
+
with sqlite3.connect(TEST_DUMPDB_FILENAME) as connection:
|
333
|
+
cursor = connection.cursor()
|
334
|
+
cursor.execute(TEST_SQLITE_QUERY)
|
335
|
+
results = cursor.fetchall()
|
336
|
+
with open(ACTUAL_TEST_FILENAME, 'w', encoding='utf-8') as afile:
|
337
|
+
afile.write('id|itax\n')
|
338
|
+
for row in results:
|
339
|
+
afile.write(f'{row[0]}|{row[1]:.2f}\n')
|
340
|
+
# compare results in ACTUAL_TEST_FILENAME and in EXPECTED_TEST_FILENAME
|
341
|
+
with open(EXPECTED_TEST_FILENAME, 'r', encoding='utf-8') as efile:
|
259
342
|
explines = efile.readlines()
|
260
|
-
with open(
|
343
|
+
with open(ACTUAL_TEST_FILENAME, 'r', encoding='utf-8') as afile:
|
261
344
|
actlines = afile.readlines()
|
262
345
|
if ''.join(explines) == ''.join(actlines):
|
263
346
|
sys.stdout.write('PASSED TEST\n')
|
@@ -266,8 +349,8 @@ def _compare_test_output_files():
|
|
266
349
|
retcode = 1
|
267
350
|
sys.stdout.write('FAILED TEST\n')
|
268
351
|
diff = difflib.unified_diff(explines, actlines,
|
269
|
-
fromfile=
|
270
|
-
tofile=
|
352
|
+
fromfile=EXPECTED_TEST_FILENAME,
|
353
|
+
tofile=ACTUAL_TEST_FILENAME, n=0)
|
271
354
|
sys.stdout.writelines(diff)
|
272
355
|
return retcode
|
273
356
|
|
taxcalc/consumption.json
CHANGED
taxcalc/cps_weights.csv.gz
CHANGED
Binary file
|
taxcalc/growdiff.json
CHANGED
taxcalc/growfactors.csv
CHANGED
@@ -1,25 +1,26 @@
|
|
1
|
-
YEAR,ATXPY,ASCHF,ABOOK,ACPIU,ACPIM,AWAGE,ASCHCI,ASCHCL,ASCHEI,ASCHEL,AINTS,ADIVS,ACGNS,ASOCSEC,AUCOMP,AIPD,ABENOTHER,ABENMCARE,ABENMCAID,ABENSSI,ABENSNAP,ABENWIC,ABENHOUSING,ABENTANF,ABENVET
|
2
|
-
2011,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
|
3
|
-
2012,1.043862,0.950283,1.104992,1.0209,1.0365,1.032649,1.049023,0.956138,1.165922,0.926962,0.923588,1.327776,1.58966,1.02827,0.7711,0.9231,0.992359,1,1,1,1,1,1,1,1
|
4
|
-
2013,1.012518,1.142179,1.033784,1.014791,1.024602,1.019984,0.99505,1.050098,0.997245,1.013128,0.893658,0.819381,0.776217,1.014786,0.728829,0.896219,0.992515,1,1,1,1,1,1,1,1
|
5
|
-
2014,1.029476,0.931683,0.976566,1.015927,1.023917,1.039999,1.040616,1.030349,1.075978,0.991321,0.925886,1.17606,1.387522,1.004801,0.641103,0.970506,0.99257,1,1,1,1,1,1,1,1
|
6
|
-
2015,1.043858,0.508206,0.999544,1.001235,1.026485,1.024119,1.038052,1.040061,1.04481,1.057257,1.013311,1.013846,1.004308,1.017188,0.81793,0.988666,1.053858,1.023325,1.041528,1.019361,1.102667,1.007792,1.026748,1.132657,1.04693
|
7
|
-
2016,1.021978,1.071198,0.984833,1.012621,1.037807,1.006659,0.984484,1.005593,0.982695,0.983807,0.999649,0.968237,0.881651,0.991403,0.933831,1.001764,1.097065,1.011695,1.010367,0.993375,0.989722,1.002577,1.01625,0.828168,1.105413
|
8
|
-
2017,1.049373,0.907035,1.018491,1.021273,1.025035,1.040577,1.060677,1.132498,1.093477,1.160123,1.088642,1.102389,1.344721,1.00723,0.94186,1.029301,1.011911,1.030968,1.014601,0.981621,1,0.998715,1.063959,1,1
|
9
|
-
2018,1.042394,0.976786,1.074059,1.0245,1.019707,1.041821,1.042769,1.042713,1.074048,1.074033,1.031272,1.076804,1.074755,1.018778,0.92284,1.050825,1.103035,1.045097,1.045897,1.005738,1,1.002574,1.034828,1,1
|
10
|
-
2019,1.032351,0.979401,1.019085,1.017913,1.028328,1.039292,1.004274,1.004387,1.019131,1.019122,1.014806,1.041751,0.925878,1.031182,0.940635,1.040577,1.054052,1.052158,1.045866,1.000751,1,1.002567,1.034809,1,1
|
11
|
-
2020,1.067957,1.167938,0.947032,1.012495,1.041121,1.006381,1.016054,1.015991,0.947016,0.94708,0.989319,1.091767,1.292516,1.023383,1.034222,1.076313,0.996727,1.050763,1.046106,1.00255,1,1.003841,1.034974,1,1
|
12
|
-
2021,1.065517,1.126248,1.216697,1.047189,1.012343,1.079707,1.057058,1.05708,1.216716,1.216644,0.999214,1.057982,1.792117,1.011965,8.619252,1.073809,1.03007,1.047248,1.047927,1.001796,1,1.002551,1.034869,1,1
|
13
|
-
2022,1.014347,1.742914,1.047552,1.08083,1.040311,1.076282,1.022527,1.022546,1.047553,1.047566,1.049118,1.042358,0.
|
14
|
-
2023,1.
|
15
|
-
2024,1.
|
16
|
-
2025,1.
|
17
|
-
2026,1.
|
18
|
-
2027,1.
|
19
|
-
2028,1.
|
20
|
-
2029,1.
|
21
|
-
2030,1.
|
22
|
-
2031,1.
|
23
|
-
2032,1.
|
24
|
-
2033,1.
|
25
|
-
2034,1.
|
1
|
+
YEAR,ATXPY,ASCHF,ABOOK,ACPIU,ACPIM,AWAGE,ASCHCI,ASCHCL,ASCHEI,ASCHEL,AINTS,ADIVS,ACGNS,ASOCSEC,AUCOMP,AIPD,ABENOTHER,ABENMCARE,ABENMCAID,ABENSSI,ABENSNAP,ABENWIC,ABENHOUSING,ABENTANF,ABENVET
|
2
|
+
2011,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0
|
3
|
+
2012,1.043862,0.950283,1.104992,1.0209,1.0365,1.032649,1.049023,0.956138,1.165922,0.926962,0.923588,1.327776,1.58966,1.02827,0.7711,0.9231,0.992359,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0
|
4
|
+
2013,1.012518,1.142179,1.033784,1.014791,1.024602,1.019984,0.99505,1.050098,0.997245,1.013128,0.893658,0.819381,0.776217,1.014786,0.728829,0.896219,0.992515,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0
|
5
|
+
2014,1.029476,0.931683,0.976566,1.015927,1.023917,1.039999,1.040616,1.030349,1.075978,0.991321,0.925886,1.17606,1.387522,1.004801,0.641103,0.970506,0.99257,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0
|
6
|
+
2015,1.043858,0.508206,0.999544,1.001235,1.026485,1.024119,1.038052,1.040061,1.04481,1.057257,1.013311,1.013846,1.004308,1.017188,0.81793,0.988666,1.053858,1.023325,1.041528,1.019361,1.102667,1.007792,1.026748,1.132657,1.04693
|
7
|
+
2016,1.021978,1.071198,0.984833,1.012621,1.037807,1.006659,0.984484,1.005593,0.982695,0.983807,0.999649,0.968237,0.881651,0.991403,0.933831,1.001764,1.097065,1.011695,1.010367,0.993375,0.989722,1.002577,1.01625,0.828168,1.105413
|
8
|
+
2017,1.049373,0.907035,1.018491,1.021273,1.025035,1.040577,1.060677,1.132498,1.093477,1.160123,1.088642,1.102389,1.344721,1.00723,0.94186,1.029301,1.011911,1.030968,1.014601,0.981621,1.0,0.998715,1.063959,1.0,1.0
|
9
|
+
2018,1.042394,0.976786,1.074059,1.0245,1.019707,1.041821,1.042769,1.042713,1.074048,1.074033,1.031272,1.076804,1.074755,1.018778,0.92284,1.050825,1.103035,1.045097,1.045897,1.005738,1.0,1.002574,1.034828,1.0,1.0
|
10
|
+
2019,1.032351,0.979401,1.019085,1.017913,1.028328,1.039292,1.004274,1.004387,1.019131,1.019122,1.014806,1.041751,0.925878,1.031182,0.940635,1.040577,1.054052,1.052158,1.045866,1.000751,1.0,1.002567,1.034809,1.0,1.0
|
11
|
+
2020,1.067957,1.167938,0.947032,1.012495,1.041121,1.006381,1.016054,1.015991,0.947016,0.94708,0.989319,1.091767,1.292516,1.023383,1.034222,1.076313,0.996727,1.050763,1.046106,1.00255,1.0,1.003841,1.034974,1.0,1.0
|
12
|
+
2021,1.065517,1.126248,1.216697,1.047189,1.012343,1.079707,1.057058,1.05708,1.216716,1.216644,0.999214,1.057982,1.792117,1.011965,8.619252,1.073809,1.03007,1.047248,1.047927,1.001796,1.0,1.002551,1.034869,1.0,1.0
|
13
|
+
2022,1.014347,1.742914,1.047552,1.08083,1.040311,1.076282,1.022527,1.022546,1.047553,1.047566,1.049118,1.042358,0.614105,1.04749,0.152665,1.022138,1.030159,1.048769,1.047573,0.999851,1.0,1.002545,1.034942,1.0,1.0
|
14
|
+
2023,1.054201,1.03319,0.873178,1.047758,1.004761,1.042139,1.028961,1.028889,0.873183,0.873156,1.174061,1.015964,0.72997,1.085497,0.748857,1.062234,1.030193,1.050822,1.048715,1.000448,1.0,1.003807,1.034968,1.0,1.0
|
15
|
+
2024,1.05941,0.42431,1.464113,1.021838,1.026755,1.05164,1.07187,1.071889,1.464111,1.464118,0.947213,1.189858,1.43944,1.053068,1.1413,1.067314,1.030334,1.048426,1.051767,0.99776,1.0,1.002528,1.034951,1.0,1.0
|
16
|
+
2025,1.041632,1.044788,1.018618,1.022303,0.947671,1.04136,1.035487,1.035494,1.018582,1.018598,1.086173,1.050943,1.048825,1.032798,1.267482,1.049137,1.030635,1.046248,1.052213,1.002245,1.0,1.003783,1.034897,1.0,1.0
|
17
|
+
2026,1.039652,1.070503,1.002596,1.024342,1.01461,1.038574,1.036202,1.036169,1.002606,1.002599,1.039571,1.050521,0.964765,1.029773,1.103105,1.047153,1.030633,1.072236,1.0,0.999552,1.0,1.002513,1.034808,1.0,1.0
|
18
|
+
2027,1.037063,1.052003,0.996587,1.023148,1.01403,1.034901,1.031166,1.031214,0.996589,0.996617,1.051254,1.034598,0.965869,1.031145,1.045641,1.044347,1.030788,1.0,1.0,1.0,1.0,1.002506,1.034863,1.0,1.0
|
19
|
+
2028,1.038667,1.042616,0.991454,1.022624,1.013836,1.03508,1.028193,1.028202,0.991435,0.991416,1.075829,1.0298,0.993501,1.03359,1.039205,1.045808,1.030942,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0
|
20
|
+
2029,1.037699,1.036497,0.999548,1.022385,1.013791,1.034165,1.026764,1.026741,0.999601,0.999612,1.066552,1.033877,1.012343,1.033618,1.031439,1.044636,1.031131,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0
|
21
|
+
2030,1.036237,1.033133,1.019395,1.022535,1.014029,1.032912,1.026209,1.02622,1.019337,1.019325,1.054094,1.033561,1.021054,1.034257,1.032431,1.043062,1.03133,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0
|
22
|
+
2031,1.034778,1.028007,1.036394,1.022226,1.013974,1.032526,1.027023,1.027016,1.036391,1.036427,1.050305,1.032957,1.025966,1.036614,1.033538,1.041284,1.03151,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0
|
23
|
+
2032,1.034722,1.023557,1.040127,1.022601,1.014264,1.032264,1.028726,1.02875,1.040116,1.040091,1.048447,1.032441,1.02936,1.036625,1.032221,1.041179,1.031644,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0
|
24
|
+
2033,1.034484,1.019571,1.037226,1.022401,1.014267,1.0318,1.031493,1.031499,1.037269,1.037279,1.039731,1.032168,1.0306,1.035799,1.029666,1.040669,1.031857,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0
|
25
|
+
2034,1.034773,1.01914,1.034899,1.022378,1.014402,1.032079,1.032644,1.032601,1.034904,1.034873,1.044366,1.03208,1.031022,1.035722,1.028596,1.040776,1.032059,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0
|
26
|
+
2035,1.035282,1.015356,1.034959,1.022404,1.014461,1.032062,1.032005,1.03198,1.034948,1.034965,1.041311,1.031909,1.031458,1.034008,1.029682,1.041135,1.032203,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0
|
taxcalc/policy.py
CHANGED
@@ -42,7 +42,7 @@ class Policy(Parameters):
|
|
42
42
|
JSON_START_YEAR = 2013 # remains the same unless earlier data added
|
43
43
|
LAST_KNOWN_YEAR = 2025 # last year for which indexed param vals are known
|
44
44
|
# should increase LAST_KNOWN_YEAR by one every calendar year
|
45
|
-
LAST_BUDGET_YEAR =
|
45
|
+
LAST_BUDGET_YEAR = 2035 # default value of last extrapolation year
|
46
46
|
# should increase LAST_BUDGET_YEAR by one every calendar year
|
47
47
|
|
48
48
|
@staticmethod
|
@@ -62,15 +62,6 @@ class Policy(Parameters):
|
|
62
62
|
'DependentCredit_before_CTC': 'is a removed parameter name',
|
63
63
|
'FilerCredit_c': 'is a removed parameter name',
|
64
64
|
'ALD_InvInc_ec_base_RyanBrady': 'is a removed parameter name',
|
65
|
-
# following parameter renamed in PR 2292 merged on 2019-04-15
|
66
|
-
"cpi_offset": (
|
67
|
-
"was renamed parameter_indexing_CPI_offset. "
|
68
|
-
"See documentation for change in usage."
|
69
|
-
),
|
70
|
-
"CPI_offset": (
|
71
|
-
"was renamed parameter_indexing_CPI_offset. "
|
72
|
-
"See documentation for change in usage."
|
73
|
-
),
|
74
65
|
# following parameters renamed in PR 2345 merged on 2019-06-24
|
75
66
|
'PT_excl_rt':
|
76
67
|
'was renamed PT_qbid_rt in release 2.4.0',
|
@@ -170,9 +161,9 @@ class Policy(Parameters):
|
|
170
161
|
vo["value"] for
|
171
162
|
vo in self._data["parameter_indexing_CPI_offset"]["value"]
|
172
163
|
]
|
173
|
-
#
|
174
|
-
|
175
|
-
|
164
|
+
# parameter_indexing_CPI_offset parameter is no longer used, so check:
|
165
|
+
assert any(cpi_vals) is False, \
|
166
|
+
'obsolete parameter_indexing_CPI_offset values must all be zero'
|
176
167
|
syr = max(self.start_year, self._gfactors.first_year)
|
177
168
|
self._inflation_rates = self._gfactors.price_inflation_rates(
|
178
169
|
syr, self.end_year
|