Skip to content

Fix taxsim --taxsim-path: accept a str path and resolve it - #1415

Open
MaxGhenis wants to merge 2 commits into
mainfrom
fix-taxsim-path-str
Open

MaxGhenis wants to merge 2 commits into
mainfrom
fix-taxsim-path-str

Conversation

@MaxGhenis

Copy link
Copy Markdown
Contributor

Summary

policyengine-taxsim taxsim <file> --taxsim-path <binary> failed on every run (reproduced at 549beade, current main):

Error: 'str' object has no attribute 'exists'
Aborted!

click.Path hands the command a str, and TaxsimRunner.__init__ stored it as is. _validate_executable then called self.taxsim_path.exists() on it. Python callers passing a str hit the same error.

A second bug sat behind it. With a Path object (which gets past the first bug), a bare name like taxsimtest-osx.exe run from the binary's own folder failed with /bin/sh: taxsimtest-osx.exe: command not found. _execute_taxsim pipes the input through the shell, and the shell searches PATH for a name with no directory in it.

Fix

TaxsimRunner.__init__ now stores Path(taxsim_path).absolute(). These lines are byte-for-byte the ones #1412 (run-provenance) adds, so the PRs can merge in either order. I checked locally:

Tests

New tests/test_taxsim_path.py runs the bundled taxsimtest binary for this OS on two pre-2021 records (2019 CA single; 2020 NY married with two children). These need no PolicyEngine run.

  • test_runner_accepts_every_path_spelling passes the executable four ways: absolute str, absolute Path, a relative path with a directory, and a bare name. Each case checks that:
    • taxsim_path is an absolute Path pointing at the bundled binary;
    • it changes working directory before run(), so the path must already be fixed at construction;
    • fiitax/siitax/fica exactly match a run where TaxsimRunner finds the binary itself.
  • test_cli_taxsim_path_option runs the reported command through click's CliRunner with -o out.csv, once with an absolute path and once with a bare name. It checks for exit 0, both output rows, and outputs that exactly match the default-binary run.
  • test_runner_reports_missing_str_path checks that a str path to a missing file raises FileNotFoundError naming the path, not AttributeError.
  • A fixture guard asserts positive fica on every record (all have wages), so the equality checks cannot pass on an empty or all-zero run.

Verification:

  • On unfixed main, 6 of the 7 new tests fail with the original AttributeError. The absolute-Path case passes either way and serves as the control.
  • Mutation check: dropping only .absolute() fails the relative-with-directory and bare-name runner cases and the CLI bare-name case (command not found).
  • Locally, tests/test_taxsim_path.py, tests/test_public_contract.py and tests/test_cli_entry_point.py give 12 passed. CI runs the new tests on ubuntu, macOS and Windows.

Invariants

These hold for any way a caller can name an existing executable (str or Path, absolute or relative, with or without a directory):

  1. TaxsimRunner.taxsim_path is an absolute pathlib.Path.
  2. Which binary runs is fixed at construction and does not depend on the working directory when run() is called.
  3. Results are identical to running the same binary through default detection.

The four spellings cover every case these depend on, and the tests check each one exhaustively. A property-based generator would add nothing over that.

axiom: n/a: CLI/runner path handling, no policy logic

Changelog: changelog.d/taxsim-path-str.fixed.md.

🤖 Generated with Claude Code

click.Path gives the taxsim command a str, and TaxsimRunner called
.exists() on it, so every --taxsim-path run failed with
"'str' object has no attribute 'exists'". Coerce the argument to an
absolute Path in __init__. Absolute matters too: the runner pipes input
through the shell, which searches PATH for a bare name such as
"taxsimtest-osx.exe" and reports "command not found".

The __init__ lines match the run-provenance branch (#1412) exactly, so
either can merge first without a conflict.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
policyengine-taxsim Ready Ready Preview Nov 11, 2026 4:52am UTC

Request Review

@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Sweep status (PR sweep of 2026-11-11): an independent Opus 5.5 review approved head c30d4bf. Every check passes except tests/test_or_kicker_output.py::test_or_kicker_export_and_comparison[2025-…], which fails on every branch cut from current main: since PolicyEngine/policyengine-us#10093, Oregon's federal tax liability subtraction nets out assigned_aca_ptc, and PE-US imputes a premium tax credit to TAXSIM records. #1518 turns ACA take-up off for TAXSIM records and fixes it. Once #1518 merges, update this branch and merge on green.

This branch was successfully deployed

1 active deployment
Preview — c30d4bfa Deployed Nov 11, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant