From d5c07ea8a95b3a1d976086bdbedbf620a069b563 Mon Sep 17 00:00:00 2001 From: "martin.holmer@gmail.com" Date: Sun, 27 Oct 2024 17:27:24 -0400 Subject: [PATCH 1/9] Changes for version 4.3.1 --- docs/about/releases.md | 18 ++++++++++++++++++ docs/index.md | 2 +- setup.py | 2 +- taxcalc/__init__.py | 2 +- taxcalc/reforms/ext.json | 2 +- 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/docs/about/releases.md b/docs/about/releases.md index 3489c2659..eef8b8ead 100644 --- a/docs/about/releases.md +++ b/docs/about/releases.md @@ -4,6 +4,24 @@ Go [here](https://github.com/PSLmodels/Tax-Calculator/pulls?q=is%3Apr+is%3Aclose for a complete commit history. +2024-10-28 Release 4.3.1 +------------------------ +(last merged pull request is +[#2828](https://github.com/PSLmodels/Tax-Calculator/pull/2828)) + +**This is a minor enhancement release.** + +**API Changes** + +**New Features** +- Remove PT_qbid_limit_switch parameter and it's assocated False code +[[#2823](https://github.com/PSLmodels/Tax-Calculator/pull/2823) by Martin Holmer] +- Add checking of Python version to the CLI tool, tc +[[#2827](https://github.com/PSLmodels/Tax-Calculator/pull/2827) by Martin Holmer] +- Add weights_scale attribute to the Records and Data classes +[[#2828](https://github.com/PSLmodels/Tax-Calculator/pull/2828) by Martin Holmer] + + 2024-10-02 Release 4.3.0 ------------------------ (last merged pull request is diff --git a/docs/index.md b/docs/index.md index f9915742b..f9c8bf320 100644 --- a/docs/index.md +++ b/docs/index.md @@ -57,7 +57,7 @@ The cross-model validation work with NBER's TAXSIM-27 model is described ## Latest release -{doc}`4.3.0 (2024-10-02) ` +{doc}`4.3.1 (2024-10-28) ` If you are already using Tax-Calculator, upgrade using the following command: diff --git a/setup.py b/setup.py index 1e437afc2..29d2bcea6 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ with open("README.md") as f: longdesc = f.read() -version = "4.3.0" +version = "4.3.1" config = { "description": "Tax Calculator", diff --git a/taxcalc/__init__.py b/taxcalc/__init__.py index 01a5efa20..702744be1 100644 --- a/taxcalc/__init__.py +++ b/taxcalc/__init__.py @@ -14,6 +14,6 @@ from taxcalc.utils import * from taxcalc.cli import * -__version__ = '4.3.0e' +__version__ = '4.3.1' __min_python3_version__ = 10 __max_python3_version__ = 12 diff --git a/taxcalc/reforms/ext.json b/taxcalc/reforms/ext.json index 7b67bbe76..f3b624e1b 100644 --- a/taxcalc/reforms/ext.json +++ b/taxcalc/reforms/ext.json @@ -1,5 +1,5 @@ // REFORM TO EXTEND TEMPORARY TCJA PROVISIONS BEYOND 2025 -// USING TAX-CALCULATOR 4.3.0 +// USING TAX-CALCULATOR 4.3.1 // WITH 2025-to-2026 INDEXING FACTOR = 1.022000 // AND 2028-to-2029 INDEXING FACTOR = 1.019400 { From 9f5bc41a4f52ce142afb892ec53fe151c6055410 Mon Sep 17 00:00:00 2001 From: "martin.holmer@gmail.com" Date: Thu, 7 Nov 2024 09:48:38 -0500 Subject: [PATCH 2/9] Fix handling of tmd_growfactors.csv file --- taxcalc.egg-info/PKG-INFO | 2 +- taxcalc/growfactors.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/taxcalc.egg-info/PKG-INFO b/taxcalc.egg-info/PKG-INFO index b93fe2de9..59007e8e1 100644 --- a/taxcalc.egg-info/PKG-INFO +++ b/taxcalc.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: taxcalc -Version: 4.3.0 +Version: 4.3.1 Summary: taxcalc Home-page: https://github.com/PSLmodels/Tax-Calculator Download-URL: https://github.com/PSLmodels/Tax-Calculator diff --git a/taxcalc/growfactors.py b/taxcalc/growfactors.py index 336d8ae74..8be68f1fb 100644 --- a/taxcalc/growfactors.py +++ b/taxcalc/growfactors.py @@ -38,7 +38,7 @@ class instance: GrowFactors which is for use with puf and cps data from the taxdata repository. """ - PACKAGE_FILE_NAMES = ['growfactors.csv', 'tmd_growfactors.csv'] + PACKAGE_FILE_NAMES = ['growfactors.csv'] FILE_PATH = os.path.abspath(os.path.dirname(__file__)) VALID_NAMES = set(['ABOOK', 'ACGNS', 'ACPIM', 'ACPIU', From 73b0aee5ee3adadda5b9ae47eace4d8e6ef92659 Mon Sep 17 00:00:00 2001 From: "martin.holmer@gmail.com" Date: Thu, 7 Nov 2024 14:48:28 -0500 Subject: [PATCH 3/9] Fix bug introduced in PR #2401: Use ParamTools --- taxcalc/calculator.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/taxcalc/calculator.py b/taxcalc/calculator.py index af2abbd84..014ae2369 100644 --- a/taxcalc/calculator.py +++ b/taxcalc/calculator.py @@ -1189,12 +1189,14 @@ def lines(text, num_indent_spaces, max_line_length=77): for pname in baseline.keys(): upda_value = getattr(updated, pname) base_value = getattr(baseline, pname) - if ( - (isinstance(upda_value, np.ndarray) and - np.allclose(upda_value, base_value)) or - (not isinstance(upda_value, np.ndarray) and - upda_value != base_value) - ): + is_diff = False + if isinstance(upda_value, np.ndarray): + if not np.allclose(upda_value, base_value): + is_diff = True + else: + if upda_value != base_value: + is_diff = True + if is_diff: params_with_diff.append(pname) if params_with_diff: mdata_base = baseline.specification(meta_data=True) From fb58222adddfc8b25d0257bbb5fb315aa0b27ce7 Mon Sep 17 00:00:00 2001 From: "martin.holmer@gmail.com" Date: Thu, 7 Nov 2024 15:31:12 -0500 Subject: [PATCH 4/9] Minor revision to test_taxcalcio.py --- taxcalc.egg-info/PKG-INFO | 2 +- taxcalc/tests/test_taxcalcio.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/taxcalc.egg-info/PKG-INFO b/taxcalc.egg-info/PKG-INFO index b93fe2de9..59007e8e1 100644 --- a/taxcalc.egg-info/PKG-INFO +++ b/taxcalc.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: taxcalc -Version: 4.3.0 +Version: 4.3.1 Summary: taxcalc Home-page: https://github.com/PSLmodels/Tax-Calculator Download-URL: https://github.com/PSLmodels/Tax-Calculator diff --git a/taxcalc/tests/test_taxcalcio.py b/taxcalc/tests/test_taxcalcio.py index edf1793e0..891d9df75 100644 --- a/taxcalc/tests/test_taxcalcio.py +++ b/taxcalc/tests/test_taxcalcio.py @@ -88,7 +88,7 @@ def fixture_reformfile1(): "II_em": { // personal exemption amount (see indexing changes below) "2016": 6000, "2018": 7500, - "2020": 9000}, + "2021": 9000}, "II_em-indexed": { // personal exemption amount indexing status "2016": false, // values in future years are same as this year value "2018": true // values in future years indexed with this year as base From 52460b360d1e63d34d7764a73ec4bff94c17b104 Mon Sep 17 00:00:00 2001 From: "martin.holmer@gmail.com" Date: Thu, 7 Nov 2024 15:39:42 -0500 Subject: [PATCH 5/9] Consolidate logical statements --- taxcalc/calculator.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/taxcalc/calculator.py b/taxcalc/calculator.py index 014ae2369..fe5e9a21c 100644 --- a/taxcalc/calculator.py +++ b/taxcalc/calculator.py @@ -1189,14 +1189,9 @@ def lines(text, num_indent_spaces, max_line_length=77): for pname in baseline.keys(): upda_value = getattr(updated, pname) base_value = getattr(baseline, pname) - is_diff = False - if isinstance(upda_value, np.ndarray): - if not np.allclose(upda_value, base_value): - is_diff = True - else: - if upda_value != base_value: - is_diff = True - if is_diff: + isarray = isinstance(upda_value, np.ndarray) + if ((isarray and not np.allclose(upda_value, base_value)) + or (not is_array and upda_value != base_value)): params_with_diff.append(pname) if params_with_diff: mdata_base = baseline.specification(meta_data=True) From 4bdaef3dc4ae1ba91fbe7876a91849dc24cf1516 Mon Sep 17 00:00:00 2001 From: "martin.holmer@gmail.com" Date: Thu, 7 Nov 2024 16:00:28 -0500 Subject: [PATCH 6/9] Additional logic revision; fix too long a line --- taxcalc/calculator.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/taxcalc/calculator.py b/taxcalc/calculator.py index fe5e9a21c..353d09959 100644 --- a/taxcalc/calculator.py +++ b/taxcalc/calculator.py @@ -698,7 +698,8 @@ def mtr(self, variable_str='e00200p', self.policy_param('FICA_ss_trt_employee') + self.policy_param('FICA_mc_trt_employer') + self.policy_param('FICA_mc_trt_employee')), - 0.5 * (self.policy_param('FICA_mc_trt_employer') + self.policy_param('FICA_mc_trt_employee'))) + 0.5 * (self.policy_param('FICA_mc_trt_employer') + + self.policy_param('FICA_mc_trt_employee'))) else: adj = 0.0 # compute marginal tax rates @@ -1189,9 +1190,11 @@ def lines(text, num_indent_spaces, max_line_length=77): for pname in baseline.keys(): upda_value = getattr(updated, pname) base_value = getattr(baseline, pname) - isarray = isinstance(upda_value, np.ndarray) - if ((isarray and not np.allclose(upda_value, base_value)) - or (not is_array and upda_value != base_value)): + is_array = isinstance(upda_value, np.ndarray) + if ( + (is_array and not np.allclose(upda_value, base_value)) + or (is_array == False and upda_value != base_value) + ): params_with_diff.append(pname) if params_with_diff: mdata_base = baseline.specification(meta_data=True) From ef34d5ad8348aa688682af55c0c48815bdb3cbed Mon Sep 17 00:00:00 2001 From: "martin.holmer@gmail.com" Date: Thu, 7 Nov 2024 18:03:34 -0500 Subject: [PATCH 7/9] Fix indentation of statement in calculator.py module --- taxcalc/calculator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/taxcalc/calculator.py b/taxcalc/calculator.py index 353d09959..d0b92a598 100644 --- a/taxcalc/calculator.py +++ b/taxcalc/calculator.py @@ -1248,7 +1248,7 @@ def lines(text, num_indent_spaces, max_line_length=77): else: # if baseline is GrowDiff object # each GrowDiff parameter has zero as default value doc += ' baseline_value: 0.0\n' - del mdata_base + del mdata_base return doc # begin main logic of reform_documentation From fad07461f0a88f4b90cbcf0f1a3282746abbbf57 Mon Sep 17 00:00:00 2001 From: "martin.holmer@gmail.com" Date: Thu, 7 Nov 2024 18:04:52 -0500 Subject: [PATCH 8/9] Update T-C version --- taxcalc/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/taxcalc/__init__.py b/taxcalc/__init__.py index 702744be1..96858709e 100644 --- a/taxcalc/__init__.py +++ b/taxcalc/__init__.py @@ -14,6 +14,6 @@ from taxcalc.utils import * from taxcalc.cli import * -__version__ = '4.3.1' +__version__ = '4.3.1a' __min_python3_version__ = 10 __max_python3_version__ = 12 From ed04183245ba75c073a093a7e3a15cd75c4823e4 Mon Sep 17 00:00:00 2001 From: "martin.holmer@gmail.com" Date: Fri, 8 Nov 2024 09:53:48 -0500 Subject: [PATCH 9/9] Add Policy.tmd_constructor static method --- taxcalc/__init__.py | 2 +- taxcalc/policy.py | 19 ++++++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/taxcalc/__init__.py b/taxcalc/__init__.py index 96858709e..01e8fef75 100644 --- a/taxcalc/__init__.py +++ b/taxcalc/__init__.py @@ -14,6 +14,6 @@ from taxcalc.utils import * from taxcalc.cli import * -__version__ = '4.3.1a' +__version__ = '4.3.1b' __min_python3_version__ = 10 __max_python3_version__ = 12 diff --git a/taxcalc/policy.py b/taxcalc/policy.py index ad9b69d89..4f1fa29a9 100644 --- a/taxcalc/policy.py +++ b/taxcalc/policy.py @@ -7,6 +7,7 @@ import os import json +from pathlib import Path import numpy as np from taxcalc.parameters import Parameters from taxcalc.growfactors import GrowFactors @@ -80,7 +81,7 @@ class instance: Policy # (3) specify which Policy parameters are wage (rather than price) indexed WAGE_INDEXED_PARAMS = ['SS_Earnings_c', 'SS_Earnings_thd'] - def __init__(self, gfactors=None, only_reading_defaults=False, **kwargs): + def __init__(self, gfactors=None, **kwargs): # put JSON contents of DEFAULTS_FILE_NAME into self._vals dictionary super().__init__() # handle gfactors argument @@ -92,7 +93,6 @@ def __init__(self, gfactors=None, only_reading_defaults=False, **kwargs): raise ValueError('gfactors is not None or a GrowFactors instance') # read default parameters and initialize syr = Policy.JSON_START_YEAR - lyr = Policy.LAST_BUDGET_YEAR nyrs = Policy.DEFAULT_NUM_YEARS self._inflation_rates = None self._wage_growth_rates = None @@ -101,6 +101,19 @@ def __init__(self, gfactors=None, only_reading_defaults=False, **kwargs): Policy.REDEFINED_PARAMS, Policy.WAGE_INDEXED_PARAMS, **kwargs) + @staticmethod + def tmd_constructor(growfactors_path): # pragma: no cover + """ + Static method returns a Policy object instantiated with TMD + input data. This convenience method works in a analogous way + to Policy(), which returns a Policy object instantiated with + non-TMD input data. + """ + assert isinstance(growfactors_path, Path) + gf_filename = str(growfactors_path) + tmd_growfactors = GrowFactors(growfactors_filename=gf_filename) + return Policy(gfactors=tmd_growfactors) + @staticmethod def read_json_reform(obj): """ @@ -129,7 +142,7 @@ def parameter_list(): Policy.DEFAULTS_FILE_PATH, Policy.DEFAULTS_FILE_NAME ) - with open(path) as f: + with open(path, 'r', encoding='utf-8') as f: defaults = json.loads(f.read()) # pylint: disable=protected-access return [k for k in defaults if k != "schema"]