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 CHANGED
@@ -14,4 +14,6 @@ from taxcalc.taxcalcio import *
14
14
  from taxcalc.utils import *
15
15
  from taxcalc.cli import *
16
16
 
17
- __version__ = '4.2.2'
17
+ __version__ = '4.3.1'
18
+ __min_python3_version__ = 10
19
+ __max_python3_version__ = 12
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, PT_qbid_limit_switch):
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
- # if PT_qbid_limit_switch is True, apply wage/capital
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
- # if PT_qbid_limit_switch is False, assume all taxpayers
1327
- # have sufficient wage expenses and capital income to avoid
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
- # show Tax-Calculator version and quit if --version option specified
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
- sys.stdout.write('Tax-Calculator {}\n'.format(tc.__version__))
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-{}-out.csv'.format(str(TEST_TAXYEAR)[2:])
217
- ACTUAL_TEST_OUTPUT_FILENAME = 'test-{}-#-#-#.csv'.format(str(TEST_TAXYEAR)[2:])
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(EXPECTED_TEST_OUTPUT_FILENAME, 'r').readlines()
246
- actlines = open(ACTUAL_TEST_OUTPUT_FILENAME, 'r').readlines()
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, weights=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] * 0.01
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] * 0.01
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.int32))
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 = 2022 # last year for which indexed param vals are known
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