policyengine 3.7.0__tar.gz → 4.3.0__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-3.7.0 → policyengine-4.3.0}/.github/workflows/pr_docs_changes.yaml +3 -6
- {policyengine-3.7.0 → policyengine-4.3.0}/CHANGELOG.md +112 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/Makefile +2 -5
- {policyengine-3.7.0 → policyengine-4.3.0}/PKG-INFO +44 -18
- {policyengine-3.7.0 → policyengine-4.3.0}/README.md +41 -17
- policyengine-4.3.0/docs/.gitignore +5 -0
- policyengine-4.3.0/docs/_generator/README.md +52 -0
- policyengine-4.3.0/docs/_generator/build_reference.py +392 -0
- policyengine-4.3.0/docs/_quarto.yml +59 -0
- policyengine-4.3.0/docs/countries.md +83 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/docs/dev.md +12 -6
- {policyengine-3.7.0 → policyengine-4.3.0}/docs/examples.md +10 -18
- policyengine-4.3.0/docs/getting-started.md +113 -0
- policyengine-4.3.0/docs/households.md +129 -0
- policyengine-4.3.0/docs/impact-analysis.md +110 -0
- policyengine-4.3.0/docs/index.md +46 -0
- policyengine-4.3.0/docs/microsim.md +152 -0
- policyengine-4.3.0/docs/outputs.md +246 -0
- policyengine-4.3.0/docs/reforms.md +108 -0
- policyengine-4.3.0/docs/regions.md +147 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/docs/release-bundles.md +3 -3
- policyengine-4.3.0/examples/household_impact_example.py +104 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/pyproject.toml +4 -1
- {policyengine-3.7.0 → policyengine-4.3.0}/scripts/generate_trace_tros.py +2 -2
- policyengine-4.3.0/scripts/refresh_release_bundle.py +79 -0
- policyengine-4.3.0/src/policyengine/__init__.py +46 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/cli.py +3 -3
- policyengine-4.3.0/src/policyengine/core/__init__.py +41 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/core/scoping_strategy.py +6 -3
- policyengine-4.3.0/src/policyengine/core/simulation.py +177 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/core/tax_benefit_model_version.py +3 -2
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/countries/uk/regions.py +1 -1
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/countries/us/regions.py +1 -1
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/data/release_manifests/uk.json +2 -2
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/data/release_manifests/us.json +2 -2
- policyengine-4.3.0/src/policyengine/graph/__init__.py +41 -0
- policyengine-4.3.0/src/policyengine/graph/extractor.py +188 -0
- policyengine-4.3.0/src/policyengine/graph/graph.py +130 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/outputs/__init__.py +2 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/outputs/constituency_impact.py +2 -1
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/outputs/local_authority_impact.py +2 -1
- policyengine-3.7.0/src/policyengine/tax_benefit_models/us/outputs.py → policyengine-4.3.0/src/policyengine/outputs/program_statistics.py +1 -1
- policyengine-4.3.0/src/policyengine/provenance/__init__.py +92 -0
- policyengine-4.3.0/src/policyengine/provenance/bundle.py +319 -0
- policyengine-3.7.0/src/policyengine/core/trace_tro.py → policyengine-4.3.0/src/policyengine/provenance/trace.py +1 -1
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/results/trace_tro.py +2 -2
- policyengine-4.3.0/src/policyengine/tax_benefit_models/common/__init__.py +16 -0
- policyengine-4.3.0/src/policyengine/tax_benefit_models/common/extra_variables.py +52 -0
- policyengine-4.3.0/src/policyengine/tax_benefit_models/common/model_version.py +320 -0
- policyengine-4.3.0/src/policyengine/tax_benefit_models/common/reform.py +197 -0
- policyengine-4.3.0/src/policyengine/tax_benefit_models/common/result.py +79 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/tax_benefit_models/uk/__init__.py +22 -16
- policyengine-4.3.0/src/policyengine/tax_benefit_models/uk/analysis.py +122 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/tax_benefit_models/uk/datasets.py +1 -1
- policyengine-4.3.0/src/policyengine/tax_benefit_models/uk/household.py +191 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/tax_benefit_models/uk/model.py +34 -197
- policyengine-4.3.0/src/policyengine/tax_benefit_models/us/__init__.py +74 -0
- policyengine-4.3.0/src/policyengine/tax_benefit_models/us/analysis.py +139 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/tax_benefit_models/us/datasets.py +1 -1
- policyengine-4.3.0/src/policyengine/tax_benefit_models/us/household.py +245 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/tax_benefit_models/us/model.py +50 -223
- policyengine-4.3.0/src/policyengine/utils/household_validation.py +113 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine.egg-info/PKG-INFO +44 -18
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine.egg-info/SOURCES.txt +47 -12
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine.egg-info/requires.txt +3 -0
- policyengine-4.3.0/tests/fixtures/household_calculator_snapshots/uk_couple_two_kids.json +139 -0
- policyengine-4.3.0/tests/fixtures/household_calculator_snapshots/uk_model_surface.json +11 -0
- policyengine-4.3.0/tests/fixtures/household_calculator_snapshots/uk_single_adult_employment_income.json +58 -0
- policyengine-4.3.0/tests/fixtures/household_calculator_snapshots/uk_single_adult_no_income.json +58 -0
- policyengine-4.3.0/tests/fixtures/household_calculator_snapshots/uk_single_parent_one_child.json +85 -0
- policyengine-4.3.0/tests/fixtures/household_calculator_snapshots/us_married_two_kids_high_income.json +97 -0
- policyengine-4.3.0/tests/fixtures/household_calculator_snapshots/us_model_surface.json +11 -0
- policyengine-4.3.0/tests/fixtures/household_calculator_snapshots/us_single_adult_employment_income.json +46 -0
- policyengine-4.3.0/tests/fixtures/household_calculator_snapshots/us_single_adult_no_income.json +46 -0
- policyengine-4.3.0/tests/fixtures/household_calculator_snapshots/us_single_parent_one_child.json +63 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/fixtures/us_reform_fixtures.py +29 -36
- policyengine-4.3.0/tests/test_bundle_refresh.py +321 -0
- policyengine-4.3.0/tests/test_dict_reforms_on_simulation.py +128 -0
- policyengine-4.3.0/tests/test_extra_variables.py +330 -0
- policyengine-4.3.0/tests/test_graph/conftest.py +0 -0
- policyengine-4.3.0/tests/test_graph/test_extractor.py +312 -0
- policyengine-4.3.0/tests/test_household_calculator_snapshot.py +217 -0
- policyengine-4.3.0/tests/test_household_impact.py +215 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/test_manifest_version_mismatch.py +24 -25
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/test_release_manifests.py +19 -19
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/test_trace_tro.py +8 -8
- policyengine-4.3.0/tests/test_us_microsim_structural_reforms.py +336 -0
- policyengine-4.3.0/tests/test_us_reform_application.py +71 -0
- policyengine-3.7.0/docs/.gitignore +0 -2
- policyengine-3.7.0/docs/advanced-outputs.md +0 -276
- policyengine-3.7.0/docs/core-concepts.md +0 -662
- policyengine-3.7.0/docs/country-models-uk.md +0 -374
- policyengine-3.7.0/docs/country-models-us.md +0 -444
- policyengine-3.7.0/docs/economic-impact-analysis.md +0 -287
- policyengine-3.7.0/docs/index.md +0 -20
- policyengine-3.7.0/docs/myst.yml +0 -27
- policyengine-3.7.0/docs/regions-and-scoping.md +0 -251
- policyengine-3.7.0/examples/household_impact_example.py +0 -120
- policyengine-3.7.0/src/policyengine/core/__init__.py +0 -62
- policyengine-3.7.0/src/policyengine/core/simulation.py +0 -91
- policyengine-3.7.0/src/policyengine/tax_benefit_models/uk/analysis.py +0 -265
- policyengine-3.7.0/src/policyengine/tax_benefit_models/uk/outputs.py +0 -105
- policyengine-3.7.0/src/policyengine/tax_benefit_models/us/__init__.py +0 -55
- policyengine-3.7.0/src/policyengine/tax_benefit_models/us/analysis.py +0 -311
- policyengine-3.7.0/tests/test_household_impact.py +0 -202
- policyengine-3.7.0/tests/test_us_reform_application.py +0 -148
- {policyengine-3.7.0 → policyengine-4.3.0}/.claude/policyengine-guide.md +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/.claude/quick-reference.md +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/.github/CONTRIBUTING.md +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/.github/bump_version.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/.github/changelog_template.md +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/.github/check-changelog.sh +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/.github/fetch_version.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/.github/get-changelog-diff.sh +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/.github/has-functional-changes.sh +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/.github/is-version-number-acceptable.sh +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/.github/publish-git-tag.sh +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/.github/workflows/pr_code_changes.yaml +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/.github/workflows/push.yaml +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/.gitignore +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/.python-version +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/LICENSE +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/changelog.d/.gitkeep +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/docs/visualisation.md +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/examples/employment_income_variation_uk.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/examples/employment_income_variation_us.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/examples/income_bands_uk.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/examples/income_distribution_us.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/examples/paper_repro_uk.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/examples/policy_change_uk.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/examples/speedtest_us_simulation.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/examples/us_budgetary_impact.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/setup.cfg +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/core/cache.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/core/dataset.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/core/dynamic.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/core/output.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/core/parameter.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/core/parameter_node.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/core/parameter_value.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/core/policy.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/core/region.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/core/tax_benefit_model.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/core/variable.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/countries/__init__.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/countries/uk/__init__.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/countries/us/__init__.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/countries/us/data/__init__.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/countries/us/data/districts.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/countries/us/data/places.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/countries/us/data/states.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/data/schemas/trace_tro.schema.json +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/outputs/aggregate.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/outputs/change_aggregate.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/outputs/congressional_district_impact.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/outputs/decile_impact.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/outputs/inequality.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/outputs/intra_decile_impact.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/outputs/poverty.py +0 -0
- /policyengine-3.7.0/src/policyengine/core/release_manifest.py → /policyengine-4.3.0/src/policyengine/provenance/manifest.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/results/__init__.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/results/schema.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/results/tracking.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/utils/__init__.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/utils/dates.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/utils/design.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/utils/entity_utils.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/utils/parameter_labels.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/utils/parametric_reforms.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine/utils/plotting.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine.egg-info/dependency_links.txt +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine.egg-info/entry_points.txt +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/src/policyengine.egg-info/top_level.txt +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/__init__.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/conftest.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/fixtures/__init__.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/fixtures/filtering_fixtures.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/fixtures/parameter_labels_fixtures.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/fixtures/parametric_reforms_fixtures.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/fixtures/poverty_by_demographics_fixtures.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/fixtures/region_fixtures.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/fixtures/variable_label_fixtures.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/test_aggregate.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/test_bump_version.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/test_cache.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/test_change_aggregate.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/test_congressional_district_impact.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/test_constituency_impact.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/test_entity_mapping.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/test_entity_utils.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/test_filtering.py +0 -0
- {policyengine-3.7.0/src/policyengine → policyengine-4.3.0/tests/test_graph}/__init__.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/test_inequality.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/test_intra_decile_impact.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/test_local_authority_impact.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/test_models.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/test_pandas3_compatibility.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/test_parameter_labels.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/test_parametric_reforms.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/test_poverty.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/test_poverty_by_demographics.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/test_poverty_run.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/test_region.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/test_results.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/test_scoping_strategy.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/test_uk_regions.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/test_us_regions.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/tests/test_variable_labels.py +0 -0
- {policyengine-3.7.0 → policyengine-4.3.0}/uv.lock +0 -0
|
@@ -18,10 +18,7 @@ jobs:
|
|
|
18
18
|
steps:
|
|
19
19
|
- name: Checkout repo
|
|
20
20
|
uses: actions/checkout@v4
|
|
21
|
-
-
|
|
22
|
-
|
|
23
|
-
node-version: 18.x
|
|
24
|
-
- name: Install MyST
|
|
25
|
-
run: npm install -g mystmd
|
|
21
|
+
- name: Set up Quarto
|
|
22
|
+
uses: quarto-dev/quarto-actions/setup@v2
|
|
26
23
|
- name: Test documentation builds
|
|
27
|
-
run:
|
|
24
|
+
run: quarto render docs
|
|
@@ -1,3 +1,115 @@
|
|
|
1
|
+
## [4.3.0] - 2026-04-20
|
|
2
|
+
|
|
3
|
+
### Added
|
|
4
|
+
|
|
5
|
+
- Added `policyengine.provenance.refresh_release_bundle`. Given a country and optional new model/data versions, the helper fetches the updated PyPI wheel metadata + HF dataset sha256, rewrites `data/release_manifests/{country}.json` and the matching extra pin in `pyproject.toml`, and (optionally) regenerates the bundle's TRACE TRO sidecar. A thin `scripts/refresh_release_bundle.py` wrapper exposes the library function as a CLI for release engineers. Unit-tested offline via mocked PyPI/HF responses.
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
## [4.2.1] - 2026-04-20
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- Rewrite docs content for the v4 API: separate pages per task (households, reforms, microsim, outputs, impact analysis, regions), updated code samples against real output classes and `Simulation` dict reforms.
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
## [4.2.0] - 2026-04-20
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- Added ``policyengine.graph`` — a static-analysis-based variable dependency graph for PolicyEngine source trees. ``extract_from_path(path)`` walks a directory of Variable subclasses, parses formula-method bodies for ``entity("<var>", period)`` and ``add(entity, period, [list])`` references, and returns a ``VariableGraph``. Queries include ``deps(var)`` (direct dependencies), ``impact(var)`` (transitive downstream), and ``path(src, dst)`` (shortest dependency chain). No runtime dependency on country models — indexes ``policyengine-us`` (4,577 variables) in under a second.
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
## [4.1.1] - 2026-04-20
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- Fixed `Simulation.extra_variables` being silently ignored on the US and UK microsim paths. The field is declared on the base `Simulation` and honored by the household calculator, but the country `run()` methods previously only iterated `self.entity_variables` — extras passed via `Simulation(extra_variables={...})` never reached the output dataset. Both country paths now route through a shared `MicrosimulationModelVersion.resolve_entity_variables` helper that merges defaults with extras, dedupes overlapping entries, and validates entity keys + variable names with close-match suggestions. Closes #303.
|
|
27
|
+
- Fixed structural-reform propagation in the US microsim path. `Simulation(policy={"gov.contrib.ctc.*": ...})` previously crashed at `.ensure()` with `AttributeError: 'NoneType' object has no attribute 'entity'` because `_build_simulation_from_dataset` instantiated entities against the module-level `policyengine_us.system` (no reform applied) instead of `microsim.tax_benefit_system` (reform applied). Published external reforms that activate all three `gov.contrib.ctc.*.in_effect` gates (e.g., app.policyengine.org policy 94589) now run end-to-end through `pe.us.economic_impact_analysis`.
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
## [4.1.0] - 2026-04-20
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
|
|
34
|
+
- ``Simulation(policy={...})`` and ``Simulation(dynamic={...})`` now accept the same flat ``{"param.path": value}`` / ``{"param.path": {date: value}}`` dict that ``pe.{uk,us}.calculate_household(reform=...)`` accepts. Dicts are compiled to full ``Policy`` / ``Dynamic`` objects on construction using the ``tax_benefit_model_version`` for parameter-path validation and ``dataset.year`` for scalar effective-date defaulting. Removes the last place where population microsim required building ``Parameter`` / ``ParameterValue`` by hand.
|
|
35
|
+
- **BREAKING (v4):** Collapse the household-calculator surface into a
|
|
36
|
+
single agent-friendly entry point, ``pe.us.calculate_household`` /
|
|
37
|
+
``pe.uk.calculate_household``.
|
|
38
|
+
|
|
39
|
+
New public API:
|
|
40
|
+
|
|
41
|
+
- ``policyengine/__init__.py`` populated with canonical accessors:
|
|
42
|
+
``pe.us``, ``pe.uk``, ``pe.Simulation`` (replacing the empty top-level
|
|
43
|
+
module). ``import policyengine as pe`` now gives you everything a
|
|
44
|
+
new coding session needs to reach in one line.
|
|
45
|
+
- ``pe.us.calculate_household(**kwargs)`` and ``pe.uk.calculate_household``
|
|
46
|
+
take flat keyword arguments (``people``, per-entity overrides,
|
|
47
|
+
``year``, ``reform``, ``extra_variables``) instead of a pydantic
|
|
48
|
+
input wrapper.
|
|
49
|
+
- ``reform=`` accepts a plain dict: ``{parameter_path: value}`` or
|
|
50
|
+
``{parameter_path: {effective_date: value}}``. Compiles internally.
|
|
51
|
+
- Returns :class:`HouseholdResult` (new) with dot-access:
|
|
52
|
+
``result.tax_unit.income_tax``, ``result.household.household_net_income``,
|
|
53
|
+
``result.person[0].age``. Singleton entities are
|
|
54
|
+
:class:`EntityResult`; ``person`` is a list of them. ``to_dict()``
|
|
55
|
+
and ``write(path)`` serialize to JSON.
|
|
56
|
+
- ``extra_variables=[...]`` is now a flat list; the library dispatches
|
|
57
|
+
each name to its entity by looking it up on the model.
|
|
58
|
+
- Unknown variable names (in ``people``, entity overrides, or
|
|
59
|
+
``extra_variables``) raise ``ValueError`` with a ``difflib`` close-match
|
|
60
|
+
suggestion and a paste-able fix hint.
|
|
61
|
+
- Unknown dot-access on a result raises ``AttributeError`` with the
|
|
62
|
+
list of available variables plus the ``extra_variables=[...]`` call
|
|
63
|
+
that would surface the requested one.
|
|
64
|
+
|
|
65
|
+
Removed (v4 breaking):
|
|
66
|
+
|
|
67
|
+
- ``USHouseholdInput`` / ``UKHouseholdInput`` / ``USHouseholdOutput`` /
|
|
68
|
+
``UKHouseholdOutput`` pydantic wrappers.
|
|
69
|
+
- ``calculate_household_impact`` — the name was misleading (it
|
|
70
|
+
returned levels, not an impact vs. baseline). Reserved for a future
|
|
71
|
+
delta function.
|
|
72
|
+
- The bare ``us_model`` / ``uk_model`` label-only singletons; each
|
|
73
|
+
country module now exposes ``.model`` pointing at the real
|
|
74
|
+
``TaxBenefitModelVersion`` (kept ``us_latest`` / ``uk_latest``
|
|
75
|
+
aliases for compatibility with any in-flight downstream code).
|
|
76
|
+
|
|
77
|
+
New internal module:
|
|
78
|
+
|
|
79
|
+
- ``policyengine.tax_benefit_models.common`` — ``compile_reform``,
|
|
80
|
+
``dispatch_extra_variables``, ``EntityResult``, ``HouseholdResult``
|
|
81
|
+
shared by both country implementations.
|
|
82
|
+
|
|
83
|
+
### Changed
|
|
84
|
+
|
|
85
|
+
- Extracted shared `MicrosimulationModelVersion` base class in `policyengine.tax_benefit_models.common`. Country subclasses now declare class-level metadata (`country_code`, `package_name`, `group_entities`) and implement a handful of thin hooks; `run()` stays per-country. Byte-level snapshot tests verify zero output drift.
|
|
86
|
+
- Documentation refreshed for the v4 agent-first surface. README, `core-concepts`, `economic-impact-analysis`, `country-models-{uk,us}`, `regions-and-scoping`, `examples`, and `dev` now lead with `pe.uk.*` / `pe.us.*` entry points and flat-kwarg `calculate_household` usage. Removed leftover docs for the dropped `filter_field`/`filter_value` simulation fields. `examples/household_impact_example.py` rewritten against the v4 API.
|
|
87
|
+
- **BREAKING (v4):** Separate the provenance layer from the core
|
|
88
|
+
value-object layer.
|
|
89
|
+
|
|
90
|
+
- ``policyengine/core/release_manifest.py`` → ``policyengine/provenance/manifest.py``
|
|
91
|
+
- ``policyengine/core/trace_tro.py`` → ``policyengine/provenance/trace.py``
|
|
92
|
+
- New ``policyengine.provenance`` package re-exports the public
|
|
93
|
+
surface (``get_release_manifest``, ``get_data_release_manifest``,
|
|
94
|
+
``build_trace_tro_from_release_bundle``, ``build_simulation_trace_tro``,
|
|
95
|
+
``serialize_trace_tro``, ``canonical_json_bytes``,
|
|
96
|
+
``compute_trace_composition_fingerprint``, etc.).
|
|
97
|
+
- ``policyengine.core`` no longer re-exports provenance types.
|
|
98
|
+
``policyengine.core`` shrinks to value objects only (Dataset,
|
|
99
|
+
Variable, Parameter, Policy, Dynamic, Simulation, Region,
|
|
100
|
+
TaxBenefitModel, TaxBenefitModelVersion, scoping strategies).
|
|
101
|
+
- ``import policyengine.core.scoping_strategy`` no longer imports
|
|
102
|
+
``h5py`` at module load; the weight-replacement code path
|
|
103
|
+
lazy-imports it. ``import policyengine.outputs.constituency_impact``
|
|
104
|
+
and ``import policyengine.outputs.local_authority_impact`` do the
|
|
105
|
+
same.
|
|
106
|
+
- Migration for downstream: replace
|
|
107
|
+
``from policyengine.core import DataReleaseManifest`` (et al.)
|
|
108
|
+
with ``from policyengine.provenance import DataReleaseManifest``.
|
|
109
|
+
The country-module imports in internal code (``tax_benefit_models/{us,uk}/model.py``
|
|
110
|
+
and ``datasets.py``) are already updated.
|
|
111
|
+
|
|
112
|
+
|
|
1
113
|
## [3.7.0] - 2026-04-19
|
|
2
114
|
|
|
3
115
|
### Removed
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
.PHONY: docs docs-serve
|
|
2
2
|
|
|
3
|
-
MYSTMD_VERSION ?= 1.8.3
|
|
4
|
-
MYST_CMD = npx --yes mystmd@$(MYSTMD_VERSION)
|
|
5
|
-
|
|
6
3
|
all: build-package
|
|
7
4
|
|
|
8
5
|
docs:
|
|
9
|
-
|
|
6
|
+
quarto render docs
|
|
10
7
|
|
|
11
8
|
docs-serve:
|
|
12
|
-
|
|
9
|
+
quarto preview docs
|
|
13
10
|
|
|
14
11
|
install:
|
|
15
12
|
uv pip install -e .[dev]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: policyengine
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 4.3.0
|
|
4
4
|
Summary: A package to conduct policy analysis using PolicyEngine tax-benefit models.
|
|
5
5
|
Author-email: PolicyEngine <hello@policyengine.org>
|
|
6
6
|
License: GNU AFFERO GENERAL PUBLIC LICENSE
|
|
@@ -682,6 +682,8 @@ Requires-Dist: psutil>=5.9.0
|
|
|
682
682
|
Requires-Dist: packaging>=23.0
|
|
683
683
|
Provides-Extra: plotting
|
|
684
684
|
Requires-Dist: plotly>=5.0.0; extra == "plotting"
|
|
685
|
+
Provides-Extra: graph
|
|
686
|
+
Requires-Dist: networkx>=3.0; extra == "graph"
|
|
685
687
|
Provides-Extra: uk
|
|
686
688
|
Requires-Dist: policyengine_core>=3.25.0; extra == "uk"
|
|
687
689
|
Requires-Dist: policyengine-uk==2.88.0; extra == "uk"
|
|
@@ -714,26 +716,47 @@ A Python package for tax-benefit microsimulation analysis. Run policy simulation
|
|
|
714
716
|
|
|
715
717
|
## Quick start
|
|
716
718
|
|
|
719
|
+
### Household calculator
|
|
720
|
+
|
|
717
721
|
```python
|
|
718
|
-
|
|
719
|
-
from policyengine.tax_benefit_models.uk import PolicyEngineUKDataset, uk_latest
|
|
720
|
-
from policyengine.outputs.aggregate import Aggregate, AggregateType
|
|
722
|
+
import policyengine as pe
|
|
721
723
|
|
|
722
|
-
#
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
filepath="./data/frs_2023_24_year_2026.h5",
|
|
724
|
+
# UK: single adult earning £50,000
|
|
725
|
+
uk = pe.uk.calculate_household(
|
|
726
|
+
people=[{"age": 35, "employment_income": 50_000}],
|
|
726
727
|
year=2026,
|
|
727
728
|
)
|
|
729
|
+
print(uk.person[0].income_tax) # income tax
|
|
730
|
+
print(uk.household.hbai_household_net_income) # net income
|
|
731
|
+
|
|
732
|
+
# US: single filer in California, with a reform
|
|
733
|
+
us = pe.us.calculate_household(
|
|
734
|
+
people=[{"age": 35, "employment_income": 60_000}],
|
|
735
|
+
tax_unit={"filing_status": "SINGLE"},
|
|
736
|
+
household={"state_code": "CA"},
|
|
737
|
+
year=2026,
|
|
738
|
+
reform={"gov.irs.credits.ctc.amount.adult_dependent": 1000},
|
|
739
|
+
)
|
|
740
|
+
print(us.tax_unit.income_tax, us.household.household_net_income)
|
|
741
|
+
```
|
|
728
742
|
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
743
|
+
### Population analysis
|
|
744
|
+
|
|
745
|
+
```python
|
|
746
|
+
import policyengine as pe
|
|
747
|
+
from policyengine.core import Simulation
|
|
748
|
+
from policyengine.outputs.aggregate import Aggregate, AggregateType
|
|
749
|
+
|
|
750
|
+
datasets = pe.uk.ensure_datasets(
|
|
751
|
+
datasets=["hf://policyengine/policyengine-uk-data/enhanced_frs_2023_24.h5"],
|
|
752
|
+
years=[2026],
|
|
753
|
+
data_folder="./data",
|
|
733
754
|
)
|
|
755
|
+
dataset = datasets["enhanced_frs_2023_24_2026"]
|
|
756
|
+
|
|
757
|
+
simulation = Simulation(dataset=dataset, tax_benefit_model_version=pe.uk.model)
|
|
734
758
|
simulation.run()
|
|
735
759
|
|
|
736
|
-
# Calculate total universal credit spending
|
|
737
760
|
agg = Aggregate(
|
|
738
761
|
simulation=simulation,
|
|
739
762
|
variable="universal_credit",
|
|
@@ -744,6 +767,9 @@ agg.run()
|
|
|
744
767
|
print(f"Total UC spending: £{agg.result / 1e9:.1f}bn")
|
|
745
768
|
```
|
|
746
769
|
|
|
770
|
+
For baseline-vs-reform comparisons, see `pe.uk.economic_impact_analysis`
|
|
771
|
+
and its US counterpart.
|
|
772
|
+
|
|
747
773
|
## Documentation
|
|
748
774
|
|
|
749
775
|
**Core concepts:**
|
|
@@ -796,7 +822,7 @@ uv pip install -e .[dev] # install with dev dependencies (pytest, ruff, m
|
|
|
796
822
|
```bash
|
|
797
823
|
make format # ruff format
|
|
798
824
|
make test # pytest with coverage
|
|
799
|
-
make docs # build static
|
|
825
|
+
make docs # build static Quarto HTML docs
|
|
800
826
|
make docs-serve # preview the docs locally
|
|
801
827
|
make clean # remove caches, build artifacts, .h5 files
|
|
802
828
|
```
|
|
@@ -889,12 +915,12 @@ dataset.load()
|
|
|
889
915
|
Simulations apply tax-benefit models to datasets:
|
|
890
916
|
|
|
891
917
|
```python
|
|
918
|
+
import policyengine as pe
|
|
892
919
|
from policyengine.core import Simulation
|
|
893
|
-
from policyengine.tax_benefit_models.uk import uk_latest
|
|
894
920
|
|
|
895
921
|
simulation = Simulation(
|
|
896
922
|
dataset=dataset,
|
|
897
|
-
tax_benefit_model_version=
|
|
923
|
+
tax_benefit_model_version=pe.uk.model,
|
|
898
924
|
)
|
|
899
925
|
simulation.run()
|
|
900
926
|
|
|
@@ -933,7 +959,7 @@ import datetime
|
|
|
933
959
|
|
|
934
960
|
parameter = Parameter(
|
|
935
961
|
name="gov.hmrc.income_tax.allowances.personal_allowance.amount",
|
|
936
|
-
tax_benefit_model_version=
|
|
962
|
+
tax_benefit_model_version=pe.uk.model,
|
|
937
963
|
data_type=float,
|
|
938
964
|
)
|
|
939
965
|
|
|
@@ -952,7 +978,7 @@ policy = Policy(
|
|
|
952
978
|
# Run reform simulation
|
|
953
979
|
reform_sim = Simulation(
|
|
954
980
|
dataset=dataset,
|
|
955
|
-
tax_benefit_model_version=
|
|
981
|
+
tax_benefit_model_version=pe.uk.model,
|
|
956
982
|
policy=policy,
|
|
957
983
|
)
|
|
958
984
|
reform_sim.run()
|
|
@@ -4,26 +4,47 @@ A Python package for tax-benefit microsimulation analysis. Run policy simulation
|
|
|
4
4
|
|
|
5
5
|
## Quick start
|
|
6
6
|
|
|
7
|
+
### Household calculator
|
|
8
|
+
|
|
7
9
|
```python
|
|
8
|
-
|
|
9
|
-
from policyengine.tax_benefit_models.uk import PolicyEngineUKDataset, uk_latest
|
|
10
|
-
from policyengine.outputs.aggregate import Aggregate, AggregateType
|
|
10
|
+
import policyengine as pe
|
|
11
11
|
|
|
12
|
-
#
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
filepath="./data/frs_2023_24_year_2026.h5",
|
|
12
|
+
# UK: single adult earning £50,000
|
|
13
|
+
uk = pe.uk.calculate_household(
|
|
14
|
+
people=[{"age": 35, "employment_income": 50_000}],
|
|
16
15
|
year=2026,
|
|
17
16
|
)
|
|
17
|
+
print(uk.person[0].income_tax) # income tax
|
|
18
|
+
print(uk.household.hbai_household_net_income) # net income
|
|
19
|
+
|
|
20
|
+
# US: single filer in California, with a reform
|
|
21
|
+
us = pe.us.calculate_household(
|
|
22
|
+
people=[{"age": 35, "employment_income": 60_000}],
|
|
23
|
+
tax_unit={"filing_status": "SINGLE"},
|
|
24
|
+
household={"state_code": "CA"},
|
|
25
|
+
year=2026,
|
|
26
|
+
reform={"gov.irs.credits.ctc.amount.adult_dependent": 1000},
|
|
27
|
+
)
|
|
28
|
+
print(us.tax_unit.income_tax, us.household.household_net_income)
|
|
29
|
+
```
|
|
18
30
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
31
|
+
### Population analysis
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
import policyengine as pe
|
|
35
|
+
from policyengine.core import Simulation
|
|
36
|
+
from policyengine.outputs.aggregate import Aggregate, AggregateType
|
|
37
|
+
|
|
38
|
+
datasets = pe.uk.ensure_datasets(
|
|
39
|
+
datasets=["hf://policyengine/policyengine-uk-data/enhanced_frs_2023_24.h5"],
|
|
40
|
+
years=[2026],
|
|
41
|
+
data_folder="./data",
|
|
23
42
|
)
|
|
43
|
+
dataset = datasets["enhanced_frs_2023_24_2026"]
|
|
44
|
+
|
|
45
|
+
simulation = Simulation(dataset=dataset, tax_benefit_model_version=pe.uk.model)
|
|
24
46
|
simulation.run()
|
|
25
47
|
|
|
26
|
-
# Calculate total universal credit spending
|
|
27
48
|
agg = Aggregate(
|
|
28
49
|
simulation=simulation,
|
|
29
50
|
variable="universal_credit",
|
|
@@ -34,6 +55,9 @@ agg.run()
|
|
|
34
55
|
print(f"Total UC spending: £{agg.result / 1e9:.1f}bn")
|
|
35
56
|
```
|
|
36
57
|
|
|
58
|
+
For baseline-vs-reform comparisons, see `pe.uk.economic_impact_analysis`
|
|
59
|
+
and its US counterpart.
|
|
60
|
+
|
|
37
61
|
## Documentation
|
|
38
62
|
|
|
39
63
|
**Core concepts:**
|
|
@@ -86,7 +110,7 @@ uv pip install -e .[dev] # install with dev dependencies (pytest, ruff, m
|
|
|
86
110
|
```bash
|
|
87
111
|
make format # ruff format
|
|
88
112
|
make test # pytest with coverage
|
|
89
|
-
make docs # build static
|
|
113
|
+
make docs # build static Quarto HTML docs
|
|
90
114
|
make docs-serve # preview the docs locally
|
|
91
115
|
make clean # remove caches, build artifacts, .h5 files
|
|
92
116
|
```
|
|
@@ -179,12 +203,12 @@ dataset.load()
|
|
|
179
203
|
Simulations apply tax-benefit models to datasets:
|
|
180
204
|
|
|
181
205
|
```python
|
|
206
|
+
import policyengine as pe
|
|
182
207
|
from policyengine.core import Simulation
|
|
183
|
-
from policyengine.tax_benefit_models.uk import uk_latest
|
|
184
208
|
|
|
185
209
|
simulation = Simulation(
|
|
186
210
|
dataset=dataset,
|
|
187
|
-
tax_benefit_model_version=
|
|
211
|
+
tax_benefit_model_version=pe.uk.model,
|
|
188
212
|
)
|
|
189
213
|
simulation.run()
|
|
190
214
|
|
|
@@ -223,7 +247,7 @@ import datetime
|
|
|
223
247
|
|
|
224
248
|
parameter = Parameter(
|
|
225
249
|
name="gov.hmrc.income_tax.allowances.personal_allowance.amount",
|
|
226
|
-
tax_benefit_model_version=
|
|
250
|
+
tax_benefit_model_version=pe.uk.model,
|
|
227
251
|
data_type=float,
|
|
228
252
|
)
|
|
229
253
|
|
|
@@ -242,7 +266,7 @@ policy = Policy(
|
|
|
242
266
|
# Run reform simulation
|
|
243
267
|
reform_sim = Simulation(
|
|
244
268
|
dataset=dataset,
|
|
245
|
-
tax_benefit_model_version=
|
|
269
|
+
tax_benefit_model_version=pe.uk.model,
|
|
246
270
|
policy=policy,
|
|
247
271
|
)
|
|
248
272
|
reform_sim.run()
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Reference generator prototype
|
|
2
|
+
|
|
3
|
+
Auto-generates one Quarto page per variable in a country model, plus a program-coverage page, purely from metadata on the `Variable` classes and `programs.yaml`.
|
|
4
|
+
|
|
5
|
+
## Run
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Full US reference (takes a couple of minutes — 4,686 variables)
|
|
9
|
+
python docs/_generator/build_reference.py --country us --out docs/_generated/reference/us
|
|
10
|
+
|
|
11
|
+
# Preview a filtered subset
|
|
12
|
+
python docs/_generator/build_reference.py --country us --filter chip --out /tmp/ref-preview
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Then render:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
cd /tmp/ref-preview && quarto render
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## What's generated from code alone
|
|
22
|
+
|
|
23
|
+
Per variable:
|
|
24
|
+
|
|
25
|
+
- Title and identifier
|
|
26
|
+
- Metadata table: entity, value type, unit, period, `defined_for` gate
|
|
27
|
+
- Documentation (docstring)
|
|
28
|
+
- Components (`adds` / `subtracts` lists)
|
|
29
|
+
- Statutory references (from `reference = ...`)
|
|
30
|
+
- Source file path and line number
|
|
31
|
+
|
|
32
|
+
Per program: a row in the generated program-coverage page pulled from `programs.yaml` (id, name, category, agency, status, coverage).
|
|
33
|
+
|
|
34
|
+
Per directory (`gov/hhs/chip/`, `gov/usda/snap/`, etc.): a listing page using Quarto's built-in directory listing so the nav auto-organizes.
|
|
35
|
+
|
|
36
|
+
## What still requires hand-authored prose
|
|
37
|
+
|
|
38
|
+
- Methodology narrative (why the model is structured this way)
|
|
39
|
+
- Tutorials (how to use `policyengine.py`)
|
|
40
|
+
- Paper content (peer-reviewable argument)
|
|
41
|
+
- Per-country deep dives that read as essays rather than reference lookups
|
|
42
|
+
|
|
43
|
+
## Design
|
|
44
|
+
|
|
45
|
+
The generator reads directly from the imported country model — no web API calls, no intermediate JSON. This keeps the build offline-reproducible and version-pinned to whatever country model the `policyengine.py` package has installed. Re-running the generator on release produces a snapshot of the reference docs tied to the exact published model versions.
|
|
46
|
+
|
|
47
|
+
Extensions worth considering:
|
|
48
|
+
|
|
49
|
+
1. Walk `parameters/` YAML tree and emit a page per parameter with its time series, breakdowns, and references.
|
|
50
|
+
2. For each variable with a formula, surface the dependency graph (other variables / parameters it reads). `policyengine_core`'s `Variable.exhaustive_parameter_dependencies` gets partway there.
|
|
51
|
+
3. For each calibration target (in `policyengine-us-data/storage/calibration_targets/*.csv`), emit a page describing source, aggregation level, freshness.
|
|
52
|
+
4. Cross-link variables to the programs they contribute to via `programs.yaml`'s `variable:` field.
|