policyengine-taxsim 3.2.2__tar.gz → 3.2.4__tar.gz
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.
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/CHANGELOG.md +14 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/PKG-INFO +7 -1
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/README.md +6 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/policyengine_taxsim/__init__.py +1 -1
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/policyengine_taxsim/api.py +7 -1
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/policyengine_taxsim/core/input_mapper.py +10 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/policyengine_taxsim/runners/policyengine_runner.py +17 -3
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/pyproject.toml +1 -1
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/scripts/dashboard-refresh-requirements.txt +1 -1
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_mappers.py +14 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_mtr_branch_overrides.py +1 -0
- policyengine_taxsim-3.2.4/tests/test_student_status.py +238 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/.claude/commands/diagnose-issue.md +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/.claude/cspell.json +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/.github/bump_version.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/.github/fetch_version.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/.github/get-changelog-diff.sh +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/.github/has-functional-changes.sh +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/.github/is-version-number-acceptable.sh +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/.github/publish-git-tag.sh +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/.github/workflows/ci.yml +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/.github/workflows/deploy-pages.yml +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/.github/workflows/refresh-dashboard.yml +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/.github/workflows/scorp-e2e.yml +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/.gitignore +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/CLAUDE.md +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/LICENSE +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/Makefile +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/changelog.d/.gitkeep +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/cps_households.csv +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/.env.production +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/.gitignore +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/README.md +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/bun.lock +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/jsconfig.json +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/next.config.mjs +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/package.json +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/postcss.config.mjs +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/public/assets/logos/policyengine/white.svg +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/public/config-data.json +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/public/data/2021/comparison_results_2021.csv +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/public/data/2021/summary_2021.json +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/public/data/2022/comparison_results_2022.csv +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/public/data/2022/summary_2022.json +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/public/data/2023/comparison_results_2023.csv +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/public/data/2023/summary_2023.json +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/public/data/2024/comparison_results_2024.csv +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/public/data/2024/summary_2024.json +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/public/data/2025/comparison_results_2025.csv +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/public/data/2025/summary_2025.json +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/public/manifest.json +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/public/policyengine.png +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/public/robots.txt +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/public/sample_ecps_2024.csv +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/scripts/extract-config.cjs +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/social-posts.md +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/app/dashboard/page.jsx +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/app/documentation/page.jsx +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/app/globals.css +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/app/layout.jsx +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/app/page.jsx +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/app/run/page.jsx +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/components/CsvRunner.jsx +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/components/DashboardContent.jsx +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/components/DocumentationContent.jsx +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/components/GitHubIssues.jsx +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/components/Header.jsx +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/components/HouseholdCard.jsx +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/components/LandingContent.jsx +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/components/MetricsRow.jsx +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/components/RunContent.jsx +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/components/StateFilter.jsx +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/components/StateTable.jsx +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/components/StateTaxNote.jsx +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/components/YearTabs.jsx +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/components/__tests__/DocumentationContent.test.jsx +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/components/__tests__/LandingContent.test.jsx +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/components/common/Button.jsx +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/components/common/ErrorMessage.jsx +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/components/common/LoadingSpinner.jsx +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/components/common/SortableTableHeader.jsx +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/constants/index.js +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/hooks/useHouseholdData.js +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/hooks/useYearData.js +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/test/setup.js +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/utils/__tests__/formatters.test.js +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/utils/__tests__/githubApi.test.js +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/utils/basePath.js +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/utils/codeHighlight.jsx +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/utils/colors.js +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/utils/configLoader.js +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/utils/dataLoader.js +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/utils/dataProcessing.js +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/utils/exportData.js +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/utils/formatters.js +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/utils/githubApi.js +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/vercel.json +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/vitest.config.mjs +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/docs/dashboard-refresh.md +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/docs/scorp-validation.md +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/issue_analysis/README.md +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/output/policyengine_taxsim_household_with_dependent_output.csv +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/output/policyengine_taxsim_household_with_dependent_single_parent_output.csv +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/output/policyengine_taxsim_joint_household_output.csv +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/output/policyengine_taxsim_single_household_output.csv +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/output/taxsim35_household_with_dependent_output.csv +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/output/taxsim35_household_with_dependent_single_parent_output.csv +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/output/taxsim35_joint_household_output.csv +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/output/taxsim35_single_household_output.csv +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/package-lock.json +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/package.json +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/policyengine_taxsim/cli.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/policyengine_taxsim/comparison/__init__.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/policyengine_taxsim/comparison/comparator.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/policyengine_taxsim/comparison/statistics.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/policyengine_taxsim/config/variable_mappings.yaml +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/policyengine_taxsim/core/__init__.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/policyengine_taxsim/core/io.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/policyengine_taxsim/core/marginal_rates.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/policyengine_taxsim/core/output_mapper.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/policyengine_taxsim/core/scorp.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/policyengine_taxsim/core/scorp_reform.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/policyengine_taxsim/core/state_output_resolver.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/policyengine_taxsim/core/text_formatter.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/policyengine_taxsim/core/utils.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/policyengine_taxsim/core/yaml_generator.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/policyengine_taxsim/runners/__init__.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/policyengine_taxsim/runners/base_runner.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/policyengine_taxsim/runners/remote_taxsim_runner.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/policyengine_taxsim/runners/stitched_runner.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/policyengine_taxsim/runners/taxsim_runner.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/r-package/README.md +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/r-package/policyenginetaxsim/.Rbuildignore +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/r-package/policyenginetaxsim/.gitignore +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/r-package/policyenginetaxsim/DESCRIPTION +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/r-package/policyenginetaxsim/LICENSE +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/r-package/policyenginetaxsim/NAMESPACE +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/r-package/policyenginetaxsim/R/calculate_taxes.R +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/r-package/policyenginetaxsim/R/compare.R +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/r-package/policyenginetaxsim/R/setup.R +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/r-package/policyenginetaxsim/R/zzz.R +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/r-package/policyenginetaxsim/README.md +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/resources/taxsim35/taxsim-latest-windows.exe +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/resources/taxsim35/taxsim35-osx.exe +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/resources/taxsim35/taxsim35-unix.exe +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/resources/taxsim35/taxsim_input_joint_household.csv +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/resources/taxsim35/taxsim_input_single_household.csv +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/resources/taxsim35/taxsim_input_with_1_dep.csv +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/resources/taxsim35/taxsim_input_with_1_dep_single_parent.csv +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/resources/taxsimtest/README.md +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/resources/taxsimtest/taxsim-docker-wrapper.sh +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/resources/taxsimtest/taxsimtest-linux.Dockerfile +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/resources/taxsimtest/taxsimtest-linux.exe +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/resources/taxsimtest/taxsimtest-osx.exe +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/resources/taxsimtest/taxsimtest-windows.exe +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/run-project.ipynb +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/scripts/convert_h5_to_taxsim.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/scripts/dashboard-refresh.in +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/scripts/refresh_dashboard.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/scripts/validate_scorp_alignment.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/taxsiminputfile_2021.csv +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_addmed_excluded_from_fiitax.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_assume_w2_wages.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_cli_entry_point.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_cli_idtl5.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_dashboard_refresh.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_de_staxbc_elected_path.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_deterministic_ordering.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_e2e.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_eitc_investment_income_baskets.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_fica_output.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_imputed_transfers_zeroed.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_income_scaled_tolerance.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_intermediate_output_mappings.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_itemized_aggregates.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_ma_premium_pay.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_ma_taxable_income.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_married_filing_separately.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_md_local_tax_parity.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_me_affordability_payment.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_me_ptfc_utilities.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_mn_credit_outputs.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_multi_state.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_net_of_rebates.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_nonprop_mapping.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_ny_separate_payments.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_or_kicker_output.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_otherprop_niit.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_passthrough_qbid.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_performance.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_public_contract.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_runner_input_order.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_scorp_e2e.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_scorp_treatment.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_spouse_income_splitting.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_stata_io.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_state_codes.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_state_output_adapters.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_state_zero_salt.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_statefip.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_stitched_runner.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_taxsim32_dependent_counts.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_taxsim_debug_output.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_taxsim_docker_wrapper.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_taxsim_opt30.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_taxsim_options.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_three_pass_disable_salt.py +0 -0
- {policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/tests/test_transfers_mapping.py +0 -0
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## [3.2.4] - 2026-10-22
|
|
2
|
+
|
|
3
|
+
### Fixed
|
|
4
|
+
|
|
5
|
+
- Treat every person in a TAXSIM record as a non-student, so a spouse aged 17 or younger no longer gets IRC 21(d)(2) deemed earned income for the child and dependent care credit, which TAXSIM does not give.
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
## [3.2.3] - 2026-10-22
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- Stop trusting the compromised eMudhra CA certificates: pin certifi 2026.10.19 in the dashboard refresh environment, and make the Modal API image upgrade ca-certificates and install certifi 2026.10.19 or later.
|
|
13
|
+
|
|
14
|
+
|
|
1
15
|
## [3.2.2] - 2026-10-20
|
|
2
16
|
|
|
3
17
|
### Fixed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: policyengine-taxsim
|
|
3
|
-
Version: 3.2.
|
|
3
|
+
Version: 3.2.4
|
|
4
4
|
Summary: A TAXSIM emulator using PolicyEngine US
|
|
5
5
|
Project-URL: Homepage, https://github.com/PolicyEngine/policyengine-taxsim
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/PolicyEngine/policyengine-taxsim/issues
|
|
@@ -317,6 +317,12 @@ The emulator accepts CSV files with the following variables:
|
|
|
317
317
|
| age2 | Second dependent's age | |
|
|
318
318
|
| ageN | Nth dependent's age | Taxsim only allows up to 8 dependents |
|
|
319
319
|
|
|
320
|
+
TAXSIM input has no student status, so the emulator treats every person as a
|
|
321
|
+
non-student (`is_full_time_student` is false). A dependent aged 19 to 23 is
|
|
322
|
+
therefore not a qualifying child through the student age test, and a spouse
|
|
323
|
+
aged 17 or younger gets no IRC 21(d)(2) deemed earned income for the child
|
|
324
|
+
and dependent care credit.
|
|
325
|
+
|
|
320
326
|
### Income
|
|
321
327
|
|
|
322
328
|
| Variable | Description |
|
|
@@ -280,6 +280,12 @@ The emulator accepts CSV files with the following variables:
|
|
|
280
280
|
| age2 | Second dependent's age | |
|
|
281
281
|
| ageN | Nth dependent's age | Taxsim only allows up to 8 dependents |
|
|
282
282
|
|
|
283
|
+
TAXSIM input has no student status, so the emulator treats every person as a
|
|
284
|
+
non-student (`is_full_time_student` is false). A dependent aged 19 to 23 is
|
|
285
|
+
therefore not a qualifying child through the student age test, and a spouse
|
|
286
|
+
aged 17 or younger gets no IRC 21(d)(2) deemed earned income for the child
|
|
287
|
+
and dependent care credit.
|
|
288
|
+
|
|
283
289
|
### Income
|
|
284
290
|
|
|
285
291
|
| Variable | Description |
|
|
@@ -14,13 +14,19 @@ Local (no Modal):
|
|
|
14
14
|
import modal
|
|
15
15
|
from typing import Literal
|
|
16
16
|
|
|
17
|
+
# Naming ca-certificates makes apt upgrade the operating-system CA store,
|
|
18
|
+
# which urllib uses, to the newest Debian package (20250419+deb13u1 on trixie,
|
|
19
|
+
# 20250419~deb12u2 on bookworm). certifi is the CA list that requests, used by
|
|
20
|
+
# resend, reads. Those packages and certifi 2026.10.19 no longer trust the
|
|
21
|
+
# compromised eMudhra root "emSign ECC Root CA - G3".
|
|
17
22
|
image = (
|
|
18
23
|
modal.Image.debian_slim(python_version="3.11")
|
|
19
|
-
.apt_install("git")
|
|
24
|
+
.apt_install("git", "ca-certificates")
|
|
20
25
|
.pip_install(
|
|
21
26
|
"policyengine-taxsim @ git+https://github.com/PolicyEngine/policyengine-taxsim.git@main",
|
|
22
27
|
"fastapi[standard]",
|
|
23
28
|
"resend",
|
|
29
|
+
"certifi>=2026.10.19",
|
|
24
30
|
)
|
|
25
31
|
)
|
|
26
32
|
|
{policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/policyengine_taxsim/core/input_mapper.py
RENAMED
|
@@ -330,6 +330,16 @@ def form_household_situation(year, state, taxsim_vars):
|
|
|
330
330
|
"medical_expense_health_insurance_premiums"
|
|
331
331
|
] = {str(year): 0}
|
|
332
332
|
|
|
333
|
+
# TAXSIM input has no student status, and the emulator does not default
|
|
334
|
+
# anyone to being a student (taxsim #532). PE-US imputes is_in_k12_school
|
|
335
|
+
# for ages 5 to 17, which made a spouse that age a full-time student with
|
|
336
|
+
# the IRC 21(d)(2) deemed earned income for the CDCC, which TAXSIM-35 does
|
|
337
|
+
# not give. Mirrors the Microsimulation path in PolicyEngineRunner.
|
|
338
|
+
for person_name in household_situation["people"]:
|
|
339
|
+
household_situation["people"][person_name]["is_full_time_student"] = {
|
|
340
|
+
str(year): False
|
|
341
|
+
}
|
|
342
|
+
|
|
333
343
|
# Explicitly set SNAP to 0 for all SPM units to prevent PolicyEngine from imputing SNAP benefits
|
|
334
344
|
# TAXSIM does not model SNAP, so we need to ensure it's not automatically calculated
|
|
335
345
|
for spm_unit_name in household_situation["spm_units"]:
|
|
@@ -1249,9 +1249,9 @@ class PolicyEngineRunner(BaseTaxRunner):
|
|
|
1249
1249
|
self, dataset, chunk_df: pd.DataFrame, zero_salt: bool = False
|
|
1250
1250
|
):
|
|
1251
1251
|
"""Build a Microsimulation from the chunk dataset and apply all
|
|
1252
|
-
emulator overrides (SALT, QBID W-2 wages, rental QBID
|
|
1253
|
-
imputed-transfer zeroing, MD local tax zeroing, ME rent
|
|
1254
|
-
separate payments).
|
|
1252
|
+
emulator overrides (student status, SALT, QBID W-2 wages, rental QBID
|
|
1253
|
+
gate, MN CRP, imputed-transfer zeroing, MD local tax zeroing, ME rent
|
|
1254
|
+
utilities, NY separate payments).
|
|
1255
1255
|
|
|
1256
1256
|
``zero_salt`` zeroes the federal deduction for state and local income
|
|
1257
1257
|
or sales tax for every record in the chunk: state-0 records and
|
|
@@ -1262,6 +1262,20 @@ class PolicyEngineRunner(BaseTaxRunner):
|
|
|
1262
1262
|
sim = Microsimulation(
|
|
1263
1263
|
dataset=dataset, tax_benefit_system=scorp_tax_benefit_system()
|
|
1264
1264
|
)
|
|
1265
|
+
# Student status: TAXSIM input has none, and the emulator does not
|
|
1266
|
+
# default anyone to being a student (taxsim #532). PE-US imputes
|
|
1267
|
+
# is_in_k12_school for ages 5 to 17, which made a spouse that age a
|
|
1268
|
+
# full-time student and gave them the IRC 21(d)(2) deemed earned
|
|
1269
|
+
# income for the CDCC, which TAXSIM-35 does not give. Pinned before
|
|
1270
|
+
# any calculate so no cached value depends on the imputation.
|
|
1271
|
+
n_persons = sim.get_variable_population("is_full_time_student").count
|
|
1272
|
+
for year in sorted(set(chunk_df["year"].astype(int))):
|
|
1273
|
+
_pin_input(
|
|
1274
|
+
sim,
|
|
1275
|
+
variable_name="is_full_time_student",
|
|
1276
|
+
value=np.zeros(n_persons, dtype=bool),
|
|
1277
|
+
period=str(year),
|
|
1278
|
+
)
|
|
1265
1279
|
for year in sorted(set(chunk_df["year"].astype(int))):
|
|
1266
1280
|
period = str(year)
|
|
1267
1281
|
income = sim.calculate("partnership_s_corp_income", period=period)
|
|
@@ -95,6 +95,7 @@ def test_import_single_household(sample_taxsim_input):
|
|
|
95
95
|
"early_head_start": {"2021": 0},
|
|
96
96
|
"commodity_supplemental_food_program": {"2021": 0},
|
|
97
97
|
"medical_expense_health_insurance_premiums": {"2021": 0},
|
|
98
|
+
"is_full_time_student": {"2021": False},
|
|
98
99
|
}
|
|
99
100
|
},
|
|
100
101
|
"spm_units": {
|
|
@@ -130,6 +131,7 @@ def test_import_single_household_without_state(sample_taxsim_input_without_state
|
|
|
130
131
|
"early_head_start": {"2021": 0},
|
|
131
132
|
"commodity_supplemental_food_program": {"2021": 0},
|
|
132
133
|
"medical_expense_health_insurance_premiums": {"2021": 0},
|
|
134
|
+
"is_full_time_student": {"2021": False},
|
|
133
135
|
}
|
|
134
136
|
},
|
|
135
137
|
"spm_units": {
|
|
@@ -172,6 +174,7 @@ def test_import_single_household_with_state_eq_0(sample_taxsim_input_with_state_
|
|
|
172
174
|
"early_head_start": {"2021": 0},
|
|
173
175
|
"commodity_supplemental_food_program": {"2021": 0},
|
|
174
176
|
"medical_expense_health_insurance_premiums": {"2021": 0},
|
|
177
|
+
"is_full_time_student": {"2021": False},
|
|
175
178
|
}
|
|
176
179
|
},
|
|
177
180
|
"spm_units": {
|
|
@@ -268,6 +271,7 @@ def test_joint_household(sample_taxsim_input_for_joint):
|
|
|
268
271
|
"early_head_start": {"2023": 0},
|
|
269
272
|
"commodity_supplemental_food_program": {"2023": 0},
|
|
270
273
|
"medical_expense_health_insurance_premiums": {"2023": 0},
|
|
274
|
+
"is_full_time_student": {"2023": False},
|
|
271
275
|
},
|
|
272
276
|
"your partner": {
|
|
273
277
|
"age": {"2023": 40},
|
|
@@ -278,6 +282,7 @@ def test_joint_household(sample_taxsim_input_for_joint):
|
|
|
278
282
|
"early_head_start": {"2023": 0},
|
|
279
283
|
"commodity_supplemental_food_program": {"2023": 0},
|
|
280
284
|
"medical_expense_health_insurance_premiums": {"2023": 0},
|
|
285
|
+
"is_full_time_student": {"2023": False},
|
|
281
286
|
},
|
|
282
287
|
"your first dependent": {
|
|
283
288
|
"age": {"2023": 10},
|
|
@@ -290,6 +295,7 @@ def test_joint_household(sample_taxsim_input_for_joint):
|
|
|
290
295
|
"early_head_start": {"2023": 0},
|
|
291
296
|
"commodity_supplemental_food_program": {"2023": 0},
|
|
292
297
|
"medical_expense_health_insurance_premiums": {"2023": 0},
|
|
298
|
+
"is_full_time_student": {"2023": False},
|
|
293
299
|
},
|
|
294
300
|
"your second dependent": {
|
|
295
301
|
"age": {"2023": 10},
|
|
@@ -302,6 +308,7 @@ def test_joint_household(sample_taxsim_input_for_joint):
|
|
|
302
308
|
"early_head_start": {"2023": 0},
|
|
303
309
|
"commodity_supplemental_food_program": {"2023": 0},
|
|
304
310
|
"medical_expense_health_insurance_premiums": {"2023": 0},
|
|
311
|
+
"is_full_time_student": {"2023": False},
|
|
305
312
|
},
|
|
306
313
|
},
|
|
307
314
|
"spm_units": {
|
|
@@ -381,6 +388,7 @@ def test_household_with_dependent(sample_taxsim_input_for_household_with_depende
|
|
|
381
388
|
"early_head_start": {"2023": 0},
|
|
382
389
|
"commodity_supplemental_food_program": {"2023": 0},
|
|
383
390
|
"medical_expense_health_insurance_premiums": {"2023": 0},
|
|
391
|
+
"is_full_time_student": {"2023": False},
|
|
384
392
|
},
|
|
385
393
|
"your partner": {
|
|
386
394
|
"age": {"2023": 40},
|
|
@@ -391,6 +399,7 @@ def test_household_with_dependent(sample_taxsim_input_for_household_with_depende
|
|
|
391
399
|
"early_head_start": {"2023": 0},
|
|
392
400
|
"commodity_supplemental_food_program": {"2023": 0},
|
|
393
401
|
"medical_expense_health_insurance_premiums": {"2023": 0},
|
|
402
|
+
"is_full_time_student": {"2023": False},
|
|
394
403
|
},
|
|
395
404
|
"your first dependent": {
|
|
396
405
|
"age": {"2023": 4},
|
|
@@ -403,6 +412,7 @@ def test_household_with_dependent(sample_taxsim_input_for_household_with_depende
|
|
|
403
412
|
"early_head_start": {"2023": 0},
|
|
404
413
|
"commodity_supplemental_food_program": {"2023": 0},
|
|
405
414
|
"medical_expense_health_insurance_premiums": {"2023": 0},
|
|
415
|
+
"is_full_time_student": {"2023": False},
|
|
406
416
|
},
|
|
407
417
|
"your second dependent": {
|
|
408
418
|
"age": {"2023": 10},
|
|
@@ -415,6 +425,7 @@ def test_household_with_dependent(sample_taxsim_input_for_household_with_depende
|
|
|
415
425
|
"early_head_start": {"2023": 0},
|
|
416
426
|
"commodity_supplemental_food_program": {"2023": 0},
|
|
417
427
|
"medical_expense_health_insurance_premiums": {"2023": 0},
|
|
428
|
+
"is_full_time_student": {"2023": False},
|
|
418
429
|
},
|
|
419
430
|
},
|
|
420
431
|
"spm_units": {
|
|
@@ -484,6 +495,7 @@ def test_household_with_dependent_single_parent(
|
|
|
484
495
|
"early_head_start": {"2023": 0},
|
|
485
496
|
"commodity_supplemental_food_program": {"2023": 0},
|
|
486
497
|
"medical_expense_health_insurance_premiums": {"2023": 0},
|
|
498
|
+
"is_full_time_student": {"2023": False},
|
|
487
499
|
},
|
|
488
500
|
"your first dependent": {
|
|
489
501
|
"age": {"2023": 4},
|
|
@@ -496,6 +508,7 @@ def test_household_with_dependent_single_parent(
|
|
|
496
508
|
"early_head_start": {"2023": 0},
|
|
497
509
|
"commodity_supplemental_food_program": {"2023": 0},
|
|
498
510
|
"medical_expense_health_insurance_premiums": {"2023": 0},
|
|
511
|
+
"is_full_time_student": {"2023": False},
|
|
499
512
|
},
|
|
500
513
|
"your second dependent": {
|
|
501
514
|
"age": {"2023": 10},
|
|
@@ -508,6 +521,7 @@ def test_household_with_dependent_single_parent(
|
|
|
508
521
|
"early_head_start": {"2023": 0},
|
|
509
522
|
"commodity_supplemental_food_program": {"2023": 0},
|
|
510
523
|
"medical_expense_health_insurance_premiums": {"2023": 0},
|
|
524
|
+
"is_full_time_student": {"2023": False},
|
|
511
525
|
},
|
|
512
526
|
},
|
|
513
527
|
"spm_units": {
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
"""TAXSIM input has no student status, so every person is a non-student.
|
|
2
|
+
|
|
3
|
+
The emulator does not default anyone to being a student (taxsim #532, where
|
|
4
|
+
a 19-year-old dependent is a non-student). PE-US's ``is_full_time_student``
|
|
5
|
+
reads ``is_in_k12_school``, which PE-US imputes for ages 5 to 17, so a spouse
|
|
6
|
+
aged 17 or younger was a full-time student. IRC 21(d)(2)
|
|
7
|
+
(https://www.law.cornell.edu/uscode/text/26/21#d_2) then deemed them to have
|
|
8
|
+
earned income for the child and dependent care credit:
|
|
9
|
+
|
|
10
|
+
> (2) Special rule for spouse who is a student or incapable of caring for
|
|
11
|
+
> himself In the case of a spouse who is a student or a qualifying
|
|
12
|
+
> individual described in subsection (b)(1)(C), for purposes of paragraph
|
|
13
|
+
> (1), such spouse shall be deemed for each month during which such spouse
|
|
14
|
+
> is a full-time student at an educational institution, or is such a
|
|
15
|
+
> qualifying individual, to be gainfully employed and to have earned income
|
|
16
|
+
> of not less than— (A) $250 if subsection (c)(1) applies for the taxable
|
|
17
|
+
> year, or (B) $500 if subsection (c)(2) applies for the taxable year.
|
|
18
|
+
|
|
19
|
+
So a joint return whose 17-year-old spouse earned little or nothing got a
|
|
20
|
+
CDCC on $3,000 or $6,000 of deemed earnings, which TAXSIM does not give.
|
|
21
|
+
|
|
22
|
+
Ground truth (evidence rule 4): every expected value below is taxsimtest
|
|
23
|
+
output, build cd2026081819 (resources/taxsimtest/taxsimtest-osx.exe, sha256
|
|
24
|
+
4a17af9c2adbea27b1e6cce240610aede264e008bcdf64b131e0c81220f62b8c), run with
|
|
25
|
+
idtl=2 on exactly the PROBES rows. TAXSIM-35 (resources/taxsim35/
|
|
26
|
+
taxsim35-osx.exe, cdate-2025Aug23) gives the same v24 on the 2021-2024 rows;
|
|
27
|
+
it does not run 2025. Before this change the emulator (policyengine-us
|
|
28
|
+
2.58.0) gave v24 of 600, 1,200, 0, 1,200, 600 and 1,500 on rows 1-6.
|
|
29
|
+
|
|
30
|
+
The records come from Tax-Calculator's PE-TAXSIM validation
|
|
31
|
+
(PSLmodels/Tax-Calculator taxcalc/validation/pe_taxsim), where five c-sample
|
|
32
|
+
units in 2022-2024 had a 17-year-old spouse and this CDCC difference.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
import io
|
|
36
|
+
import platform
|
|
37
|
+
import subprocess
|
|
38
|
+
from pathlib import Path
|
|
39
|
+
|
|
40
|
+
import numpy as np
|
|
41
|
+
import pandas as pd
|
|
42
|
+
import pytest
|
|
43
|
+
from hypothesis import HealthCheck, given, settings
|
|
44
|
+
from hypothesis import strategies as st
|
|
45
|
+
|
|
46
|
+
import policyengine_taxsim.runners.policyengine_runner as runner_module
|
|
47
|
+
from policyengine_taxsim import export_household, generate_household
|
|
48
|
+
from policyengine_taxsim.runners.policyengine_runner import (
|
|
49
|
+
PolicyEngineRunner,
|
|
50
|
+
TaxsimMicrosimDataset,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
TAXSIMTEST_OSX = (
|
|
54
|
+
Path(__file__).resolve().parent.parent
|
|
55
|
+
/ "resources"
|
|
56
|
+
/ "taxsimtest"
|
|
57
|
+
/ "taxsimtest-osx.exe"
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
PROBES = (
|
|
61
|
+
"taxsimid,year,state,mstat,page,sage,depx,age1,age2,pwages,swages,"
|
|
62
|
+
"childcare,idtl\n"
|
|
63
|
+
# Spouse 17 with no earnings, one child under 13.
|
|
64
|
+
"1,2024,0,2,40,17,1,3,0,60000,0,3000,2\n"
|
|
65
|
+
# Spouse 17 earning $2,000, two children under 13.
|
|
66
|
+
"2,2024,0,2,40,17,2,3,8,60000,2000,7000,2\n"
|
|
67
|
+
# Control: the same as row 1 with a spouse aged 40.
|
|
68
|
+
"3,2024,0,2,40,40,1,3,0,60000,0,3000,2\n"
|
|
69
|
+
# Both spouses 17 (Tax-Calculator c23 unit 7174 pattern).
|
|
70
|
+
"4,2023,0,2,17,17,2,3,8,93000,0,6000,2\n"
|
|
71
|
+
# Spouse 16 earning $1,000 (2025).
|
|
72
|
+
"5,2025,0,2,40,16,1,3,0,60000,1000,3000,2\n"
|
|
73
|
+
# 2021, when the CDCC was refundable.
|
|
74
|
+
"6,2021,0,2,40,17,1,3,0,60000,0,3000,2\n"
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
# taxsimid -> (v24, fiitax), taxsimtest build cd2026081819.
|
|
78
|
+
TAXSIMTEST_EXPECTED = {
|
|
79
|
+
1: (0.0, 1232.00),
|
|
80
|
+
2: (400.0, -1072.98),
|
|
81
|
+
3: (0.0, 1232.00),
|
|
82
|
+
4: (0.0, 3396.00),
|
|
83
|
+
5: (200.0, 663.00),
|
|
84
|
+
6: (0.0, -4010.00),
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def _records(csv: str) -> pd.DataFrame:
|
|
89
|
+
return pd.read_csv(io.StringIO(csv))
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def _taxsim_input(row: pd.Series) -> dict:
|
|
93
|
+
return {
|
|
94
|
+
key: int(value) if float(value).is_integer() else float(value)
|
|
95
|
+
for key, value in row.items()
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
@pytest.fixture(scope="module")
|
|
100
|
+
def runner_result():
|
|
101
|
+
result = PolicyEngineRunner(_records(PROBES)).run(show_progress=False)
|
|
102
|
+
result["taxsimid"] = result["taxsimid"].astype(int)
|
|
103
|
+
return result.set_index("taxsimid")
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
@pytest.mark.parametrize("taxsimid", sorted(TAXSIMTEST_EXPECTED))
|
|
107
|
+
def test_runner_matches_taxsimtest(runner_result, taxsimid):
|
|
108
|
+
v24, fiitax = TAXSIMTEST_EXPECTED[taxsimid]
|
|
109
|
+
row = runner_result.loc[taxsimid]
|
|
110
|
+
assert row["v24"] == pytest.approx(v24, abs=0.01)
|
|
111
|
+
assert row["fiitax"] == pytest.approx(fiitax, abs=0.01)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
@pytest.mark.parametrize("taxsimid", sorted(TAXSIMTEST_EXPECTED))
|
|
115
|
+
def test_single_household_path_matches_taxsimtest(taxsimid):
|
|
116
|
+
records = _records(PROBES).set_index("taxsimid", drop=False)
|
|
117
|
+
taxsim_input = _taxsim_input(records.loc[taxsimid])
|
|
118
|
+
situation = generate_household(dict(taxsim_input))
|
|
119
|
+
out = export_household(taxsim_input, situation, False, False)
|
|
120
|
+
v24, fiitax = TAXSIMTEST_EXPECTED[taxsimid]
|
|
121
|
+
assert out["v24"] == pytest.approx(v24, abs=0.01)
|
|
122
|
+
assert out["fiitax"] == pytest.approx(fiitax, abs=0.01)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
@pytest.mark.skipif(
|
|
126
|
+
platform.system() != "Darwin",
|
|
127
|
+
reason="Expected values were taken from taxsimtest-osx.exe (cd2026081819).",
|
|
128
|
+
)
|
|
129
|
+
def test_expectations_match_taxsimtest():
|
|
130
|
+
"""The expected constants are the bundled taxsimtest binary's output."""
|
|
131
|
+
try:
|
|
132
|
+
completed = subprocess.run(
|
|
133
|
+
[str(TAXSIMTEST_OSX)],
|
|
134
|
+
input=_records(PROBES).to_csv(index=False),
|
|
135
|
+
capture_output=True,
|
|
136
|
+
text=True,
|
|
137
|
+
timeout=60,
|
|
138
|
+
)
|
|
139
|
+
except OSError as error:
|
|
140
|
+
pytest.skip(f"taxsimtest binary cannot run here: {error}")
|
|
141
|
+
assert completed.returncode == 0, completed.stderr
|
|
142
|
+
taxsim = pd.read_csv(io.StringIO(completed.stdout))
|
|
143
|
+
taxsim["taxsimid"] = taxsim["taxsimid"].astype(int)
|
|
144
|
+
taxsim = taxsim.set_index("taxsimid")
|
|
145
|
+
for taxsimid, (v24, fiitax) in TAXSIMTEST_EXPECTED.items():
|
|
146
|
+
assert taxsim.loc[taxsimid, "v24"] == pytest.approx(v24, abs=0.01)
|
|
147
|
+
assert taxsim.loc[taxsimid, "fiitax"] == pytest.approx(fiitax, abs=0.01)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def test_no_person_is_a_student_in_either_path():
|
|
151
|
+
df = _records(PROBES)
|
|
152
|
+
# The runner simulates each year separately (people differ by year).
|
|
153
|
+
for year, year_df in df.groupby("year"):
|
|
154
|
+
year_df = year_df.reset_index(drop=True)
|
|
155
|
+
runner = PolicyEngineRunner(year_df)
|
|
156
|
+
dataset = TaxsimMicrosimDataset(year_df)
|
|
157
|
+
try:
|
|
158
|
+
dataset.generate()
|
|
159
|
+
sim = runner._build_configured_sim(dataset, year_df)
|
|
160
|
+
student = sim.calculate("is_full_time_student", str(int(year)))
|
|
161
|
+
# Every PROBES row is a joint return: two filers plus dependents.
|
|
162
|
+
assert len(student) == 2 * len(year_df) + int(year_df["depx"].sum())
|
|
163
|
+
assert not np.asarray(student).any()
|
|
164
|
+
assert "is_full_time_student" in sim.input_variables
|
|
165
|
+
finally:
|
|
166
|
+
dataset.cleanup()
|
|
167
|
+
|
|
168
|
+
for _, row in df.iterrows():
|
|
169
|
+
situation = generate_household(_taxsim_input(row))
|
|
170
|
+
year = str(int(row["year"]))
|
|
171
|
+
for person in situation["people"].values():
|
|
172
|
+
assert person["is_full_time_student"] == {year: False}
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
# Property tests. Joint returns with wages only and children under 13, so
|
|
176
|
+
# each spouse's earned income for IRC 21(d) is their wages. Without deemed
|
|
177
|
+
# income the credit is at most the applicable percentage (never above 50%)
|
|
178
|
+
# of the lower earner's wages.
|
|
179
|
+
_joint_record = st.fixed_dictionaries(
|
|
180
|
+
{
|
|
181
|
+
"year": st.integers(2021, 2025),
|
|
182
|
+
"page": st.integers(25, 64),
|
|
183
|
+
"sage": st.integers(5, 17),
|
|
184
|
+
"depx": st.integers(1, 2),
|
|
185
|
+
"age1": st.integers(1, 12),
|
|
186
|
+
"age2": st.integers(1, 12),
|
|
187
|
+
"pwages": st.integers(0, 40).map(lambda k: 5000 * k),
|
|
188
|
+
"swages": st.integers(0, 8).map(lambda k: 500 * k),
|
|
189
|
+
"childcare": st.integers(0, 20).map(lambda k: 500 * k),
|
|
190
|
+
}
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def _frame(records):
|
|
195
|
+
rows = []
|
|
196
|
+
for i, rec in enumerate(records, start=1):
|
|
197
|
+
row = dict(rec, taxsimid=i, state=0, mstat=2, idtl=2)
|
|
198
|
+
if row["depx"] < 2:
|
|
199
|
+
row["age2"] = 0
|
|
200
|
+
rows.append(row)
|
|
201
|
+
return pd.DataFrame(rows)
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
@settings(
|
|
205
|
+
max_examples=6,
|
|
206
|
+
deadline=None,
|
|
207
|
+
suppress_health_check=[HealthCheck.too_slow, HealthCheck.data_too_large],
|
|
208
|
+
)
|
|
209
|
+
@given(st.lists(_joint_record, min_size=1, max_size=5))
|
|
210
|
+
def test_minor_spouse_gets_no_deemed_earnings(records):
|
|
211
|
+
"""For a spouse aged 5 to 17: (1) the CDCC is at most half the lower
|
|
212
|
+
earner's wages; (2) the runner and single-household paths agree; (3) the
|
|
213
|
+
CDCC is the same as for an otherwise identical spouse aged 40, since only
|
|
214
|
+
student status could separate them."""
|
|
215
|
+
df = _frame(records)
|
|
216
|
+
adult = df.assign(sage=40)
|
|
217
|
+
|
|
218
|
+
def run(frame):
|
|
219
|
+
out = PolicyEngineRunner(frame).run(show_progress=False)
|
|
220
|
+
out["taxsimid"] = out["taxsimid"].astype(int)
|
|
221
|
+
return out.set_index("taxsimid")
|
|
222
|
+
|
|
223
|
+
minor_out = run(df)
|
|
224
|
+
adult_out = run(adult)
|
|
225
|
+
for _, rec in df.iterrows():
|
|
226
|
+
taxsimid = int(rec["taxsimid"])
|
|
227
|
+
v24 = float(minor_out.loc[taxsimid, "v24"])
|
|
228
|
+
lower_wages = min(rec["pwages"], rec["swages"])
|
|
229
|
+
assert v24 <= 0.5 * lower_wages + 0.01
|
|
230
|
+
assert v24 == pytest.approx(float(adult_out.loc[taxsimid, "v24"]), abs=0.01)
|
|
231
|
+
taxsim_input = _taxsim_input(rec)
|
|
232
|
+
out = export_household(
|
|
233
|
+
taxsim_input, generate_household(dict(taxsim_input)), False, False
|
|
234
|
+
)
|
|
235
|
+
assert out["v24"] == pytest.approx(v24, abs=0.01)
|
|
236
|
+
assert out["fiitax"] == pytest.approx(
|
|
237
|
+
float(minor_out.loc[taxsimid, "fiitax"]), abs=0.01
|
|
238
|
+
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/.github/is-version-number-acceptable.sh
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/.github/workflows/refresh-dashboard.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/public/data/2021/summary_2021.json
RENAMED
|
File without changes
|
|
File without changes
|
{policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/public/data/2022/summary_2022.json
RENAMED
|
File without changes
|
|
File without changes
|
{policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/public/data/2023/summary_2023.json
RENAMED
|
File without changes
|
|
File without changes
|
{policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/public/data/2024/summary_2024.json
RENAMED
|
File without changes
|
|
File without changes
|
{policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/public/data/2025/summary_2025.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/public/sample_ecps_2024.csv
RENAMED
|
File without changes
|
{policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/scripts/extract-config.cjs
RENAMED
|
File without changes
|
|
File without changes
|
{policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/app/dashboard/page.jsx
RENAMED
|
File without changes
|
{policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/app/documentation/page.jsx
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{policyengine_taxsim-3.2.2 → policyengine_taxsim-3.2.4}/dashboard/src/components/CsvRunner.jsx
RENAMED
|
File without changes
|
|
File without changes
|