taxcalc 4.6.1__py3-none-any.whl → 4.6.3__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 -2
- taxcalc/cli/tc.py +85 -29
- taxcalc/parameters.py +188 -118
- taxcalc/policy.py +26 -4
- taxcalc/policy_current_law.json +2 -2
- taxcalc/reforms/REFORMS.md +0 -2
- taxcalc/reforms/ext.json +0 -2
- taxcalc/taxcalcio.py +95 -24
- taxcalc/tests/conftest.py +1 -1
- taxcalc/tests/reforms.json +8 -19
- taxcalc/tests/reforms_expect.csv +9 -10
- taxcalc/tests/test_4package.py +0 -1
- taxcalc/tests/test_parameters.py +18 -22
- taxcalc/tests/test_policy.py +153 -41
- taxcalc/tests/test_reforms.py +2 -2
- taxcalc/tests/test_taxcalcio.py +35 -13
- taxcalc/utils.py +32 -10
- {taxcalc-4.6.1.dist-info → taxcalc-4.6.3.dist-info}/METADATA +5 -2
- {taxcalc-4.6.1.dist-info → taxcalc-4.6.3.dist-info}/RECORD +24 -24
- {taxcalc-4.6.1.dist-info → taxcalc-4.6.3.dist-info}/WHEEL +1 -1
- {taxcalc-4.6.1.dist-info → taxcalc-4.6.3.dist-info}/entry_points.txt +0 -0
- {taxcalc-4.6.1.dist-info → taxcalc-4.6.3.dist-info}/licenses/LICENSE +0 -0
- {taxcalc-4.6.1.dist-info → taxcalc-4.6.3.dist-info}/top_level.txt +0 -0
taxcalc/__init__.py
CHANGED
taxcalc/calcfunctions.py
CHANGED
@@ -3190,7 +3190,7 @@ def NonrefundableCredits(c05800, e07240, e07260, e07300, e07400,
|
|
3190
3190
|
@iterate_jit(nopython=True)
|
3191
3191
|
def AdditionalCTC(codtc_limited, ACTC_c, n24, earned, ACTC_Income_thd,
|
3192
3192
|
ACTC_rt, nu06, ACTC_rt_bonus_under6family, ACTC_ChildNum,
|
3193
|
-
CTC_is_refundable, CTC_include17,
|
3193
|
+
CTC_is_refundable, CTC_include17, CTC_c,
|
3194
3194
|
age_head, age_spouse, MARS, nu18,
|
3195
3195
|
ptax_was, c03260, e09800, c59660, e11200,
|
3196
3196
|
c11070):
|
@@ -3251,7 +3251,7 @@ def AdditionalCTC(codtc_limited, ACTC_c, n24, earned, ACTC_Income_thd,
|
|
3251
3251
|
childnum = n24 + max(0, nu18 - tu18 - su18 - n24)
|
3252
3252
|
else:
|
3253
3253
|
childnum = n24
|
3254
|
-
line4 = ACTC_c * childnum
|
3254
|
+
line4 = min(ACTC_c, CTC_c) * childnum
|
3255
3255
|
c11070 = 0. # line15
|
3256
3256
|
if line3 > 0. and line4 > 0.:
|
3257
3257
|
line5 = min(line3, line4)
|
taxcalc/cli/tc.py
CHANGED
@@ -43,7 +43,7 @@ def cli_tc_main():
|
|
43
43
|
),
|
44
44
|
(
|
45
45
|
' '
|
46
|
-
'[--silent] [--test] [--version] [--usage]'
|
46
|
+
'[--runid N] [--silent] [--test] [--version] [--usage]'
|
47
47
|
)
|
48
48
|
)
|
49
49
|
parser = argparse.ArgumentParser(
|
@@ -75,20 +75,20 @@ def cli_tc_main():
|
|
75
75
|
parser.add_argument('--baseline',
|
76
76
|
help=('BASELINE is name of optional JSON reform file. '
|
77
77
|
'A compound reform can be specified using 2+ '
|
78
|
-
'file names
|
78
|
+
'file names connected by plus (+) character(s). '
|
79
79
|
'No --baseline implies baseline policy is '
|
80
80
|
'current-law policy.'),
|
81
81
|
default=None)
|
82
82
|
parser.add_argument('--reform',
|
83
83
|
help=('REFORM is name of optional JSON reform file. '
|
84
84
|
'A compound reform can be specified using 2+ '
|
85
|
-
'file names
|
85
|
+
'file names connected by plus (+) character(s). '
|
86
86
|
'No --reform implies reform policy is '
|
87
87
|
'current-law policy).'),
|
88
88
|
default=None)
|
89
89
|
parser.add_argument('--assump',
|
90
90
|
help=('ASSUMP is name of optional JSON economic '
|
91
|
-
'assumptions file.
|
91
|
+
'assumptions file. No --assump implies use '
|
92
92
|
'of no customized assumptions.'),
|
93
93
|
default=None)
|
94
94
|
parser.add_argument('--exact',
|
@@ -125,12 +125,19 @@ def cli_tc_main():
|
|
125
125
|
parser.add_argument('--dumpvars',
|
126
126
|
help=('DUMPVARS is name of optional file containing a '
|
127
127
|
'space-delimited list of variables to include '
|
128
|
-
'in the dump database.
|
129
|
-
'
|
130
|
-
'
|
128
|
+
'in the dump database. No --dumpvars implies '
|
129
|
+
'a minimal set of variables. Valid variable '
|
130
|
+
'names include all variables in the '
|
131
131
|
'records_variables.json file plus mtr_itax and '
|
132
132
|
'mtr_ptax (MTRs wrt taxpayer earnings).'),
|
133
133
|
default=None)
|
134
|
+
parser.add_argument('--runid', metavar='N',
|
135
|
+
help=('N is a positive integer run id that is used '
|
136
|
+
'to construct simpler output file names. '
|
137
|
+
'No --runid implies legacy output file names '
|
138
|
+
'are used.'),
|
139
|
+
type=int,
|
140
|
+
default=0)
|
134
141
|
parser.add_argument('--silent',
|
135
142
|
help=('optional flag that suppresses messages about '
|
136
143
|
'input and output actions.'),
|
@@ -153,16 +160,23 @@ def cli_tc_main():
|
|
153
160
|
default=False,
|
154
161
|
action="store_true")
|
155
162
|
args = parser.parse_args()
|
163
|
+
using_error_file = args.silent and args.runid != 0
|
164
|
+
efilename = f'run{args.runid}.errors'
|
156
165
|
# check Python version
|
157
166
|
pyv = sys.version_info
|
158
167
|
pymin = tc.__min_python3_version__
|
159
168
|
pymax = tc.__max_python3_version__
|
160
169
|
if pyv[0] != 3 or pyv[1] < pymin or pyv[1] > pymax: # pragma: no cover
|
161
170
|
pyreq = f'at least Python 3.{pymin} and at most Python 3.{pymax}'
|
162
|
-
|
171
|
+
msg = (
|
163
172
|
f'ERROR: Tax-Calculator requires {pyreq}\n'
|
164
173
|
f' but Python {pyv[0]}.{pyv[1]} is installed\n'
|
165
174
|
)
|
175
|
+
if using_error_file:
|
176
|
+
with open(efilename, 'w', encoding='utf-8') as efile:
|
177
|
+
efile.write(msg)
|
178
|
+
else:
|
179
|
+
sys.stderr.write(msg)
|
166
180
|
return 1
|
167
181
|
# show Tax-Calculator version and quit if --version option is specified
|
168
182
|
if args.version:
|
@@ -186,20 +200,32 @@ def cli_tc_main():
|
|
186
200
|
# check taxyear value
|
187
201
|
if taxyear > tc.Policy.LAST_BUDGET_YEAR:
|
188
202
|
msg = f'ERROR: TAXYEAR is greater than {tc.Policy.LAST_BUDGET_YEAR}\n'
|
189
|
-
|
190
|
-
|
203
|
+
if using_error_file:
|
204
|
+
with open(efilename, 'w', encoding='utf-8') as efile:
|
205
|
+
efile.write(msg)
|
206
|
+
else:
|
207
|
+
sys.stderr.write(msg)
|
208
|
+
sys.stderr.write('USAGE: tc --help\n')
|
191
209
|
return 1
|
192
210
|
# check numyears value
|
193
211
|
if args.numyears < 1:
|
194
212
|
msg = 'ERROR: --numyears parameter N is less than one\n'
|
195
|
-
|
196
|
-
|
213
|
+
if using_error_file:
|
214
|
+
with open(efilename, 'w', encoding='utf-8') as efile:
|
215
|
+
efile.write(msg)
|
216
|
+
else:
|
217
|
+
sys.stderr.write(msg)
|
218
|
+
sys.stderr.write('USAGE: tc --help\n')
|
197
219
|
return 1
|
198
220
|
max_numyears = tc.Policy.LAST_BUDGET_YEAR - taxyear + 1
|
199
221
|
if args.numyears > max_numyears:
|
200
222
|
msg = f'ERROR: --numyears parameter N is greater than {max_numyears}\n'
|
201
|
-
|
202
|
-
|
223
|
+
if using_error_file:
|
224
|
+
with open(efilename, 'w', encoding='utf-8') as efile:
|
225
|
+
efile.write(msg)
|
226
|
+
else:
|
227
|
+
sys.stderr.write(msg)
|
228
|
+
sys.stderr.write('USAGE: tc --help\n')
|
203
229
|
return 1
|
204
230
|
# specify if aging input data
|
205
231
|
aging_data = (
|
@@ -210,8 +236,12 @@ def cli_tc_main():
|
|
210
236
|
# check args.dumpdb and args.dumpvars consistency
|
211
237
|
if not args.dumpdb and args.dumpvars:
|
212
238
|
msg = 'ERROR: DUMPVARS file specified without --dumpdb option\n'
|
213
|
-
|
214
|
-
|
239
|
+
if using_error_file:
|
240
|
+
with open(efilename, 'w', encoding='utf-8') as efile:
|
241
|
+
efile.write(msg)
|
242
|
+
else:
|
243
|
+
sys.stderr.write(msg)
|
244
|
+
sys.stderr.write('USAGE: tc --help\n')
|
215
245
|
return 1
|
216
246
|
# specify dumpvars_str from args.dumpvars file
|
217
247
|
dumpvars_str = ''
|
@@ -221,9 +251,22 @@ def cli_tc_main():
|
|
221
251
|
dumpvars_str = dfile.read()
|
222
252
|
else:
|
223
253
|
msg = f'ERROR: DUMPVARS file {args.dumpvars} does not exist\n'
|
254
|
+
if using_error_file:
|
255
|
+
with open(efilename, 'w', encoding='utf-8') as efile:
|
256
|
+
efile.write(msg)
|
257
|
+
else:
|
258
|
+
sys.stderr.write(msg)
|
259
|
+
sys.stderr.write('USAGE: tc --help\n')
|
260
|
+
return 1
|
261
|
+
if args.runid < 0:
|
262
|
+
msg = 'ERROR: --runid parameter N is less than zero\n'
|
263
|
+
if using_error_file:
|
264
|
+
with open(efilename, 'w', encoding='utf-8') as efile:
|
265
|
+
efile.write(msg)
|
266
|
+
else:
|
224
267
|
sys.stderr.write(msg)
|
225
268
|
sys.stderr.write('USAGE: tc --help\n')
|
226
|
-
|
269
|
+
return 1
|
227
270
|
# do calculations for taxyear
|
228
271
|
# ... initialize TaxCalcIO object for taxyear
|
229
272
|
tcio = tc.TaxCalcIO(
|
@@ -232,14 +275,19 @@ def cli_tc_main():
|
|
232
275
|
baseline=args.baseline,
|
233
276
|
reform=args.reform,
|
234
277
|
assump=args.assump,
|
278
|
+
runid=args.runid,
|
235
279
|
silent=args.silent,
|
236
280
|
)
|
237
281
|
if tcio.errmsg:
|
238
|
-
|
239
|
-
|
282
|
+
msg = tcio.errmsg
|
283
|
+
if not msg.endswith('\n'):
|
284
|
+
msg += '\n'
|
285
|
+
if using_error_file:
|
286
|
+
with open(efilename, 'w', encoding='utf-8') as efile:
|
287
|
+
efile.write(msg)
|
240
288
|
else:
|
241
|
-
sys.stderr.write(
|
242
|
-
|
289
|
+
sys.stderr.write(msg)
|
290
|
+
sys.stderr.write('USAGE: tc --help\n')
|
243
291
|
return 1
|
244
292
|
tcio.init(
|
245
293
|
input_data=inputfn,
|
@@ -251,19 +299,27 @@ def cli_tc_main():
|
|
251
299
|
exact_calculations=args.exact,
|
252
300
|
)
|
253
301
|
if tcio.errmsg:
|
254
|
-
|
255
|
-
|
302
|
+
msg = tcio.errmsg
|
303
|
+
if not msg.endswith('\n'):
|
304
|
+
msg += '\n'
|
305
|
+
if using_error_file:
|
306
|
+
with open(efilename, 'w', encoding='utf-8') as efile:
|
307
|
+
efile.write(msg)
|
256
308
|
else:
|
257
|
-
sys.stderr.write(
|
258
|
-
|
309
|
+
sys.stderr.write(msg)
|
310
|
+
sys.stderr.write('USAGE: tc --help\n')
|
259
311
|
return 1
|
260
312
|
# ... conduct tax analysis for taxyear
|
261
313
|
dumpvars_list = tcio.dump_variables(dumpvars_str)
|
262
314
|
if tcio.errmsg:
|
263
|
-
|
264
|
-
|
315
|
+
msg = tcio.errmsg
|
316
|
+
if not msg.endswith('\n'):
|
317
|
+
msg += '\n'
|
318
|
+
if using_error_file:
|
319
|
+
with open(efilename, 'w', encoding='utf-8') as efile:
|
320
|
+
efile.write(msg)
|
265
321
|
else:
|
266
|
-
sys.stderr.write(
|
322
|
+
sys.stderr.write(msg)
|
267
323
|
sys.stderr.write('USAGE: tc --help\n')
|
268
324
|
return 1
|
269
325
|
tcio.analyze(
|
@@ -313,7 +369,7 @@ EXPECTED_TEST_OUTPUT = (
|
|
313
369
|
'1|131.88\n'
|
314
370
|
'2|28879.00\n'
|
315
371
|
)
|
316
|
-
TEST_DUMPDB_FILENAME = f'test-{str(TEST_TAXYEAR)[2:]}-#-#-#.
|
372
|
+
TEST_DUMPDB_FILENAME = f'test-{str(TEST_TAXYEAR)[2:]}-#-#-#.dumpdb'
|
317
373
|
TEST_SQLITE_QUERY = """
|
318
374
|
SELECT
|
319
375
|
RECID AS id,
|