taxcalc 4.4.0__py3-none-any.whl → 4.4.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.
Files changed (46) hide show
  1. taxcalc/__init__.py +1 -1
  2. taxcalc/calcfunctions.py +326 -171
  3. taxcalc/calculator.py +35 -34
  4. taxcalc/cli/tc.py +6 -7
  5. taxcalc/consumption.py +9 -4
  6. taxcalc/data.py +8 -8
  7. taxcalc/decorators.py +3 -3
  8. taxcalc/growdiff.py +5 -0
  9. taxcalc/growfactors.py +1 -1
  10. taxcalc/parameters.py +85 -42
  11. taxcalc/policy.py +1 -1
  12. taxcalc/records.py +1 -0
  13. taxcalc/records_variables.json +6 -0
  14. taxcalc/taxcalcio.py +49 -44
  15. taxcalc/tests/cmpi_cps_expect.txt +6 -6
  16. taxcalc/tests/cmpi_puf_expect.txt +6 -6
  17. taxcalc/tests/conftest.py +42 -41
  18. taxcalc/tests/test_4package.py +9 -7
  19. taxcalc/tests/test_benefits.py +9 -8
  20. taxcalc/tests/test_calcfunctions.py +55 -38
  21. taxcalc/tests/test_calculator.py +11 -6
  22. taxcalc/tests/test_compare.py +44 -50
  23. taxcalc/tests/test_compatible_data.py +9 -7
  24. taxcalc/tests/test_consumption.py +38 -18
  25. taxcalc/tests/test_cpscsv.py +33 -31
  26. taxcalc/tests/test_data.py +31 -24
  27. taxcalc/tests/test_decorators.py +84 -32
  28. taxcalc/tests/test_growdiff.py +16 -13
  29. taxcalc/tests/test_growfactors.py +8 -8
  30. taxcalc/tests/test_parameters.py +54 -58
  31. taxcalc/tests/test_policy.py +14 -12
  32. taxcalc/tests/test_puf_var_stats.py +14 -14
  33. taxcalc/tests/test_pufcsv.py +40 -40
  34. taxcalc/tests/test_records.py +73 -60
  35. taxcalc/tests/test_reforms.py +34 -31
  36. taxcalc/tests/test_responses.py +4 -4
  37. taxcalc/tests/test_taxcalcio.py +76 -62
  38. taxcalc/tests/test_utils.py +78 -46
  39. taxcalc/utils.py +49 -42
  40. taxcalc/validation/taxsim35/taxsim_emulation.json +1 -5
  41. {taxcalc-4.4.0.dist-info → taxcalc-4.4.1.dist-info}/METADATA +19 -5
  42. {taxcalc-4.4.0.dist-info → taxcalc-4.4.1.dist-info}/RECORD +46 -46
  43. {taxcalc-4.4.0.dist-info → taxcalc-4.4.1.dist-info}/WHEEL +1 -1
  44. {taxcalc-4.4.0.dist-info → taxcalc-4.4.1.dist-info}/LICENSE +0 -0
  45. {taxcalc-4.4.0.dist-info → taxcalc-4.4.1.dist-info}/entry_points.txt +0 -0
  46. {taxcalc-4.4.0.dist-info → taxcalc-4.4.1.dist-info}/top_level.txt +0 -0
@@ -38,7 +38,7 @@ def test_make_calculator(cps_subsample):
38
38
  with pytest.raises(ValueError):
39
39
  Calculator(policy=pol, records=None)
40
40
  with pytest.raises(ValueError):
41
- Calculator(policy=pol, records=rec, consumption=list())
41
+ Calculator(policy=pol, records=rec, consumption=[])
42
42
 
43
43
 
44
44
  def test_make_calculator_deepcopy(cps_subsample):
@@ -522,7 +522,7 @@ def test_read_bad_json_assump_file():
522
522
  with pytest.raises(ValueError):
523
523
  Calculator.read_json_param_objects(None, 'unknown_file_name')
524
524
  with pytest.raises(TypeError):
525
- Calculator.read_json_param_objects(None, list())
525
+ Calculator.read_json_param_objects(None, [])
526
526
 
527
527
 
528
528
  def test_json_doesnt_exist():
@@ -629,7 +629,7 @@ def test_reform_documentation():
629
629
  dump = False # set to True to print documentation and force test failure
630
630
  if dump:
631
631
  print(doc)
632
- assert 1 == 2
632
+ assert False, 'ERROR: reform_documentation above'
633
633
 
634
634
 
635
635
  def test_distribution_tables(cps_subsample):
@@ -827,7 +827,7 @@ def test_itemded_component_amounts(year, cvname, hcname, puf_fullsample):
827
827
  itmded1 = calc1.weighted_total('c04470') * 1e-9
828
828
  itmded2 = calc2.weighted_total('c04470') * 1e-9
829
829
  else:
830
- raise ValueError('illegal year value = {}'.format(year))
830
+ raise ValueError(f'illegal year value = {year}')
831
831
  difference_in_total_itmded = itmded1 - itmded2
832
832
  # calculate itemized component amount
833
833
  component_amt = calc1.weighted_total(cvname) * 1e-9
@@ -841,8 +841,11 @@ def test_itemded_component_amounts(year, cvname, hcname, puf_fullsample):
841
841
  else:
842
842
  atol = 0.00001
843
843
  if not np.allclose(component_amt, difference_in_total_itmded, atol=atol):
844
- txt = '\n{}={:.3f} != {:.3f}=difference_in_total_itemized_deductions'
845
- msg = txt.format(cvname, component_amt, difference_in_total_itmded)
844
+ msg = (
845
+ f'\n{cvname}={component_amt:.3f} != '
846
+ f'{difference_in_total_itmded:.3f}='
847
+ 'difference_in_total_itemized_deductions'
848
+ )
846
849
  raise ValueError(msg)
847
850
 
848
851
 
@@ -928,6 +931,8 @@ def test_cg_top_rate():
928
931
  """
929
932
  Test top CG bracket and rate.
930
933
  """
934
+ # pylint: disable=too-many-locals
935
+
931
936
  cy = 2019
932
937
 
933
938
  # set NIIT and STD to zero to isolate CG tax rates
@@ -8,22 +8,21 @@ Compares Tax-Calculator PUF and CPS results with historical information.
8
8
  import os
9
9
  import pytest
10
10
  import numpy as np
11
- # pylint: disable=import-error,pointless-string-statement
12
- from taxcalc import Policy, Records, Calculator
13
- from taxcalc import add_income_table_row_variable, SOI_AGI_BINS
11
+ from taxcalc.policy import Policy
12
+ from taxcalc.records import Records
13
+ from taxcalc.calculator import Calculator
14
+ from taxcalc.utils import add_income_table_row_variable, SOI_AGI_BINS
14
15
 
15
16
 
16
- """
17
- 2015 IRS-SOI amounts by AGI category are from "Table 3.3 All Returns: Tax
18
- Liability, Tax Credits, and Tax Payments by Size of Adjusted Gross Income,
19
- Tax Year 2015" which is available as a spreadsheet at this URL:
20
- <https://www.irs.gov/statistics/soi-tax-stats-individual-
21
- statistical-tables-by-size-of-adjusted-gross-income>
22
- The IRS-SOI amounts are from 19 rows in the spreadsheet numbered from
23
- 11 (AGI under one dollar) through 29 (AGI $10M or more).
24
- Dollar IRS-SOI amounts are expressed in billions of dollars and rounded
25
- to the nearest one-tenth of a million dollars.
26
- """
17
+ # 2015 IRS-SOI amounts by AGI category are from "Table 3.3 All Returns: Tax
18
+ # Liability, Tax Credits, and Tax Payments by Size of Adjusted Gross Income,
19
+ # Tax Year 2015" which is available as a spreadsheet at this URL:
20
+ # <https://www.irs.gov/statistics/soi-tax-stats-individual-
21
+ # statistical-tables-by-size-of-adjusted-gross-income>
22
+ # The IRS-SOI amounts are from 19 rows in the spreadsheet numbered from
23
+ # 11 (AGI under one dollar) through 29 (AGI $10M or more).
24
+ # Dollar IRS-SOI amounts are expressed in billions of dollars and rounded
25
+ # to the nearest one-tenth of a million dollars.
27
26
  ITAX = {
28
27
  '0:EITC': {
29
28
  # Full earned income credit
@@ -204,11 +203,12 @@ def comparison(cname, calc, cmpdata, ofile):
204
203
  # construct AGI table
205
204
  vardf = add_income_table_row_variable(vardf, 'c00100', SOI_AGI_BINS)
206
205
  gbydf = vardf.groupby('table_row', as_index=False)
207
- # write AGI table with ALL row at bottom to ofile
208
- ofile.write('TABLE for {}\n'.format(cname.split(':')[1]))
206
+ # write AGI table with ALL row at bottom of ofile
207
+ ofile.write(f'TABLE for {cname.split(":")[1]}\n')
209
208
  results = '{:23s}\t{:8.3f}\t{:8.3f}\t{:+6.1f}\n'
210
- colhead = '{:23s}\t{:>8s}\t{:>8s}\t{:>6s}\n'
211
- ofile.write(colhead.format('AGI category', 'T-C', 'SOI', '%diff'))
209
+ colhead = f'{"AGIcategory":23s}\t{"T-C":>8s}\t{"SOI":>8s}\t{"%diff":>6s}\n'
210
+ ofile.write(colhead)
211
+ # pylint: disable=consider-using-f-string
212
212
  txc_tot = 0.
213
213
  soi_tot = 0.
214
214
  idx = 0
@@ -221,12 +221,12 @@ def comparison(cname, calc, cmpdata, ofile):
221
221
  pct_diff = 100. * ((txc / soi) - 1.)
222
222
  else:
223
223
  pct_diff = np.nan
224
- glabel = '[{:.8g}, {:.8g})'.format(grp_interval.left,
225
- grp_interval.right)
224
+ glabel = f'[{grp_interval.left:.8g}, {grp_interval.right:.8g})'
226
225
  ofile.write(results.format(glabel, txc, soi, pct_diff))
227
226
  idx += 1
228
227
  pct_diff = 100. * ((txc_tot / soi_tot) - 1.)
229
228
  ofile.write(results.format('ALL', txc_tot, soi_tot, pct_diff))
229
+ # pylint: enable=consider-using-f-string
230
230
 
231
231
 
232
232
  def nonsmall_diffs(linelist1, linelist2, small=0.0):
@@ -256,24 +256,20 @@ def nonsmall_diffs(linelist1, linelist2, small=0.0):
256
256
  for line1, line2 in zip(linelist1, linelist2):
257
257
  if line1 == line2:
258
258
  continue
259
- else:
260
- tokens1 = line1.replace(',', '').split()
261
- tokens2 = line2.replace(',', '').split()
262
- for tok1, tok2 in zip(tokens1, tokens2):
263
- tok1_isfloat = isfloat(tok1)
264
- tok2_isfloat = isfloat(tok2)
265
- if tok1_isfloat and tok2_isfloat:
266
- if abs(float(tok1) - float(tok2)) <= smallamt:
267
- continue
268
- else:
269
- return True
270
- elif not tok1_isfloat and not tok2_isfloat:
271
- if tok1 == tok2:
272
- continue
273
- else:
274
- return True
275
- else:
276
- return True
259
+ tokens1 = line1.replace(',', '').split()
260
+ tokens2 = line2.replace(',', '').split()
261
+ for tok1, tok2 in zip(tokens1, tokens2):
262
+ tok1_isfloat = isfloat(tok1)
263
+ tok2_isfloat = isfloat(tok2)
264
+ if tok1_isfloat and tok2_isfloat:
265
+ if abs(float(tok1) - float(tok2)) <= smallamt:
266
+ continue
267
+ return True
268
+ if not tok1_isfloat and not tok2_isfloat:
269
+ if tok1 == tok2:
270
+ continue
271
+ return True
272
+ return True
277
273
  return False
278
274
 
279
275
 
@@ -281,9 +277,9 @@ def differences(afilename, efilename):
281
277
  """
282
278
  Check for differences between results in afilename and efilename files.
283
279
  """
284
- with open(afilename, 'r') as afile:
280
+ with open(afilename, 'r', encoding='utf-8') as afile:
285
281
  actres = afile.read()
286
- with open(efilename, 'r') as efile:
282
+ with open(efilename, 'r', encoding='utf-8') as efile:
287
283
  expres = efile.read()
288
284
  diffs = nonsmall_diffs(actres.splitlines(True),
289
285
  expres.splitlines(True), 0.0)
@@ -292,12 +288,12 @@ def differences(afilename, efilename):
292
288
  efname = os.path.basename(efilename)
293
289
  msg = 'COMPARE RESULTS DIFFER\n'
294
290
  msg += '-------------------------------------------------\n'
295
- msg += '--- NEW RESULTS IN {} FILE ---\n'
296
- msg += '--- if new OK, copy {} to ---\n'
297
- msg += '--- {} ---\n'
291
+ msg += f'--- NEW RESULTS IN {afname} FILE ---\n'
292
+ msg += f'--- if new OK, copy {afname} to ---\n'
293
+ msg += f'--- {efname} ---\n'
298
294
  msg += '--- and rerun test. ---\n'
299
295
  msg += '-------------------------------------------------\n'
300
- raise ValueError(msg.format(afname, afname, efname))
296
+ raise ValueError(msg)
301
297
  os.remove(afilename)
302
298
 
303
299
 
@@ -325,12 +321,10 @@ def test_itax_compare(tests_path, using_puf, puf_fullsample, cps_fullsample):
325
321
  afilename = os.path.join(tests_path, 'cmpi_puf_actual.txt')
326
322
  else:
327
323
  afilename = os.path.join(tests_path, 'cmpi_cps_actual.txt')
328
- afile = open(afilename, 'w')
329
- # write compare results to afile
330
- for cname in sorted(ITAX.keys()):
331
- comparison(cname, calc, ITAX, afile)
332
- # close actual output file
333
- afile.close()
324
+ with open(afilename, 'w', encoding='utf-8') as afile:
325
+ # write compare results to afile
326
+ for cname in sorted(ITAX.keys()):
327
+ comparison(cname, calc, ITAX, afile)
334
328
  # check for differences between actual and expect output files
335
329
  efilename = afilename.replace('actual', 'expect')
336
330
  differences(afilename, efilename)
@@ -12,7 +12,9 @@ plug-in pytest-xdist is able to run all parametrized functions in parallel
12
12
  import copy
13
13
  import pytest
14
14
  import numpy as np
15
- from taxcalc import Policy, Records, Calculator # pylint: disable=import-error
15
+ from taxcalc.policy import Policy
16
+ from taxcalc.records import Records
17
+ from taxcalc.calculator import Calculator
16
18
 
17
19
 
18
20
  @pytest.fixture(scope='module', name='allparams')
@@ -49,7 +51,7 @@ def test_compatible_data_presence(allparams):
49
51
  return True
50
52
 
51
53
  # Main logic of test_compatible_data_presence function
52
- problem_pnames = list()
54
+ problem_pnames = []
53
55
  for pname in allparams:
54
56
  if 'compatible_data' in allparams[pname]:
55
57
  compatible_data = allparams[pname]['compatible_data']
@@ -61,7 +63,7 @@ def test_compatible_data_presence(allparams):
61
63
  msg = '{} has no or invalid compatible_data field'
62
64
  for pname in problem_pnames:
63
65
  print(msg.format(pname))
64
- assert 'list of problem_pnames' == 'empty list'
66
+ assert False, 'ERROR: list of problem_pnames is above'
65
67
 
66
68
 
67
69
  XX_YEAR = 2019
@@ -142,7 +144,7 @@ BATCHES = int(np.floor(NPARAMS / BATCHSIZE)) + 1
142
144
 
143
145
 
144
146
  @pytest.fixture(scope='module', name='allparams_batch',
145
- params=[i for i in range(0, BATCHES)])
147
+ params=list(range(0, BATCHES)))
146
148
  def fixture_allparams_batch(request, allparams, sorted_param_names):
147
149
  """
148
150
  Fixture for grouping Tax-Calculator parameters
@@ -229,8 +231,8 @@ def test_compatible_data(cps_subsample, puf_subsample,
229
231
  at least one of these reforms when using datasets marked compatible
230
232
  and does not differ when using datasets marked as incompatible.
231
233
  """
232
- # pylint: disable=too-many-arguments,too-many-locals
233
- # pylint: disable=too-many-statements,too-many-branches
234
+ # pylint: disable=too-many-arguments,too-many-positional-arguments
235
+ # pylint: disable=too-many-statements,too-many-branches,too-many-locals
234
236
 
235
237
  # Check NPARAMS value
236
238
  assert NPARAMS == len(allparams)
@@ -335,4 +337,4 @@ def test_compatible_data(cps_subsample, puf_subsample,
335
337
  # test failure if any errors
336
338
  if errors:
337
339
  print(errors)
338
- assert 'compatible_data' == 'invalid'
340
+ assert False, 'ERROR: compatible_data is invalid; see errors above'
@@ -1,18 +1,24 @@
1
+ """
2
+ Test Consumption class and its methods.
3
+ """
1
4
  # CODING-STYLE CHECKS:
2
5
  # pycodestyle test_consumption.py
6
+ # pylint --disable=locally-disabled test_consumption.py
3
7
 
8
+ import copy
4
9
  import numpy as np
5
- import paramtools
6
10
  import pytest
7
- import copy
11
+ import paramtools
8
12
  from taxcalc import Policy, Records, Calculator, Consumption
9
13
 
10
14
 
11
15
  def test_start_year_consistency():
16
+ """Test docstring"""
12
17
  assert Consumption.JSON_START_YEAR == Policy.JSON_START_YEAR
13
18
 
14
19
 
15
20
  def test_validity_of_consumption_vars_set():
21
+ """Test docstring"""
16
22
  records_varinfo = Records(data=None)
17
23
  assert Consumption.RESPONSE_VARS.issubset(records_varinfo.USABLE_READ_VARS)
18
24
  useable_vars = set(['housing', 'snap', 'tanf', 'vet', 'wic',
@@ -21,6 +27,7 @@ def test_validity_of_consumption_vars_set():
21
27
 
22
28
 
23
29
  def test_update_consumption():
30
+ """Test docstring"""
24
31
  consump = Consumption()
25
32
  consump.update_consumption({})
26
33
  revision = {
@@ -33,21 +40,29 @@ def test_update_consumption():
33
40
  expected_mpc_e20400 = np.full((consump.num_years,), 0.06)
34
41
  expected_mpc_e20400[0] = 0.0
35
42
  expected_mpc_e20400[1] = 0.05
36
- assert np.allclose(consump._MPC_e20400,
37
- expected_mpc_e20400,
38
- rtol=0.0)
39
- assert np.allclose(consump._MPC_e17500,
40
- np.zeros((consump.num_years,)),
41
- rtol=0.0)
43
+ assert np.allclose(
44
+ consump._MPC_e20400, # pylint: disable=protected-access
45
+ expected_mpc_e20400,
46
+ rtol=0.0
47
+ )
48
+ assert np.allclose(
49
+ consump._MPC_e17500, # pylint: disable=protected-access
50
+ np.zeros((consump.num_years,)),
51
+ rtol=0.0
52
+ )
42
53
  expected_ben_mcare_value = np.full((consump.num_years,), 0.80)
43
54
  expected_ben_mcare_value[0] = 1.0
44
55
  expected_ben_mcare_value[1] = 0.75
45
- assert np.allclose(consump._BEN_mcare_value,
46
- expected_ben_mcare_value,
47
- rtol=0.0)
48
- assert np.allclose(consump._BEN_snap_value,
49
- np.ones((consump.num_years,)),
50
- rtol=0.0)
56
+ assert np.allclose(
57
+ consump._BEN_mcare_value, # pylint: disable=protected-access
58
+ expected_ben_mcare_value,
59
+ rtol=0.0
60
+ )
61
+ assert np.allclose(
62
+ consump._BEN_snap_value, # pylint: disable=protected-access
63
+ np.ones((consump.num_years,)),
64
+ rtol=0.0
65
+ )
51
66
  consump.set_year(2015)
52
67
  assert consump.current_year == 2015
53
68
  assert consump.MPC_e20400 == 0.06
@@ -57,6 +72,7 @@ def test_update_consumption():
57
72
 
58
73
 
59
74
  def test_incorrect_update_consumption():
75
+ """Test docstring"""
60
76
  with pytest.raises(paramtools.ValidationError):
61
77
  Consumption().update_consumption([])
62
78
  with pytest.raises(paramtools.ValidationError):
@@ -74,6 +90,7 @@ def test_incorrect_update_consumption():
74
90
 
75
91
 
76
92
  def test_future_update_consumption():
93
+ """Test docstring"""
77
94
  consump = Consumption()
78
95
  assert consump.current_year == consump.start_year
79
96
  assert consump.has_response() is False
@@ -97,6 +114,7 @@ def test_future_update_consumption():
97
114
 
98
115
 
99
116
  def test_consumption_default_data():
117
+ """Test docstring"""
100
118
  consump = Consumption()
101
119
  pdata = consump.specification(meta_data=True, ignore_state=True)
102
120
  for pname in pdata.keys():
@@ -107,24 +125,26 @@ def test_consumption_default_data():
107
125
 
108
126
 
109
127
  def test_consumption_response(cps_subsample):
128
+ """Test docstring"""
129
+ # pylint: disable=too-many-locals
110
130
  consump = Consumption()
111
131
  mpc = 0.5
112
132
  consumption_response = {'MPC_e20400': {2013: mpc}}
113
133
  consump.update_consumption(consumption_response)
114
134
  # test incorrect call to response method
115
135
  with pytest.raises(ValueError):
116
- consump.response(list(), 1)
136
+ consump.response([], 1)
117
137
  # test correct call to response method
118
138
  rec = Records.cps_constructor(data=cps_subsample)
119
- pre = copy.deepcopy(rec.e20400)
139
+ pre = copy.deepcopy(getattr(rec, 'e20400'))
120
140
  consump.response(rec, 1.0)
121
- post = rec.e20400
141
+ post = getattr(rec, 'e20400')
122
142
  actual_diff = post - pre
123
143
  expected_diff = np.ones(rec.array_length) * mpc
124
144
  assert np.allclose(actual_diff, expected_diff)
125
145
  # compute earnings mtr with no consumption response
126
146
  rec = Records.cps_constructor(data=cps_subsample)
127
- ided0 = copy.deepcopy(rec.e20400)
147
+ ided0 = copy.deepcopy(getattr(rec, 'e20400'))
128
148
  calc0 = Calculator(policy=Policy(), records=rec, consumption=None)
129
149
  (mtr0_ptax, mtr0_itax, _) = calc0.mtr(variable_str='e00200p',
130
150
  wrt_full_compensation=False)
@@ -17,8 +17,11 @@ import json
17
17
  import pytest
18
18
  import numpy as np
19
19
  import pandas as pd
20
- # pylint: disable=import-error
21
- from taxcalc import GrowFactors, GrowDiff, Policy, Records, Calculator
20
+ from taxcalc.growfactors import GrowFactors
21
+ from taxcalc.growdiff import GrowDiff
22
+ from taxcalc.policy import Policy
23
+ from taxcalc.records import Records
24
+ from taxcalc.calculator import Calculator
22
25
 
23
26
 
24
27
  START_YEAR = 2017
@@ -52,7 +55,7 @@ def test_agg(tests_path, cps_fullsample):
52
55
  if not np.allclose(adt[icol], edt[str(icol)]):
53
56
  diffs = True
54
57
  if diffs:
55
- new_filename = '{}{}'.format(aggres_path[:-10], 'actual.csv')
58
+ new_filename = f'{aggres_path[:-10]}actual.csv'
56
59
  adt.to_csv(new_filename, float_format='%.1f')
57
60
  msg = 'CPSCSV AGG RESULTS DIFFER\n'
58
61
  msg += '-------------------------------------------------\n'
@@ -65,7 +68,7 @@ def test_agg(tests_path, cps_fullsample):
65
68
  raise ValueError(msg)
66
69
  # create aggregate diagnostic table using unweighted sub-sample of records
67
70
  rn_seed = 180 # to ensure sub-sample is always the same
68
- subfrac = 0.07# 0.03 # sub-sample fraction
71
+ subfrac = 0.07 # sub-sample fraction
69
72
  subsample = cps_fullsample.sample(frac=subfrac, random_state=rn_seed)
70
73
  recs_subsample = Records.cps_constructor(data=subsample)
71
74
  calc_subsample = Calculator(policy=baseline_policy, records=recs_subsample)
@@ -84,14 +87,17 @@ def test_agg(tests_path, cps_fullsample):
84
87
  if not np.allclose(taxes_subsample[cyr], taxes_fullsample[cyr],
85
88
  atol=0.0, rtol=reltol):
86
89
  reldiff = (taxes_subsample[cyr] / taxes_fullsample[cyr]) - 1.
87
- line1 = '\nCPSCSV AGG SUB-vs-FULL RESULTS DIFFER IN {}'
88
- line2 = '\n when subfrac={:.3f}, rtol={:.4f}, seed={}'
89
- line3 = '\n with sub={:.3f}, full={:.3f}, rdiff={:.4f}'
90
- msg += line1.format(cyr)
91
- msg += line2.format(subfrac, reltol, rn_seed)
92
- msg += line3.format(taxes_subsample[cyr],
93
- taxes_fullsample[cyr],
94
- reldiff)
90
+ line1 = f'\nCPSCSV AGG SUB-vs-FULL RESULTS DIFFER IN {cyr}'
91
+ line2 = (
92
+ f'\n when subfrac={subfrac:.3f}, rtol={reltol:.4f}, '
93
+ f'seed={rn_seed}'
94
+ )
95
+ line3 = (
96
+ f'\n with sub={taxes_subsample[cyr]:.3f}, '
97
+ f'full={taxes_fullsample[cyr]:.3f}, '
98
+ f'rdiff={reldiff:.4f}'
99
+ )
100
+ msg += line1 + line2 + line3
95
101
  if msg:
96
102
  raise ValueError(msg)
97
103
 
@@ -104,7 +110,7 @@ def test_cps_availability(tests_path, cps_path):
104
110
  cpsvars = set(list(cpsdf))
105
111
  # make set of variable names that are marked as cps.csv available
106
112
  rvpath = os.path.join(tests_path, '..', 'records_variables.json')
107
- with open(rvpath, 'r') as rvfile:
113
+ with open(rvpath, 'r', encoding='utf-8') as rvfile:
108
114
  rvdict = json.load(rvfile)
109
115
  recvars = set()
110
116
  for vname, vdict in rvdict['read'].items():
@@ -142,24 +148,20 @@ def nonsmall_diffs(linelist1, linelist2, small=0.0):
142
148
  for line1, line2 in zip(linelist1, linelist2):
143
149
  if line1 == line2:
144
150
  continue
145
- else:
146
- tokens1 = line1.replace(',', '').split()
147
- tokens2 = line2.replace(',', '').split()
148
- for tok1, tok2 in zip(tokens1, tokens2):
149
- tok1_isfloat = isfloat(tok1)
150
- tok2_isfloat = isfloat(tok2)
151
- if tok1_isfloat and tok2_isfloat:
152
- if abs(float(tok1) - float(tok2)) <= smallamt:
153
- continue
154
- else:
155
- return True
156
- elif not tok1_isfloat and not tok2_isfloat:
157
- if tok1 == tok2:
158
- continue
159
- else:
160
- return True
161
- else:
162
- return True
151
+ tokens1 = line1.replace(',', '').split()
152
+ tokens2 = line2.replace(',', '').split()
153
+ for tok1, tok2 in zip(tokens1, tokens2):
154
+ tok1_isfloat = isfloat(tok1)
155
+ tok2_isfloat = isfloat(tok2)
156
+ if tok1_isfloat and tok2_isfloat:
157
+ if abs(float(tok1) - float(tok2)) <= smallamt:
158
+ continue
159
+ return True
160
+ if not tok1_isfloat and not tok2_isfloat:
161
+ if tok1 == tok2:
162
+ continue
163
+ return True
164
+ return True
163
165
  return False
164
166
 
165
167
 
@@ -1,5 +1,9 @@
1
+ """
2
+ Test Data class and its methods.
3
+ """
1
4
  # CODING-STYLE CHECKS:
2
5
  # pycodestyle test_data.py
6
+ # pylint --disable=locally-disabled test_data.py
3
7
 
4
8
  import os
5
9
  import tempfile
@@ -75,14 +79,17 @@ def test_recs_class(recs_varinfo_file, cps_subsample):
75
79
  super().__init__(data, start_year, gfactors, weights)
76
80
 
77
81
  def _extrapolate(self, year):
78
- self.e00300 *= self.gfactors.factor_value('AINTS', year)
82
+ val = getattr(self, 'e00300')
83
+ setattr(
84
+ self, 'e00300', val * self.gfactors.factor_value('AINTS', year)
85
+ )
79
86
 
80
- # test Recs class for incorrect instantiation
87
+ # test Recs class for incorrect instantiation:
81
88
  with pytest.raises(ValueError):
82
- Recs(data=list(), start_year=2000,
89
+ Recs(data=[], start_year=2000,
83
90
  gfactors=None, weights=None)
84
91
  with pytest.raises(ValueError):
85
- Recs(data=cps_subsample, start_year=list(),
92
+ Recs(data=cps_subsample, start_year=[],
86
93
  gfactors=None, weights=None)
87
94
  with pytest.raises(ValueError):
88
95
  Recs(data=cps_subsample, start_year=2000,
@@ -93,19 +100,18 @@ def test_recs_class(recs_varinfo_file, cps_subsample):
93
100
  with pytest.raises(ValueError):
94
101
  Recs(data=cps_subsample, start_year=2000,
95
102
  gfactors='', weights='')
96
- # test Recs class for correct instantiation with no aging of data
103
+ # test Recs class for correct instantiation with no aging of data:
97
104
  syr = 2014
98
105
  rec = Recs(data=cps_subsample, start_year=syr,
99
106
  gfactors=None, weights=None)
100
- assert isinstance(rec, Recs)
101
- assert np.all(rec.MARS != 0)
102
- assert rec.data_year == syr
103
- assert rec.current_year == syr
104
- sum_e00300_in_syr = rec.e00300.sum()
107
+ assert np.all(getattr(rec, 'MARS') != 0)
108
+ assert getattr(rec, 'data_year') == syr
109
+ assert getattr(rec, 'current_year') == syr
110
+ sum_e00300_in_syr = getattr(rec, 'e00300').sum()
105
111
  rec.increment_year()
106
- assert rec.data_year == syr
107
- assert rec.current_year == syr + 1
108
- sum_e00300_in_syr_plus_one = rec.e00300.sum()
112
+ assert getattr(rec, 'data_year') == syr
113
+ assert getattr(rec, 'current_year') == syr + 1
114
+ sum_e00300_in_syr_plus_one = getattr(rec, 'e00300').sum()
109
115
  assert np.allclose([sum_e00300_in_syr], [sum_e00300_in_syr_plus_one])
110
116
  del rec
111
117
  # test Recs class for correct instantiation with aging of data
@@ -114,20 +120,21 @@ def test_recs_class(recs_varinfo_file, cps_subsample):
114
120
  rec = Recs(data=cps_subsample, start_year=syr,
115
121
  gfactors=GrowFactors(), weights=wghts_df)
116
122
  assert isinstance(rec, Recs)
117
- assert np.all(rec.MARS != 0)
118
- assert rec.data_year == syr
119
- assert rec.current_year == syr
120
- sum_s006_in_syr = rec.s006.sum()
121
- sum_e00300_in_syr = rec.e00300.sum()
123
+ assert np.all(getattr(rec, 'MARS') != 0)
124
+ assert getattr(rec, 'data_year') == syr
125
+ assert getattr(rec, 'current_year') == syr
126
+ sum_s006_in_syr = getattr(rec, 's006').sum()
127
+ sum_e00300_in_syr = getattr(rec, 'e00300').sum()
122
128
  rec.increment_year()
123
- assert rec.data_year == syr
124
- assert rec.current_year == syr + 1
125
- sum_s006_in_syr_plus_one = rec.s006.sum()
129
+ assert getattr(rec, 'data_year') == syr
130
+ assert getattr(rec, 'current_year') == syr + 1
131
+ sum_s006_in_syr_plus_one = getattr(rec, 's006').sum()
126
132
  assert sum_s006_in_syr_plus_one > sum_s006_in_syr
127
- sum_e00300_in_syr_plus_one = rec.e00300.sum()
133
+ sum_e00300_in_syr_plus_one = getattr(rec, 'e00300').sum()
128
134
  assert sum_e00300_in_syr_plus_one > sum_e00300_in_syr
129
- # test private methods
135
+ # test private methods:
136
+ # pylint: disable=protected-access
130
137
  rec._read_data(data=None)
131
138
  rec._read_weights(weights=None)
132
139
  with pytest.raises(ValueError):
133
- rec._read_weights(weights=list())
140
+ rec._read_weights(weights=[])