taxcalc 4.2.2__py3-none-any.whl → 4.3.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.
- taxcalc/__init__.py +3 -1
- taxcalc/calcfunctions.py +4 -12
- taxcalc/cli/tc.py +26 -10
- taxcalc/data.py +13 -5
- taxcalc/policy.py +1 -1
- taxcalc/policy_current_law.json +2714 -228
- taxcalc/records.py +32 -18
- taxcalc/reforms/ext.json +20 -20
- taxcalc/taxcalcio.py +61 -28
- taxcalc/tests/cpscsv_agg_expect.csv +18 -18
- taxcalc/tests/puf_var_wght_means_by_year.csv +5 -5
- taxcalc/tests/pufcsv_agg_expect.csv +19 -19
- taxcalc/tests/test_benefits.py +3 -3
- taxcalc/tests/test_calcfunctions.py +4 -5
- taxcalc/tests/test_calculator.py +1 -36
- taxcalc/tests/test_policy.py +460 -478
- taxcalc/tests/test_reforms.py +16 -15
- {taxcalc-4.2.2.dist-info → taxcalc-4.3.1.dist-info}/METADATA +1 -1
- {taxcalc-4.2.2.dist-info → taxcalc-4.3.1.dist-info}/RECORD +23 -28
- {taxcalc-4.2.2.dist-info → taxcalc-4.3.1.dist-info}/WHEEL +1 -1
- taxcalc/reforms/rounding2022.json +0 -153
- taxcalc/reforms/rounding2022.out.csv +0 -10
- taxcalc/tests/test_tmdcsv.py +0 -38
- taxcalc/tmd_growfactors.csv +0 -55
- taxcalc/tmd_weights.csv.gz +0 -0
- {taxcalc-4.2.2.dist-info → taxcalc-4.3.1.dist-info}/LICENSE +0 -0
- {taxcalc-4.2.2.dist-info → taxcalc-4.3.1.dist-info}/entry_points.txt +0 -0
- {taxcalc-4.2.2.dist-info → taxcalc-4.3.1.dist-info}/top_level.txt +0 -0
taxcalc/__init__.py
CHANGED
taxcalc/calcfunctions.py
CHANGED
@@ -1217,7 +1217,7 @@ def TaxInc(c00100, standard, c04470, c04600, MARS, e00900, c03260, e26270,
|
|
1217
1217
|
PT_binc_w2_wages, PT_ubia_property, PT_qbid_rt,
|
1218
1218
|
PT_qbid_taxinc_thd, PT_qbid_taxinc_gap, PT_qbid_w2_wages_rt,
|
1219
1219
|
PT_qbid_alt_w2_wages_rt, PT_qbid_alt_property_rt, c04800,
|
1220
|
-
PT_qbid_ps, PT_qbid_prt, qbided
|
1220
|
+
PT_qbid_ps, PT_qbid_prt, qbided):
|
1221
1221
|
"""
|
1222
1222
|
Calculates taxable income, c04800, and
|
1223
1223
|
qualified business income deduction, qbided.
|
@@ -1275,8 +1275,6 @@ def TaxInc(c00100, standard, c04470, c04600, MARS, e00900, c03260, e26270,
|
|
1275
1275
|
QBID phaseout rate
|
1276
1276
|
qbided: float
|
1277
1277
|
Qualified Business Income (QBI) deduction
|
1278
|
-
PT_qbid_limit_switch: bool
|
1279
|
-
QBID wage and capital limitations switch
|
1280
1278
|
|
1281
1279
|
Returns
|
1282
1280
|
-------
|
@@ -1300,9 +1298,7 @@ def TaxInc(c00100, standard, c04470, c04600, MARS, e00900, c03260, e26270,
|
|
1300
1298
|
upper_thd = lower_thd + pre_qbid_taxinc_gap
|
1301
1299
|
if PT_SSTB_income == 1 and pre_qbid_taxinc >= upper_thd:
|
1302
1300
|
qbided = 0.
|
1303
|
-
|
1304
|
-
# limitations.
|
1305
|
-
elif PT_qbid_limit_switch:
|
1301
|
+
else:
|
1306
1302
|
wage_cap = PT_binc_w2_wages * PT_qbid_w2_wages_rt
|
1307
1303
|
alt_cap = (PT_binc_w2_wages * PT_qbid_alt_w2_wages_rt +
|
1308
1304
|
PT_ubia_property * PT_qbid_alt_property_rt)
|
@@ -1323,12 +1319,8 @@ def TaxInc(c00100, standard, c04470, c04600, MARS, e00900, c03260, e26270,
|
|
1323
1319
|
prt = (pre_qbid_taxinc - lower_thd) / pre_qbid_taxinc_gap
|
1324
1320
|
adj = prt * (qbid_adjusted - cap_adjusted)
|
1325
1321
|
qbided = qbid_adjusted - adj
|
1326
|
-
|
1327
|
-
|
1328
|
-
# QBID limitations.
|
1329
|
-
else:
|
1330
|
-
qbided = qbid_before_limits
|
1331
|
-
# apply taxinc cap (assuning cap rate is equal to PT_qbid_rt)
|
1322
|
+
|
1323
|
+
# apply taxinc cap (assuming cap rate is equal to PT_qbid_rt)
|
1332
1324
|
net_cg = e00650 + c01000 # per line 34 in 2018 Pub 535 Worksheet 12-A
|
1333
1325
|
taxinc_cap = PT_qbid_rt * max(0., pre_qbid_taxinc - net_cg)
|
1334
1326
|
qbided = min(qbided, taxinc_cap)
|
taxcalc/cli/tc.py
CHANGED
@@ -138,11 +138,23 @@ def cli_tc_main():
|
|
138
138
|
default=False,
|
139
139
|
action="store_true")
|
140
140
|
args = parser.parse_args()
|
141
|
-
#
|
141
|
+
# check Python version
|
142
|
+
pyv = sys.version_info
|
143
|
+
pymin = tc.__min_python3_version__
|
144
|
+
pymax = tc.__max_python3_version__
|
145
|
+
if pyv[0] != 3 or pyv[1] < pymin or pyv[1] > pymax: # pragma: no cover
|
146
|
+
pyreq = f'at least Python 3.{pymin} and at most Python 3.{pymax}'
|
147
|
+
sys.stderr.write(
|
148
|
+
f'ERROR: Tax-Calculator requires {pyreq}\n'
|
149
|
+
f' but Python {pyv[0]}.{pyv[1]} is installed\n'
|
150
|
+
)
|
151
|
+
return 1
|
152
|
+
# show Tax-Calculator version and quit if --version option is specified
|
142
153
|
if args.version:
|
143
|
-
|
154
|
+
pyver = f'Python 3.{pyv[1]}'
|
155
|
+
sys.stdout.write(f'Tax-Calculator {tc.__version__} on {pyver}\n')
|
144
156
|
return 0
|
145
|
-
# write test input and expected output files if --test option specified
|
157
|
+
# write test input and expected output files if --test option is specified
|
146
158
|
if args.test:
|
147
159
|
_write_expected_test_output()
|
148
160
|
inputfn = TEST_INPUT_FILENAME
|
@@ -181,7 +193,7 @@ def cli_tc_main():
|
|
181
193
|
dumpvar_set = None
|
182
194
|
if args.dvars and (args.dump or args.sqldb):
|
183
195
|
if os.path.exists(args.dvars):
|
184
|
-
with open(args.dvars) as dfile:
|
196
|
+
with open(args.dvars, 'r', encoding='utf-8') as dfile:
|
185
197
|
dump_vars_str = dfile.read()
|
186
198
|
dumpvar_set = tcio.custom_dump_variables(dump_vars_str)
|
187
199
|
if tcio.errmsg:
|
@@ -213,8 +225,8 @@ def cli_tc_main():
|
|
213
225
|
# end of cli_tc_main function code
|
214
226
|
|
215
227
|
|
216
|
-
EXPECTED_TEST_OUTPUT_FILENAME = 'test-{
|
217
|
-
ACTUAL_TEST_OUTPUT_FILENAME = 'test-{
|
228
|
+
EXPECTED_TEST_OUTPUT_FILENAME = f'test-{str(TEST_TAXYEAR)[2:]}-out.csv'
|
229
|
+
ACTUAL_TEST_OUTPUT_FILENAME = f'test-{str(TEST_TAXYEAR)[2:]}-#-#-#.csv'
|
218
230
|
|
219
231
|
|
220
232
|
def _write_expected_test_output():
|
@@ -226,14 +238,14 @@ def _write_expected_test_output():
|
|
226
238
|
'1, 2, 3, 1, 40000, 40000, 0, 0, 3000, 4000\n'
|
227
239
|
'2, 2, 3, 1,200000, 200000, 0, 0, 15000, 20000\n'
|
228
240
|
)
|
229
|
-
with open(TEST_INPUT_FILENAME, 'w') as ifile:
|
241
|
+
with open(TEST_INPUT_FILENAME, 'w', encoding='utf-8') as ifile:
|
230
242
|
ifile.write(input_data)
|
231
243
|
expected_output_data = (
|
232
244
|
'RECID,YEAR,WEIGHT,INCTAX,LSTAX,PAYTAX\n'
|
233
245
|
'1,2018,0.00,131.88,0.00,6120.00\n'
|
234
246
|
'2,2018,0.00,28879.00,0.00,21721.60\n'
|
235
247
|
)
|
236
|
-
with open(EXPECTED_TEST_OUTPUT_FILENAME, 'w') as ofile:
|
248
|
+
with open(EXPECTED_TEST_OUTPUT_FILENAME, 'w', encoding='utf-8') as ofile:
|
237
249
|
ofile.write(expected_output_data)
|
238
250
|
|
239
251
|
|
@@ -242,8 +254,12 @@ def _compare_test_output_files():
|
|
242
254
|
Private function that compares expected and actual tc --test output files;
|
243
255
|
returns 0 if pass test, otherwise returns 1.
|
244
256
|
"""
|
245
|
-
explines = open(
|
246
|
-
|
257
|
+
explines = open(
|
258
|
+
EXPECTED_TEST_OUTPUT_FILENAME, 'r', encoding='utf-8'
|
259
|
+
).readlines()
|
260
|
+
actlines = open(
|
261
|
+
ACTUAL_TEST_OUTPUT_FILENAME, 'r', encoding='utf-8'
|
262
|
+
).readlines()
|
247
263
|
if ''.join(explines) == ''.join(actlines):
|
248
264
|
sys.stdout.write('PASSED TEST\n')
|
249
265
|
retcode = 0
|
taxcalc/data.py
CHANGED
@@ -42,6 +42,13 @@ class Data():
|
|
42
42
|
NOTE: when using custom weights, set this argument to a DataFrame.
|
43
43
|
NOTE: assumes weights are integers that are 100 times the real weights.
|
44
44
|
|
45
|
+
weights_scale: float
|
46
|
+
specifies the weights scaling factor used to convert contents
|
47
|
+
of weights file into the s006 variable. PUF and CPS input data
|
48
|
+
generated in the taxdata repository use a weights_scale of 0.01,
|
49
|
+
while TMD input data generated in the tax-microdata repository
|
50
|
+
use a 1.0 weights_scale value.
|
51
|
+
|
45
52
|
Raises
|
46
53
|
------
|
47
54
|
ValueError:
|
@@ -66,7 +73,8 @@ class Data():
|
|
66
73
|
VARINFO_FILE_NAME = None
|
67
74
|
VARINFO_FILE_PATH = None
|
68
75
|
|
69
|
-
def __init__(self, data, start_year, gfactors=None,
|
76
|
+
def __init__(self, data, start_year, gfactors=None,
|
77
|
+
weights=None, weights_scale=0.01):
|
70
78
|
# initialize data variable info sets and read variable information
|
71
79
|
self.INTEGER_READ_VARS = set()
|
72
80
|
self.MUST_READ_VARS = set()
|
@@ -97,6 +105,7 @@ class Data():
|
|
97
105
|
self.gfactors = gfactors
|
98
106
|
# read sample weights
|
99
107
|
self.WT = None
|
108
|
+
self.weights_scale = weights_scale
|
100
109
|
if self.__aging_data:
|
101
110
|
self._read_weights(weights)
|
102
111
|
# ... weights must be same size as data
|
@@ -114,7 +123,7 @@ class Data():
|
|
114
123
|
assert wt_colname in self.WT.columns, (
|
115
124
|
f'no weights for start year {self.current_year}'
|
116
125
|
)
|
117
|
-
self.s006 = self.WT[wt_colname] *
|
126
|
+
self.s006 = self.WT[wt_colname] * self.weights_scale
|
118
127
|
|
119
128
|
@property
|
120
129
|
def data_year(self):
|
@@ -152,7 +161,7 @@ class Data():
|
|
152
161
|
assert wt_colname in self.WT.columns, (
|
153
162
|
f'no weights for new year {self.current_year}'
|
154
163
|
)
|
155
|
-
self.s006 = self.WT[wt_colname] *
|
164
|
+
self.s006 = self.WT[wt_colname] * self.weights_scale
|
156
165
|
|
157
166
|
# ----- begin private methods of Data class -----
|
158
167
|
|
@@ -260,7 +269,6 @@ class Data():
|
|
260
269
|
Read sample weights from file or
|
261
270
|
use specified DataFrame as weights or
|
262
271
|
create empty DataFrame if None.
|
263
|
-
NOTE: assumes weights are integers equal to 100 times the real weight.
|
264
272
|
"""
|
265
273
|
if weights is None:
|
266
274
|
return
|
@@ -276,7 +284,7 @@ class Data():
|
|
276
284
|
msg = 'weights is not None or a string or a Pandas DataFrame'
|
277
285
|
raise ValueError(msg)
|
278
286
|
assert isinstance(WT, pd.DataFrame)
|
279
|
-
setattr(self, 'WT', WT.astype(np.
|
287
|
+
setattr(self, 'WT', WT.astype(np.float64))
|
280
288
|
del WT
|
281
289
|
|
282
290
|
def _extrapolate(self, year):
|
taxcalc/policy.py
CHANGED
@@ -37,7 +37,7 @@ class Policy(Parameters):
|
|
37
37
|
DEFAULTS_FILE_NAME = 'policy_current_law.json'
|
38
38
|
DEFAULTS_FILE_PATH = os.path.abspath(os.path.dirname(__file__))
|
39
39
|
JSON_START_YEAR = 2013 # remains the same unless earlier data added
|
40
|
-
LAST_KNOWN_YEAR =
|
40
|
+
LAST_KNOWN_YEAR = 2024 # last year for which indexed param vals are known
|
41
41
|
# should increase LAST_KNOWN_YEAR by one every calendar year
|
42
42
|
LAST_BUDGET_YEAR = 2034 # last extrapolation year
|
43
43
|
# should increase LAST_BUDGET_YEAR by one every calendar year
|