Skip to content

Commit b32b7e8

Browse files
committed
Merge remote-tracking branch 'upstream/master' into as/baseline_2026feb
2 parents 23da4ce + 10b9a97 commit b32b7e8

37 files changed

+1080
-388
lines changed

.github/workflows/check_black.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ jobs:
77
lint:
88
runs-on: ubuntu-latest
99
steps:
10-
- uses: actions/checkout@v2
10+
- uses: actions/checkout@v5
1111
- uses: actions/setup-python@v2
1212
- uses: psf/black@stable
1313
with:
14-
options: " --check"
14+
options: "-l 79 --check"
1515
src: "."

.github/workflows/deploy_docs.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,16 @@ jobs:
99
runs-on: ubuntu-latest
1010
steps:
1111
- name: Checkout
12-
uses: actions/checkout@v2 # If you're using actions/checkout@v2 you must set persist-credentials to false in most cases for the deployment to work correctly.
12+
uses: actions/checkout@v5
1313
with:
1414
persist-credentials: false
1515

1616
- name: Setup Miniconda
17-
uses: conda-incubator/setup-miniconda@v2
17+
uses: conda-incubator/setup-miniconda@v3
1818
with:
1919
activate-environment: taxdata-dev
2020
environment-file: environment.yml
21-
python-version: 3.7
21+
python-version: 3.13
2222
auto-activate-base: false
2323

2424
- name: Build # Build Jupyter Book

.github/workflows/docs_check.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,16 @@ jobs:
66
runs-on: ubuntu-latest
77
steps:
88
- name: Checkout
9-
uses: actions/checkout@v2 # If you're using actions/checkout@v2 you must set persist-credentials to false in most cases for the deployment to work correctly.
9+
uses: actions/checkout@v5
1010
with:
1111
persist-credentials: false
1212

1313
- name: Setup Miniconda
14-
uses: conda-incubator/setup-miniconda@v2
14+
uses: conda-incubator/setup-miniconda@v3
1515
with:
1616
activate-environment: taxdata-dev
1717
environment-file: environment.yml
18-
python-version: 3.7
18+
python-version: 3.13
1919
auto-activate-base: false
2020

2121
- name: Build # Build Jupyter Book

.github/workflows/test.yml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
1-
name: Test data
1+
name: Test source code
22

33
on: [push, pull_request]
44

55
jobs:
66
build:
7-
runs-on: ubuntu-latest
7+
runs-on: ${{ matrix.os }}
88
strategy:
99
matrix:
10-
python-version: [3.7]
10+
os: [ubuntu-latest, windows-latest]
11+
python-version: ['3.11', '3.12', '3.13']
12+
1113
steps:
1214
- name: checkout
1315
uses: actions/checkout@master
1416
with:
1517
persist-credentials: false
1618

1719
- name: Setup Miniconda using Python ${{ matrix.python-version }}
18-
uses: conda-incubator/setup-miniconda@v2
20+
uses: conda-incubator/setup-miniconda@v3
1921
with:
2022
activate-environment: taxdata-dev
2123
environment-file: environment.yml

cps_stage2/dataprep.py

Lines changed: 72 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,16 @@ def target(target_val, pop, factor, value):
2424
weights * factors["APOPSNR"][year],
2525
weights * factors["ARETS"][year],
2626
)
27-
single_returns = np.where((data["mars"] == 1) & (data["filer"] == 1), s006, 0)
28-
joint_returns = np.where((data["mars"] == 2) & (data["filer"] == 1), s006, 0)
27+
single_returns = np.where(
28+
(data["mars"] == 1) & (data["filer"] == 1), s006, 0
29+
)
30+
joint_returns = np.where(
31+
(data["mars"] == 2) & (data["filer"] == 1), s006, 0
32+
)
2933
hh_returns = np.where((data["mars"] == 4) & (data["filer"] == 1), s006, 0)
30-
returns_w_ss = np.where((data["e02400"] > 0) & (data["filer"] == 1), s006, 0)
34+
returns_w_ss = np.where(
35+
(data["e02400"] > 0) & (data["filer"] == 1), s006, 0
36+
)
3137
dep_exemptions = (
3238
np.where(data["mars"] == 2, data["XTOT"] - 2, data["XTOT"] - 1) * s006
3339
)
@@ -45,27 +51,39 @@ def target(target_val, pop, factor, value):
4551
# wage distribution
4652
wage1 = np.where(data["agi"] <= 10000, data["e00200"], 0) * s006
4753
wage2 = (
48-
np.where((data["agi"] > 10000) & (data["agi"] <= 20000), data["e00200"], 0)
54+
np.where(
55+
(data["agi"] > 10000) & (data["agi"] <= 20000), data["e00200"], 0
56+
)
4957
* s006
5058
)
5159
wage3 = (
52-
np.where((data["agi"] > 20000) & (data["agi"] <= 30000), data["e00200"], 0)
60+
np.where(
61+
(data["agi"] > 20000) & (data["agi"] <= 30000), data["e00200"], 0
62+
)
5363
* s006
5464
)
5565
wage4 = (
56-
np.where((data["agi"] > 30000) & (data["agi"] <= 40000), data["e00200"], 0)
66+
np.where(
67+
(data["agi"] > 30000) & (data["agi"] <= 40000), data["e00200"], 0
68+
)
5769
* s006
5870
)
5971
wage5 = (
60-
np.where((data["agi"] > 40000) & (data["agi"] <= 50000), data["e00200"], 0)
72+
np.where(
73+
(data["agi"] > 40000) & (data["agi"] <= 50000), data["e00200"], 0
74+
)
6175
* s006
6276
)
6377
wage6 = (
64-
np.where((data["agi"] > 50000) & (data["agi"] <= 75000), data["e00200"], 0)
78+
np.where(
79+
(data["agi"] > 50000) & (data["agi"] <= 75000), data["e00200"], 0
80+
)
6581
* s006
6682
)
6783
wage7 = (
68-
np.where((data["agi"] > 75000) & (data["agi"] <= 100_000), data["e00200"], 0)
84+
np.where(
85+
(data["agi"] > 75000) & (data["agi"] <= 100_000), data["e00200"], 0
86+
)
6987
* s006
7088
)
7189
wage8 = np.where(data["agi"] > 100_000, data["e00200"], 0) * s006
@@ -118,15 +136,27 @@ def target(target_val, pop, factor, value):
118136
target_name = "SS_return"
119137
rhs_vars["returns_w_ss"] = targets[year][target_name] - returns_w_ss.sum()
120138
target_name = "Dep_return"
121-
rhs_vars["dep_exemptions"] = targets[year][target_name] - dep_exemptions.sum()
122-
rhs_vars["interest"] = target(targets[year]["INTS"], apopn, aints, interest.sum())
123-
rhs_vars["dividend"] = target(targets[year]["DIVS"], apopn, adivs, dividend.sum())
139+
rhs_vars["dep_exemptions"] = (
140+
targets[year][target_name] - dep_exemptions.sum()
141+
)
142+
rhs_vars["interest"] = target(
143+
targets[year]["INTS"], apopn, aints, interest.sum()
144+
)
145+
rhs_vars["dividend"] = target(
146+
targets[year]["DIVS"], apopn, adivs, dividend.sum()
147+
)
124148
rhs_vars["biz_income"] = target(
125149
targets[year]["SCHCI"], apopn, aschci, biz_income.sum()
126150
)
127-
rhs_vars["biz_loss"] = target(targets[year]["SCHCL"], apopn, aschcl, biz_loss.sum())
128-
rhs_vars["cap_gain"] = target(targets[year]["CGNS"], apopn, acgns, cap_gain.sum())
129-
rhs_vars["pension"] = target(targets[year]["Pension"], apopn, atxpy, pension.sum())
151+
rhs_vars["biz_loss"] = target(
152+
targets[year]["SCHCL"], apopn, aschcl, biz_loss.sum()
153+
)
154+
rhs_vars["cap_gain"] = target(
155+
targets[year]["CGNS"], apopn, acgns, cap_gain.sum()
156+
)
157+
rhs_vars["pension"] = target(
158+
targets[year]["Pension"], apopn, atxpy, pension.sum()
159+
)
130160
rhs_vars["sch_e_income"] = target(
131161
targets[year]["SCHEI"], apopn, aschei, sch_e_income.sum()
132162
)
@@ -136,15 +166,33 @@ def target(target_val, pop, factor, value):
136166
rhs_vars["ss_income"] = target(
137167
targets[year]["SS"], apopsnr, asocsec, ss_income.sum()
138168
)
139-
rhs_vars["ucomp"] = target(targets[year]["UCOMP"], apopn, aucomp, ucomp.sum())
140-
rhs_vars["wage1"] = target(targets[year]["wage1"], apopn, awage, wage1.sum())
141-
rhs_vars["wage2"] = target(targets[year]["wage2"], apopn, awage, wage2.sum())
142-
rhs_vars["wage3"] = target(targets[year]["wage3"], apopn, awage, wage3.sum())
143-
rhs_vars["wage4"] = target(targets[year]["wage4"], apopn, awage, wage4.sum())
144-
rhs_vars["wage5"] = target(targets[year]["wage5"], apopn, awage, wage5.sum())
145-
rhs_vars["wage6"] = target(targets[year]["wage6"], apopn, awage, wage6.sum())
146-
rhs_vars["wage7"] = target(targets[year]["wage7"], apopn, awage, wage7.sum())
147-
rhs_vars["wage8"] = target(targets[year]["wage8"], apopn, awage, wage8.sum())
169+
rhs_vars["ucomp"] = target(
170+
targets[year]["UCOMP"], apopn, aucomp, ucomp.sum()
171+
)
172+
rhs_vars["wage1"] = target(
173+
targets[year]["wage1"], apopn, awage, wage1.sum()
174+
)
175+
rhs_vars["wage2"] = target(
176+
targets[year]["wage2"], apopn, awage, wage2.sum()
177+
)
178+
rhs_vars["wage3"] = target(
179+
targets[year]["wage3"], apopn, awage, wage3.sum()
180+
)
181+
rhs_vars["wage4"] = target(
182+
targets[year]["wage4"], apopn, awage, wage4.sum()
183+
)
184+
rhs_vars["wage5"] = target(
185+
targets[year]["wage5"], apopn, awage, wage5.sum()
186+
)
187+
rhs_vars["wage6"] = target(
188+
targets[year]["wage6"], apopn, awage, wage6.sum()
189+
)
190+
rhs_vars["wage7"] = target(
191+
targets[year]["wage7"], apopn, awage, wage7.sum()
192+
)
193+
rhs_vars["wage8"] = target(
194+
targets[year]["wage8"], apopn, awage, wage8.sum()
195+
)
148196

149197
model_vars = [
150198
"single_returns",

cps_stage2/stage2.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,9 @@ def main():
6363
for year in range(START_YEAR, END_YEAR + 1):
6464
try:
6565
factor_match = _factors[year].equals(CUR_FACTORS[year])
66-
target_match = stage_2_targets[f"{year}"].equals(CUR_TARGETS[f"{year}"])
66+
target_match = stage_2_targets[f"{year}"].equals(
67+
CUR_TARGETS[f"{year}"]
68+
)
6769
if files_match and factor_match and target_match:
6870
print(f"Skipping {year}")
6971
skipped_years.append(year)

createpuf.py

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,18 @@ def dataprep(data):
4949
"""
5050
# we use a slightly modified version of mars for matching.
5151
# _mars = 1 if single, 3 if HoH, 2 any type of joint filer
52-
data["_mars"] = np.where(data["mars"] == 1, 1, np.where(data["mars"] == 4, 3, 2))
52+
data["_mars"] = np.where(
53+
data["mars"] == 1, 1, np.where(data["mars"] == 4, 3, 2)
54+
)
5355
data["const"] = 1
5456
data["bil"] = np.maximum(0, data["e00900"])
5557
data["fil"] = np.maximum(0, data["e02100"])
5658
data["tpi"] = data[INC_VARS].sum(axis=1)
5759
data["wage_share"] = np.divide(
58-
data["e00200"], data["tpi"], out=np.zeros(data.shape[0]), where=data["tpi"] != 0
60+
data["e00200"],
61+
data["tpi"],
62+
out=np.zeros(data.shape[0]),
63+
where=data["tpi"] != 0,
5964
)
6065
data["cap_inc"] = data[CAP_VARS].sum(axis=1)
6166
data["cap_share"] = np.divide(
@@ -73,25 +78,33 @@ def dataprep(data):
7378
),
7479
0,
7580
)
76-
data["people"] = np.where(data["_mars"] == 2, data["depne"] + 2, data["depne"] + 1)
81+
data["people"] = np.where(
82+
data["_mars"] == 2, data["depne"] + 2, data["depne"] + 1
83+
)
7784
data["people"] = np.minimum(5, data["people"])
7885
wage_flag = (data["e00200"] != 0).astype(int)
7986
# self employment flag
80-
se_flag = np.logical_or(data["e00900"] != 0, data["e02100"] != 0).astype(int)
87+
se_flag = np.logical_or(data["e00900"] != 0, data["e02100"] != 0).astype(
88+
int
89+
)
8190
# income source flags
8291
data["se1"] = np.where(wage_flag & ~se_flag, 1, 0)
8392
data["se2"] = np.where(~wage_flag & se_flag, 1, 0)
8493
data["se3"] = np.where(wage_flag & se_flag, 1, 0)
8594
data["_depne"] = np.where(
86-
np.logical_and(data["mars"] == 3, data["_depne"] == 0), 1, data["_depne"]
95+
np.logical_and(data["mars"] == 3, data["_depne"] == 0),
96+
1,
97+
data["_depne"],
8798
)
8899

89100
return data
90101

91102

92103
# create CPS tax units
93104
print("Creating CPS tax units")
94-
raw_cps = cps.create(DATA_PATH, exportpkl=True, cps_files=[CPS_YEAR], benefits=False)
105+
raw_cps = cps.create(
106+
DATA_PATH, exportpkl=True, cps_files=[CPS_YEAR], benefits=False
107+
)
95108
# minor PUF prep
96109
print("Prepping PUF")
97110
puf2011 = pd.read_csv(Path(DATA_PATH, "puf2011.csv"))
@@ -158,7 +171,9 @@ def dataprep(data):
158171

159172
# merge all the data together
160173
print("Merging matched data")
161-
data = pd.merge(raw_puf, match_index, how="inner", left_on="recid", right_on="recip")
174+
data = pd.merge(
175+
raw_puf, match_index, how="inner", left_on="recid", right_on="recip"
176+
)
162177
data = pd.merge(
163178
data,
164179
filers,

docs/book/content/methods/CBO_Baseline_Updating_Instructions.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ Table VI.C4. Operations of the OASI Trust Fund, Table VI.C4, Column:
9898

9999
Previous: [2023 Report](https://www.ssa.gov/oact/TR/2023/VI_C_SRfyproj.html)
100100

101-
Current: [2023 Report](https://www.ssa.gov/oact/TR/2023/VI_C_SRfyproj.html)
101+
Current: [2024 Report](https://www.ssa.gov/oact/TR/2024/VI_C_SRfyproj.html)
102102

103103
Projections are taken directly from the `Scheduled Benefits: Intermediate Level`
104104
column of this table.
@@ -124,7 +124,7 @@ Manual Instructions:
124124

125125
Source: [CBO Unemployment Compensation projections](https://www.cbo.gov/about/products/baseline-projections-selected-programs#24)
126126

127-
Previous: [June 2024](https://www.cbo.gov/system/files/2024-06/51316-2024-06-unemployment.xlsx)
127+
Previous: [January 2025](https://www.cbo.gov/system/files/2025-01/51316-2025-01-unemployment.xlsx)
128128

129129
Current: [January 2025](https://www.cbo.gov/system/files/2025-01/51316-2025-01-unemployment.xlsx)
130130

environment.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ name: taxdata-dev
22
channels:
33
- conda-forge
44
dependencies:
5-
- python>=3.6.5
6-
- numpy>=1.12.1
7-
- pandas>=0.20.3
5+
- "python>=3.11, <3.14"
6+
- "numpy>=1.26"
7+
- "pandas>=2.2"
8+
- "bokeh>=3.7"
89
- scipy>=0.18.1
9-
- bokeh>=0.12.3
1010
- statsmodels
1111
- pytest
1212
- pulp
@@ -21,9 +21,9 @@ dependencies:
2121
- python-chromedriver-binary
2222
- tabulate
2323
- pre-commit
24-
- taxcalc>=3.5.0
2524
- pip
2625
- pip:
2726
- requests-html
2827
- black
28+
- taxcalc>=5.3.0
2929
- jupyter-book>=0.9.1

0 commit comments

Comments
 (0)