taxcalc 4.5.0__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 CHANGED
@@ -14,6 +14,6 @@ from taxcalc.taxcalcio import *
14
14
  from taxcalc.utils import *
15
15
  from taxcalc.cli import *
16
16
 
17
- __version__ = '4.5.0'
17
+ __version__ = '4.6.0'
18
18
  __min_python3_version__ = 10
19
19
  __max_python3_version__ = 12
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 policy parameter is the only
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
- Schedule C business net profit/loss for filing unit
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('Tax-Calculator startup automatically ' +
133
- 'extrapolated your data to ' +
134
- str(self.__records.current_year) + '.')
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('Tax-Calculator startup did not ' +
138
- 'extrapolate your data.')
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 {}{}{}{}{}'.format(
32
+ usage_str = 'tc INPUT TAXYEAR {}{}{}{}'.format(
30
33
  '[--help]\n',
31
- (' '
32
- '[--baseline BASELINE] [--reform REFORM] [--assump ASSUMP]\n'),
33
- (' '
34
- '[--exact] [--tables] [--graphs] [--timings]\n'),
35
- (' '
36
- '[--dump] [--dvars DVARS] [--sqldb] [--outdir OUTDIR]\n'),
37
- (' '
38
- '[--test] [--version]'))
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 to a file the federal income and payroll tax '
43
- 'OUTPUT for each filing unit specified in the INPUT '
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 a "null" reform (that is, '
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('--timings',
94
- help=('optional flag that causes execution times to '
95
- 'be written to stdout.'),
96
- default=False,
97
- action="store_true")
98
- parser.add_argument('--dump',
99
- help=('optional flag that causes OUTPUT to contain '
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('--dvars',
112
- help=('DVARS is name of optional file containing a '
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 a partial dump OUTPUT file. No --dvars '
115
- 'implies a full dump containing all variables.'),
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('--sqldb',
118
- help=('optional flag that writes SQLite database '
119
- 'with two tables (baseline and reform) each '
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
- _write_expected_test_output()
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(input_data=inputfn, tax_year=taxyear,
168
- baseline=args.baseline,
169
- reform=args.reform, assump=args.assump,
170
- outdir=args.outdir)
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
- sys.stderr.write(tcio.errmsg)
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
- if args.timings:
181
- stime = time.time()
182
- tcio.init(input_data=inputfn, tax_year=taxyear,
183
- baseline=args.baseline,
184
- reform=args.reform, assump=args.assump,
185
- aging_input_data=aging,
186
- exact_calculations=args.exact)
187
- if args.timings:
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
- sys.stderr.write(tcio.errmsg)
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
- dumpvar_set = None
195
- if args.dvars and (args.dump or args.sqldb):
196
- if os.path.exists(args.dvars):
197
- with open(args.dvars, 'r', encoding='utf-8') as dfile:
198
- dump_vars_str = dfile.read()
199
- dumpvar_set = tcio.custom_dump_variables(dump_vars_str)
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: DVARS file {} does not exist\n'
206
- sys.stderr.write(msg.format(args.dvars))
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
- if args.timings:
211
- stime = time.time()
212
- tcio.analyze(writing_output_file=True,
213
- output_tables=args.tables,
214
- output_graphs=args.graphs,
215
- dump_varset=dumpvar_set,
216
- output_dump=args.dump,
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
- EXPECTED_TEST_OUTPUT_FILENAME = f'test-{str(TEST_TAXYEAR)[2:]}-out.csv'
230
- ACTUAL_TEST_OUTPUT_FILENAME = f'test-{str(TEST_TAXYEAR)[2:]}-#-#-#.csv'
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 _write_expected_test_output():
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(input_data)
244
- expected_output_data = (
245
- 'RECID,YEAR,WEIGHT,INCTAX,LSTAX,PAYTAX\n'
246
- '1,2018,0.00,131.88,0.00,6120.00\n'
247
- '2,2018,0.00,28879.00,0.00,21721.60\n'
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 output files;
328
+ Private function that compares expected and actual tc --test results;
256
329
  returns 0 if pass test, otherwise returns 1.
257
330
  """
258
- with open(EXPECTED_TEST_OUTPUT_FILENAME, 'r', encoding='utf-8') as efile:
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(ACTUAL_TEST_OUTPUT_FILENAME, 'r', encoding='utf-8') as afile:
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=EXPECTED_TEST_OUTPUT_FILENAME,
270
- tofile=ACTUAL_TEST_OUTPUT_FILENAME, n=0)
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/policy.py CHANGED
@@ -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
- # policy_current_law.json should not specify any non-zero values
174
- # for the parameter_indexing_CPI_offset parameter, so check this
175
- assert any(cpi_vals) is False
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
@@ -76,9 +76,9 @@
76
76
  }
77
77
  },
78
78
  "parameter_indexing_CPI_offset": {
79
- "title": "Decimal offset ADDED to unchained CPI to get parameter indexing rate",
80
- "description": "Values are zero before 2017; reforms that introduce indexing with chained CPI would have values around -0.0025 beginning in the year before the first year policy parameters will have values computed with chained CPI.",
81
- "notes": "See April 2013 CBO report entitled 'What Would Be the Effect on the Deficit of Using the Chained CPI to Index Benefit Programs and the Tax Code?', which includes this: 'The chained CPI grows more slowly than the traditional CPI does: an average of about 0.25 percentage points more slowly per year over the past decade.' <https://www.cbo.gov/publication/44089>",
79
+ "title": "OBSOLETE: Decimal offset ADDED to unchained CPI to get parameter indexing rate",
80
+ "description": "OBSOLETE policy parameter.",
81
+ "notes": "",
82
82
  "section_1": "Parameter Indexing",
83
83
  "section_2": "Offsets",
84
84
  "indexable": false,
taxcalc/reforms/ext.json CHANGED
@@ -1,5 +1,5 @@
1
1
  // REFORM TO EXTEND TEMPORARY TCJA PROVISIONS BEYOND 2025
2
- // USING TAX-CALCULATOR 4.4.1
2
+ // USING TAX-CALCULATOR 4.5.0
3
3
  // WITH 2025-to-2026 INDEXING FACTOR = 1.022300
4
4
  // AND 2028-to-2029 INDEXING FACTOR = 1.022600
5
5
  {
@@ -32,7 +32,10 @@
32
32
  "PT_rt7": {"2026": 0.37},
33
33
  "PT_brk7": {"2026": [9e+99, 9e+99, 9e+99, 9e+99, 9e+99]},
34
34
  "CTC_c": {"2026": 2000.00},
35
- "ACTC_c": {"2026": 1700.00},
35
+ "ACTC_c": {"2026": 1776.67},
36
+ "ACTC_c-indexed": {"2026": true},
37
+ "ACTC_c": {"2032": 2000.00},
38
+ "ACTC_c-indexed": {"2032": false},
36
39
  "ODC_c": {"2026": 500.00},
37
40
  "CTC_ps": {"2026": [200000.0, 400000.0, 200000.0, 200000.0, 400000.0]},
38
41
  "ACTC_Income_thd": {"2026": 2500.00},