diff --git a/changelog.d/add-marginal-rates.added.md b/changelog.d/add-marginal-rates.added.md
new file mode 100644
index 0000000..43df4dd
--- /dev/null
+++ b/changelog.d/add-marginal-rates.added.md
@@ -0,0 +1 @@
+Add TAXSIM-compatible marginal tax rate computation (frate, srate, ficar) via wage perturbation.
diff --git a/dashboard/public/config-data.json b/dashboard/public/config-data.json
index 41a8b76..4798ca8 100644
--- a/dashboard/public/config-data.json
+++ b/dashboard/public/config-data.json
@@ -280,5 +280,5 @@
}
]
},
- "lastUpdated": "2026-03-06T19:56:21.560Z"
+ "lastUpdated": "2026-03-17T17:29:16.416Z"
}
\ No newline at end of file
diff --git a/dashboard/src/components/DocumentationContent.jsx b/dashboard/src/components/DocumentationContent.jsx
index 77647f5..ca37346 100644
--- a/dashboard/src/components/DocumentationContent.jsx
+++ b/dashboard/src/components/DocumentationContent.jsx
@@ -24,7 +24,8 @@ import {
getMultipleVariables
} from '../constants';
-const NON_LINKABLE = ['na_pe', 'taxsimid', 'get_year'];
+const NON_LINKABLE = ['na_pe', 'taxsimid', 'get_year', 'marginal_rate_computed'];
+const ADJUSTED_VARIABLES = ['federal_marginal_tax_rate', 'state_marginal_tax_rate', 'fica_marginal_tax_rate'];
const LANG_LABELS = {
cli: 'CLI',
@@ -276,7 +277,13 @@ policyengine_versions()
}
if (mapping.implemented && mapping.policyengine && !NON_LINKABLE.includes(mapping.policyengine)) {
- return
Marginal tax rates (frate, srate, ficar)
+
+ Marginal rates are based on PolicyEngine's federal_marginal_tax_rate,{' '}
+ state_marginal_tax_rate, and{' '}
+ fica_marginal_tax_rate variables,
+ with adjustments to match TAXSIM-35 methodology:
+
mtr=11)frate), state income tax (srate), and employee payroll tax (ficar)+ Note: PolicyEngine's upstream MTR variables perturb all earned income (including self-employment) and use a different delta. + The emulator adjusts the computation to match TAXSIM's wage-only perturbation and uses a $100 delta + (vs TAXSIM's $0.01 with Fortran float64) for numerical stability with PolicyEngine's float32 internals. +
+logs
@@ -895,6 +927,11 @@ policyengine-taxsim policyengine input.csv --disable-salt --assume-w2-wages --lo
+ * Adjusted to match TAXSIM methodology: perturbs employment income (wages) only, splits perturbation proportionally between spouses, and uses a $100 delta for numerical stability with PolicyEngine's float32 internals. +
+ )} >} )} diff --git a/dashboard/src/constants/index.js b/dashboard/src/constants/index.js index 3833521..5de1b39 100644 --- a/dashboard/src/constants/index.js +++ b/dashboard/src/constants/index.js @@ -135,7 +135,7 @@ export const OUTPUT_VARIABLES = [ { code: 'sctc', name: 'State child tax credit', policyengine: 'state_ctc' }, { code: 'sptcr', name: 'State property tax credit', policyengine: 'state_property_tax_credit' }, { code: 'samt', name: 'State alternative minimum tax', policyengine: 'state_amt' }, - { code: 'srate', name: 'State marginal rate', policyengine: null }, + { code: 'srate', name: 'State marginal rate', policyengine: 'state_marginal_tax_rate' }, // Additional Federal Results (v42-v46) { code: 'v42', name: 'Earned Self-Employment Income for FICA', policyengine: 'self_employment_income' }, @@ -152,8 +152,8 @@ export const OUTPUT_VARIABLES = [ // Additional Outputs (moved to end for proper section ordering) { code: 'fica', name: 'FICA (OADSI and HI, sum of employee AND employer including Additional Medicare Tax)', policyengine: null }, { code: 'tfica', name: 'Taxpayer liability for FICA', policyengine: 'taxsim_tfica' }, - { code: 'frate', name: 'Federal marginal rate', policyengine: null }, - { code: 'ficar', name: 'FICA rate', policyengine: null }, + { code: 'frate', name: 'Federal marginal rate', policyengine: 'federal_marginal_tax_rate' }, + { code: 'ficar', name: 'FICA rate', policyengine: 'fica_marginal_tax_rate' }, ]; // Input fields from TAXSIM diff --git a/output/policyengine_taxsim_household_with_dependent_output.csv b/output/policyengine_taxsim_household_with_dependent_output.csv index 071c2b2..a15770e 100644 --- a/output/policyengine_taxsim_household_with_dependent_output.csv +++ b/output/policyengine_taxsim_household_with_dependent_output.csv @@ -1,2 +1,2 @@ -taxsimid,year,state,fiitax,siitax,fica,tfica,v10,v11,v12,v13,v14,v17,qbid,niit,v18,v19,v22,v24,v25,v26,v27,v28,v29,v32,v34,v35,v36,v37,v38,v39,v40,v42,v43,v44,cares -6,2023,39,3956.0,2486.7,0.0,6196.5,81000.0,0.0,0.0,27700.0,0.0,2486.7,0.0,0.0,53300.0,5956.0,2000.0,0.0,0.0,81000.0,0.0,5956.0,6196.5,81000.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1174.5,0.0 +taxsimid,year,state,fiitax,siitax,fica,tfica,v10,v11,v12,v13,v14,v17,qbid,niit,v18,v19,v22,v24,v25,v26,v27,v28,v29,v32,v34,v35,v36,v37,v38,v39,v40,v42,v43,v44,cares,srate,frate +6,2023,39,3956.0,2486.7,0.0,6196.5,81000.0,0.0,0.0,27700.0,0.0,2486.7,0.0,0.0,53300.0,5956.0,2000.0,0.0,0.0,81000.0,0.0,5956.0,6196.5,81000.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1174.5,0.0,3.0701,12.0 diff --git a/output/policyengine_taxsim_household_with_dependent_single_parent_output.csv b/output/policyengine_taxsim_household_with_dependent_single_parent_output.csv index b16f00e..c2e2fe2 100644 --- a/output/policyengine_taxsim_household_with_dependent_single_parent_output.csv +++ b/output/policyengine_taxsim_household_with_dependent_single_parent_output.csv @@ -1,2 +1,2 @@ -taxsimid,year,state,fiitax,siitax,fica,tfica,v10,v11,v12,v13,v14,v17,qbid,niit,v18,v19,v22,v24,v25,v26,v27,v28,v29,v32,v34,v35,v36,v37,v38,v39,v40,v42,v43,v44,cares -6,2023,39,4945.0,2486.7,0.0,6196.5,81000.0,0.0,0.0,20800.0,0.0,2486.7,0.0,0.0,60200.0,6945.0,2000.0,0.0,0.0,81000.0,0.0,6945.0,6196.5,81000.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1174.5,0.0 +taxsimid,year,state,fiitax,siitax,fica,tfica,v10,v11,v12,v13,v14,v17,qbid,niit,v18,v19,v22,v24,v25,v26,v27,v28,v29,v32,v34,v35,v36,v37,v38,v39,v40,v42,v43,v44,cares,srate,frate +6,2023,39,4945.0,2486.7,0.0,6196.5,81000.0,0.0,0.0,20800.0,0.0,2486.7,0.0,0.0,60200.0,6945.0,2000.0,0.0,0.0,81000.0,0.0,6945.0,6196.5,81000.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1174.5,0.0,3.0701,22.0 diff --git a/output/policyengine_taxsim_joint_household_output.csv b/output/policyengine_taxsim_joint_household_output.csv index 6205bd1..ee66353 100644 --- a/output/policyengine_taxsim_joint_household_output.csv +++ b/output/policyengine_taxsim_joint_household_output.csv @@ -1,3 +1,3 @@ -taxsimid,year,state,fiitax,siitax,fica,tfica,v10,v11,v12,v13,v14,v17,qbid,niit,v18,v19,v22,v24,v25,v26,v27,v28,v29,v32,v34,v35,v36,v37,v38,v39,v40,v42,v43,v44,cares -999,2023,44,1716.0,0.0,0.0,6043.5,79000.0,0.0,0.0,27700.0,0.0,1927.2,0.0,0.0,51300.0,5716.0,4000.0,0.0,0.0,79000.0,0.0,5716.0,6043.5,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1145.5,0.0 -11,2023,44,1476.0,0.0,0.0,5890.5,77000.0,0.0,0.0,27700.0,0.0,1927.2,0.0,0.0,49300.0,5476.0,4000.0,0.0,0.0,77000.0,0.0,5476.0,5890.5,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1116.5,0.0 +taxsimid,year,state,fiitax,siitax,fica,tfica,v10,v11,v12,v13,v14,v17,qbid,niit,v18,v19,v22,v24,v25,v26,v27,v28,v29,v32,v34,v35,v36,v37,v38,v39,v40,v42,v43,v44,cares,frate,srate +999,2023,44,1716.0,0.0,0.0,6043.5,79000.0,0.0,0.0,27700.0,0.0,1927.2,0.0,0.0,51300.0,5716.0,4000.0,0.0,0.0,79000.0,0.0,5716.0,6043.5,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1145.5,0.0,12.0,0.0 +11,2023,44,1476.0,0.0,0.0,5890.5,77000.0,0.0,0.0,27700.0,0.0,1927.2,0.0,0.0,49300.0,5476.0,4000.0,0.0,0.0,77000.0,0.0,5476.0,5890.5,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1116.5,0.0,12.0,0.0 diff --git a/output/policyengine_taxsim_single_household_output.csv b/output/policyengine_taxsim_single_household_output.csv index 56f5ec5..f888a58 100644 --- a/output/policyengine_taxsim_single_household_output.csv +++ b/output/policyengine_taxsim_single_household_output.csv @@ -1,3 +1,3 @@ -taxsimid,year,state,fiitax,siitax,fica,tfica,v10,v11,v12,v13,v14,v17,qbid,niit,v18,v19,v22,v24,v25,v26,v27,v28,v29,v32,v34,v35,v36,v37,v38,v39,v40,v42,v43,v44,cares -999,2021,3,2775.0,1008.87,0.0,3748.5,49000.0,0.0,0.0,12550.0,0.0,1020.0,0.0,0.0,36450.0,4175.0,0.0,0.0,0.0,49000.0,0.0,4175.0,3748.5,49000.0,12550.0,1020.0,36450.0,0.0,0.0,0.0,0.0,0.0,0.0,710.5,1400.0 -11,2021,3,2535.0,942.07,0.0,3595.5,47000.0,0.0,0.0,12550.0,0.0,1020.0,0.0,0.0,34450.0,3935.0,0.0,0.0,0.0,47000.0,0.0,3935.0,3595.5,47000.0,12550.0,1020.0,34450.0,0.0,0.0,0.0,0.0,0.0,0.0,681.5,1400.0 +taxsimid,year,state,fiitax,siitax,fica,tfica,v10,v11,v12,v13,v14,v17,qbid,niit,v18,v19,v22,v24,v25,v26,v27,v28,v29,v32,v34,v35,v36,v37,v38,v39,v40,v42,v43,v44,cares,frate,srate +999,2021,3,2775.0,1008.87,0.0,3748.5,49000.0,0.0,0.0,12550.0,0.0,1020.0,0.0,0.0,36450.0,4175.0,0.0,0.0,0.0,49000.0,0.0,4175.0,3748.5,49000.0,12550.0,1020.0,36450.0,0.0,0.0,0.0,0.0,0.0,0.0,710.5,1400.0,12.0,3.34 +11,2021,3,2535.0,942.07,0.0,3595.5,47000.0,0.0,0.0,12550.0,0.0,1020.0,0.0,0.0,34450.0,3935.0,0.0,0.0,0.0,47000.0,0.0,3935.0,3595.5,47000.0,12550.0,1020.0,34450.0,0.0,0.0,0.0,0.0,0.0,0.0,681.5,1400.0,12.0,3.34 diff --git a/policyengine_taxsim/config/variable_mappings.yaml b/policyengine_taxsim/config/variable_mappings.yaml index 3beec9c..c2787d8 100644 --- a/policyengine_taxsim/config/variable_mappings.yaml +++ b/policyengine_taxsim/config/variable_mappings.yaml @@ -66,8 +66,8 @@ policyengine_to_taxsim: full_text_group: "Basic Output" group_column: 1 frate: - variable: na_pe - implemented: false + variable: marginal_rate_computed + implemented: true idtl: - standard: 0 - full: 2 @@ -77,8 +77,8 @@ policyengine_to_taxsim: full_text_group: "Marginal Rates wrt Weighted Average Earnings" group_column: 1 srate: - variable: na_pe - implemented: false + variable: marginal_rate_computed + implemented: true idtl: - standard: 0 - full: 2 @@ -88,7 +88,7 @@ policyengine_to_taxsim: full_text_group: "Marginal Rates wrt Weighted Average Earnings" group_column: 1 ficar: - variable: na_pe + variable: marginal_rate_computed implemented: false idtl: - standard: 0 diff --git a/policyengine_taxsim/core/input_mapper.py b/policyengine_taxsim/core/input_mapper.py index 1d36227..5d15fcb 100644 --- a/policyengine_taxsim/core/input_mapper.py +++ b/policyengine_taxsim/core/input_mapper.py @@ -8,7 +8,6 @@ def add_additional_units(state, year, situation, taxsim_vars): - additional_tax_units_config = load_variable_mappings()["taxsim_to_policyengine"][ "household_situation" ]["additional_tax_units"] diff --git a/policyengine_taxsim/core/marginal_rates.py b/policyengine_taxsim/core/marginal_rates.py new file mode 100644 index 0000000..28ec150 --- /dev/null +++ b/policyengine_taxsim/core/marginal_rates.py @@ -0,0 +1,84 @@ +"""TAXSIM-compatible marginal tax rate computation. + +Matches TAXSIM-35 methodology: +- Perturbs wages split proportionally between primary and spouse + (weighted average earnings) +- Only perturbs employment income (wages), not self-employment +- Returns rates as percentages (22.0 for 22%) + +Note: TAXSIM uses $0.01 delta with Fortran float64 precision. +PolicyEngine uses float32 internally, so we use $100 delta to +avoid precision loss while remaining small enough to stay within +a single tax bracket for most filers. +""" + +import copy +from policyengine_us import Simulation + + +DELTA = 100.0 # $100: large enough for float32 precision, small for bracket safety + + +def compute_marginal_rates_single(simulation, situation, year, disable_salt): + """Compute marginal rates for a single household (exe/output_mapper path). + + Args: + simulation: Base PolicyEngine Simulation (already computed). + situation: The situation dict used to create the simulation. + year: Tax year string. + disable_salt: Whether SALT deduction is disabled. + + Returns: + dict with 'frate', 'srate', 'ficar' as percentage values. + """ + people = situation["people"] + + # Get base tax values from the existing simulation + # frate must match fiitax definition: income_tax + additional_medicare_tax + base_federal = float(simulation.calculate("income_tax", period=year)[0]) + float( + simulation.calculate("additional_medicare_tax", period=year)[0] + ) + base_state = float(simulation.calculate("state_income_tax", period=year)[0]) + + # Get current wages + pwages = float(people["you"].get("employment_income", {}).get(year, 0)) + swages = 0.0 + if "your partner" in people: + swages = float(people["your partner"].get("employment_income", {}).get(year, 0)) + + total_wages = pwages + swages + + # Compute proportional split (TAXSIM: weighted average earnings) + if total_wages > 0: + p_share = pwages / total_wages + s_share = swages / total_wages + else: + p_share = 0.5 + s_share = 0.5 if "your partner" in people else 0.0 + + # Create perturbed situation + perturbed = copy.deepcopy(situation) + perturbed["people"]["you"]["employment_income"] = {year: pwages + DELTA * p_share} + if "your partner" in perturbed["people"]: + perturbed["people"]["your partner"]["employment_income"] = { + year: swages + DELTA * s_share + } + + # Run perturbed simulation + perturbed_sim = Simulation(situation=perturbed) + if disable_salt: + perturbed_sim.set_input( + variable_name="state_and_local_sales_or_income_tax", + value=0.0, + period=year, + ) + + new_federal = float(perturbed_sim.calculate("income_tax", period=year)[0]) + float( + perturbed_sim.calculate("additional_medicare_tax", period=year)[0] + ) + new_state = float(perturbed_sim.calculate("state_income_tax", period=year)[0]) + + return { + "frate": round(100.0 * (new_federal - base_federal) / DELTA, 4), + "srate": round(100.0 * (new_state - base_state) / DELTA, 4), + } diff --git a/policyengine_taxsim/core/output_mapper.py b/policyengine_taxsim/core/output_mapper.py index 7a866e7..4b8d81a 100644 --- a/policyengine_taxsim/core/output_mapper.py +++ b/policyengine_taxsim/core/output_mapper.py @@ -5,6 +5,7 @@ ) from policyengine_us import Simulation from .yaml_generator import generate_pe_tests_yaml +from .marginal_rates import compute_marginal_rates_single disable_salt_variable = False @@ -13,6 +14,9 @@ def generate_non_description_output( taxsim_output, mappings, year, state_name, simulation, output_type, logs ): outputs = [] + mtr_computed = False + mtr_results = {} + for key, each_item in mappings.items(): if each_item["implemented"]: if key == "taxsimid": @@ -21,6 +25,22 @@ def generate_non_description_output( taxsim_output[key] = int(year) elif key == "state": taxsim_output[key] = get_state_number(state_name) + elif each_item.get("variable") == "marginal_rate_computed": + # Marginal rates: compute once, apply per key + if not mtr_computed: + try: + mtr_results = compute_marginal_rates_single( + simulation, + simulation.situation_input, + year, + disable_salt_variable, + ) + except Exception: + mtr_results = {"frate": 0.0, "srate": 0.0, "ficar": 0.0} + mtr_computed = True + for entry in each_item["idtl"]: + if output_type in entry.values(): + taxsim_output[key] = mtr_results.get(key, 0.0) elif "variables" in each_item and len(each_item["variables"]) > 0: pe_variables = each_item["variables"] taxsim_output[key] = simulate_multiple(simulation, pe_variables, year) @@ -77,6 +97,9 @@ def generate_text_description_output( lines = [""] sorted_groups = sorted(groups.keys(), key=lambda x: group_orders[x]) outputs = [] + mtr_computed = False + mtr_results = {} + for group_name in sorted_groups: variables = groups[group_name] if variables: @@ -98,6 +121,19 @@ def generate_text_description_output( value = ( f"{get_state_number(state_name)}{' ' * LEFT_MARGIN}{state_name}" ) + elif variable == "marginal_rate_computed": + if not mtr_computed: + try: + mtr_results = compute_marginal_rates_single( + simulation, + simulation.situation_input, + year, + disable_salt_variable, + ) + except Exception: + mtr_results = {"frate": 0.0, "srate": 0.0, "ficar": 0.0} + mtr_computed = True + value = mtr_results.get(var_name, 0.0) elif "variables" in each_item and len(each_item["variables"]) > 0: value = simulate_multiple(simulation, each_item["variables"], year) else: diff --git a/policyengine_taxsim/runners/policyengine_runner.py b/policyengine_taxsim/runners/policyengine_runner.py index a7f3977..7d2bb36 100644 --- a/policyengine_taxsim/runners/policyengine_runner.py +++ b/policyengine_taxsim/runners/policyengine_runner.py @@ -961,6 +961,86 @@ def _calc_tax_unit(self, sim, var_name, period): return np.array(sim.map_result(values, entity_key, "tax_unit")) return values + def _compute_marginal_rates(self, sim, year_str, year_data): + """Compute TAXSIM-compatible marginal tax rates via wage perturbation. + + Matches TAXSIM-35 methodology: + - Perturbs employment_income (wages) only, not self-employment + - Splits perturbation between primary and spouse proportionally + to their share of total wages (weighted average earnings) + - Uses $0.01 delta to match TAXSIM batch mode + - Returns rates as percentages (22.0 for 22%) + + Returns: + dict with 'frate', 'srate' arrays at tax_unit level + """ + delta = ( + 100.0 # $100: large enough for float32 precision, small for bracket safety + ) + # Get base tax values from the main simulation + # frate must match fiitax definition: income_tax + additional_medicare_tax + base_federal = self._calc_tax_unit( + sim, "income_tax", year_str + ) + self._calc_tax_unit(sim, "additional_medicare_tax", year_str) + base_state = self._calc_tax_unit(sim, "state_income_tax", year_str) + + # Get current employment_income at person level + emp_income = np.array(sim.calculate("employment_income", period=year_str)) + + # Compute proportional wage split per person + # Map person-level income to tax_unit totals, then compute share + tu_total_wages = np.array( + sim.map_result(emp_income, "person", "tax_unit", how="sum") + ) + # Expand tax_unit totals back to person level + person_tu_id = np.array(sim.populations["tax_unit"].members_entity_id) + tu_total_expanded = tu_total_wages[person_tu_id] + + # Each person's share of total wages (0.5/0.5 if both zero) + with np.errstate(divide="ignore", invalid="ignore"): + wage_share = np.where( + tu_total_expanded > 0, + emp_income / tu_total_expanded, + 0.0, + ) + # For zero-wage households, split 50/50 between head and spouse + is_head = np.array(sim.calculate("is_tax_unit_head", period=year_str)) + is_spouse = np.array(sim.calculate("is_tax_unit_spouse", period=year_str)) + zero_wage_mask = tu_total_expanded == 0 + wage_share = np.where(zero_wage_mask & is_head, 0.5, wage_share) + wage_share = np.where(zero_wage_mask & is_spouse, 0.5, wage_share) + + # Create perturbation: delta * wage_share for each person + perturbation = delta * wage_share + + # Create branch simulation with perturbed wages + branch = sim.get_branch("mtr_wage_perturbation") + + # Clear cached values for variables that depend on employment_income + for variable in sim.tax_benefit_system.variables: + if variable not in sim.input_variables or variable == "employment_income": + branch.delete_arrays(variable) + + # Set perturbed employment income + branch.set_input("employment_income", year_str, emp_income + perturbation) + + # Compute perturbed tax values + new_federal = self._calc_tax_unit( + branch, "income_tax", year_str + ) + self._calc_tax_unit(branch, "additional_medicare_tax", year_str) + new_state = self._calc_tax_unit(branch, "state_income_tax", year_str) + # Compute rates as percentages: 100 * (new - base) / delta + frate = 100.0 * (new_federal - base_federal) / delta + srate = 100.0 * (new_state - base_state) / delta + + # Clean up branch + del sim.branches["mtr_wage_perturbation"] + + return { + "frate": np.round(frate, 4), + "srate": np.round(srate, 4), + } + def _extract_vectorized_results( self, sim: Microsimulation, input_df: pd.DataFrame ) -> pd.DataFrame: @@ -1045,6 +1125,10 @@ def _extract_vectorized_results( columns[taxsim_var] = np.zeros(n) continue + if pe_var == "marginal_rate_computed": + # Marginal rates are computed specially after this loop + continue + try: if has_state: # Check if unified PE variable exists (e.g., state_agi, @@ -1166,6 +1250,22 @@ def _extract_vectorized_results( ) + self._calc_tax_unit(sim, "additional_medicare_tax", year_str) columns["fiitax"] = np.round(fiitax_arr, 2) + # Compute marginal rates if any idtl level requests them + mtr_vars = {"frate", "srate"} + needs_mtr = any(v in vars_to_compute for v in mtr_vars) + if needs_mtr: + try: + mtr_results = self._compute_marginal_rates(sim, year_str, year_data) + for mtr_var in mtr_vars: + if mtr_var in vars_to_compute: + columns[mtr_var] = mtr_results[mtr_var] + except Exception as e: + if self.logs: + print(f"Warning: marginal rate computation failed: {e}") + for mtr_var in mtr_vars: + if mtr_var in vars_to_compute: + columns[mtr_var] = np.zeros(n) + # Apply idtl filtering: mask out columns not requested by each row's idtl if len(unique_idtls) > 1 or 0 in unique_idtls: for taxsim_var, info in vars_to_compute.items(): diff --git a/tests/test_e2e.py b/tests/test_e2e.py index 3c752e9..23286b3 100644 --- a/tests/test_e2e.py +++ b/tests/test_e2e.py @@ -193,7 +193,6 @@ def test_generate_policyengine_taxsim_single_household_output(self): print(f.read()) def test_generate_taxsim35_single_household_output(self): - output_file = self.output_dir / self.SINGLE_HOUSEHOLD_TAXSIM35_OUTPUT self.generate_taxsim35_output(self.input_file_single_household, output_file) @@ -298,7 +297,6 @@ def test_generate_policyengine_taxsim_joint_household_output(self): print(f.read()) def test_generate_taxsim35_joint_household_output(self): - output_file = self.output_dir / self.JOINT_HOUSEHOLD_TAXSIM35_OUTPUT self.generate_taxsim35_output(self.input_file_joint_household, output_file)