policyengine 4.2.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.
Files changed (198) hide show
  1. {policyengine-4.2.0 → policyengine-4.3.0}/CHANGELOG.md +14 -0
  2. {policyengine-4.2.0 → policyengine-4.3.0}/PKG-INFO +1 -1
  3. {policyengine-4.2.0 → policyengine-4.3.0}/docs/_quarto.yml +26 -15
  4. policyengine-4.3.0/docs/countries.md +83 -0
  5. {policyengine-4.2.0 → policyengine-4.3.0}/docs/dev.md +4 -1
  6. policyengine-4.3.0/docs/getting-started.md +113 -0
  7. policyengine-4.3.0/docs/households.md +129 -0
  8. policyengine-4.3.0/docs/impact-analysis.md +110 -0
  9. policyengine-4.3.0/docs/index.md +46 -0
  10. policyengine-4.3.0/docs/microsim.md +152 -0
  11. policyengine-4.3.0/docs/outputs.md +246 -0
  12. policyengine-4.3.0/docs/reforms.md +108 -0
  13. policyengine-4.3.0/docs/regions.md +147 -0
  14. {policyengine-4.2.0 → policyengine-4.3.0}/pyproject.toml +1 -1
  15. policyengine-4.3.0/scripts/refresh_release_bundle.py +79 -0
  16. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/provenance/__init__.py +3 -0
  17. policyengine-4.3.0/src/policyengine/provenance/bundle.py +319 -0
  18. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine.egg-info/PKG-INFO +1 -1
  19. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine.egg-info/SOURCES.txt +11 -6
  20. policyengine-4.3.0/tests/test_bundle_refresh.py +321 -0
  21. policyengine-4.2.0/docs/advanced-outputs.md +0 -276
  22. policyengine-4.2.0/docs/core-concepts.md +0 -731
  23. policyengine-4.2.0/docs/country-models-uk.md +0 -362
  24. policyengine-4.2.0/docs/country-models-us.md +0 -439
  25. policyengine-4.2.0/docs/economic-impact-analysis.md +0 -242
  26. policyengine-4.2.0/docs/index.md +0 -20
  27. policyengine-4.2.0/docs/regions-and-scoping.md +0 -228
  28. {policyengine-4.2.0 → policyengine-4.3.0}/.claude/policyengine-guide.md +0 -0
  29. {policyengine-4.2.0 → policyengine-4.3.0}/.claude/quick-reference.md +0 -0
  30. {policyengine-4.2.0 → policyengine-4.3.0}/.github/CONTRIBUTING.md +0 -0
  31. {policyengine-4.2.0 → policyengine-4.3.0}/.github/bump_version.py +0 -0
  32. {policyengine-4.2.0 → policyengine-4.3.0}/.github/changelog_template.md +0 -0
  33. {policyengine-4.2.0 → policyengine-4.3.0}/.github/check-changelog.sh +0 -0
  34. {policyengine-4.2.0 → policyengine-4.3.0}/.github/fetch_version.py +0 -0
  35. {policyengine-4.2.0 → policyengine-4.3.0}/.github/get-changelog-diff.sh +0 -0
  36. {policyengine-4.2.0 → policyengine-4.3.0}/.github/has-functional-changes.sh +0 -0
  37. {policyengine-4.2.0 → policyengine-4.3.0}/.github/is-version-number-acceptable.sh +0 -0
  38. {policyengine-4.2.0 → policyengine-4.3.0}/.github/publish-git-tag.sh +0 -0
  39. {policyengine-4.2.0 → policyengine-4.3.0}/.github/workflows/pr_code_changes.yaml +0 -0
  40. {policyengine-4.2.0 → policyengine-4.3.0}/.github/workflows/pr_docs_changes.yaml +0 -0
  41. {policyengine-4.2.0 → policyengine-4.3.0}/.github/workflows/push.yaml +0 -0
  42. {policyengine-4.2.0 → policyengine-4.3.0}/.gitignore +0 -0
  43. {policyengine-4.2.0 → policyengine-4.3.0}/.python-version +0 -0
  44. {policyengine-4.2.0 → policyengine-4.3.0}/LICENSE +0 -0
  45. {policyengine-4.2.0 → policyengine-4.3.0}/Makefile +0 -0
  46. {policyengine-4.2.0 → policyengine-4.3.0}/README.md +0 -0
  47. {policyengine-4.2.0 → policyengine-4.3.0}/changelog.d/.gitkeep +0 -0
  48. {policyengine-4.2.0 → policyengine-4.3.0}/docs/.gitignore +0 -0
  49. {policyengine-4.2.0 → policyengine-4.3.0}/docs/_generator/README.md +0 -0
  50. {policyengine-4.2.0 → policyengine-4.3.0}/docs/_generator/build_reference.py +0 -0
  51. {policyengine-4.2.0 → policyengine-4.3.0}/docs/examples.md +0 -0
  52. {policyengine-4.2.0 → policyengine-4.3.0}/docs/release-bundles.md +0 -0
  53. {policyengine-4.2.0 → policyengine-4.3.0}/docs/visualisation.md +0 -0
  54. {policyengine-4.2.0 → policyengine-4.3.0}/examples/employment_income_variation_uk.py +0 -0
  55. {policyengine-4.2.0 → policyengine-4.3.0}/examples/employment_income_variation_us.py +0 -0
  56. {policyengine-4.2.0 → policyengine-4.3.0}/examples/household_impact_example.py +0 -0
  57. {policyengine-4.2.0 → policyengine-4.3.0}/examples/income_bands_uk.py +0 -0
  58. {policyengine-4.2.0 → policyengine-4.3.0}/examples/income_distribution_us.py +0 -0
  59. {policyengine-4.2.0 → policyengine-4.3.0}/examples/paper_repro_uk.py +0 -0
  60. {policyengine-4.2.0 → policyengine-4.3.0}/examples/policy_change_uk.py +0 -0
  61. {policyengine-4.2.0 → policyengine-4.3.0}/examples/speedtest_us_simulation.py +0 -0
  62. {policyengine-4.2.0 → policyengine-4.3.0}/examples/us_budgetary_impact.py +0 -0
  63. {policyengine-4.2.0 → policyengine-4.3.0}/scripts/generate_trace_tros.py +0 -0
  64. {policyengine-4.2.0 → policyengine-4.3.0}/setup.cfg +0 -0
  65. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/__init__.py +0 -0
  66. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/cli.py +0 -0
  67. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/core/__init__.py +0 -0
  68. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/core/cache.py +0 -0
  69. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/core/dataset.py +0 -0
  70. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/core/dynamic.py +0 -0
  71. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/core/output.py +0 -0
  72. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/core/parameter.py +0 -0
  73. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/core/parameter_node.py +0 -0
  74. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/core/parameter_value.py +0 -0
  75. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/core/policy.py +0 -0
  76. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/core/region.py +0 -0
  77. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/core/scoping_strategy.py +0 -0
  78. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/core/simulation.py +0 -0
  79. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/core/tax_benefit_model.py +0 -0
  80. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/core/tax_benefit_model_version.py +0 -0
  81. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/core/variable.py +0 -0
  82. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/countries/__init__.py +0 -0
  83. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/countries/uk/__init__.py +0 -0
  84. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/countries/uk/regions.py +0 -0
  85. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/countries/us/__init__.py +0 -0
  86. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/countries/us/data/__init__.py +0 -0
  87. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/countries/us/data/districts.py +0 -0
  88. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/countries/us/data/places.py +0 -0
  89. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/countries/us/data/states.py +0 -0
  90. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/countries/us/regions.py +0 -0
  91. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/data/release_manifests/uk.json +0 -0
  92. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/data/release_manifests/us.json +0 -0
  93. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/data/schemas/trace_tro.schema.json +0 -0
  94. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/graph/__init__.py +0 -0
  95. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/graph/extractor.py +0 -0
  96. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/graph/graph.py +0 -0
  97. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/outputs/__init__.py +0 -0
  98. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/outputs/aggregate.py +0 -0
  99. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/outputs/change_aggregate.py +0 -0
  100. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/outputs/congressional_district_impact.py +0 -0
  101. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/outputs/constituency_impact.py +0 -0
  102. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/outputs/decile_impact.py +0 -0
  103. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/outputs/inequality.py +0 -0
  104. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/outputs/intra_decile_impact.py +0 -0
  105. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/outputs/local_authority_impact.py +0 -0
  106. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/outputs/poverty.py +0 -0
  107. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/outputs/program_statistics.py +0 -0
  108. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/provenance/manifest.py +0 -0
  109. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/provenance/trace.py +0 -0
  110. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/results/__init__.py +0 -0
  111. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/results/schema.py +0 -0
  112. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/results/trace_tro.py +0 -0
  113. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/results/tracking.py +0 -0
  114. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/tax_benefit_models/common/__init__.py +0 -0
  115. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/tax_benefit_models/common/extra_variables.py +0 -0
  116. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/tax_benefit_models/common/model_version.py +0 -0
  117. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/tax_benefit_models/common/reform.py +0 -0
  118. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/tax_benefit_models/common/result.py +0 -0
  119. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/tax_benefit_models/uk/__init__.py +0 -0
  120. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/tax_benefit_models/uk/analysis.py +0 -0
  121. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/tax_benefit_models/uk/datasets.py +0 -0
  122. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/tax_benefit_models/uk/household.py +0 -0
  123. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/tax_benefit_models/uk/model.py +0 -0
  124. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/tax_benefit_models/us/__init__.py +0 -0
  125. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/tax_benefit_models/us/analysis.py +0 -0
  126. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/tax_benefit_models/us/datasets.py +0 -0
  127. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/tax_benefit_models/us/household.py +0 -0
  128. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/tax_benefit_models/us/model.py +0 -0
  129. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/utils/__init__.py +0 -0
  130. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/utils/dates.py +0 -0
  131. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/utils/design.py +0 -0
  132. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/utils/entity_utils.py +0 -0
  133. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/utils/household_validation.py +0 -0
  134. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/utils/parameter_labels.py +0 -0
  135. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/utils/parametric_reforms.py +0 -0
  136. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine/utils/plotting.py +0 -0
  137. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine.egg-info/dependency_links.txt +0 -0
  138. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine.egg-info/entry_points.txt +0 -0
  139. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine.egg-info/requires.txt +0 -0
  140. {policyengine-4.2.0 → policyengine-4.3.0}/src/policyengine.egg-info/top_level.txt +0 -0
  141. {policyengine-4.2.0 → policyengine-4.3.0}/tests/__init__.py +0 -0
  142. {policyengine-4.2.0 → policyengine-4.3.0}/tests/conftest.py +0 -0
  143. {policyengine-4.2.0 → policyengine-4.3.0}/tests/fixtures/__init__.py +0 -0
  144. {policyengine-4.2.0 → policyengine-4.3.0}/tests/fixtures/filtering_fixtures.py +0 -0
  145. {policyengine-4.2.0 → policyengine-4.3.0}/tests/fixtures/household_calculator_snapshots/uk_couple_two_kids.json +0 -0
  146. {policyengine-4.2.0 → policyengine-4.3.0}/tests/fixtures/household_calculator_snapshots/uk_model_surface.json +0 -0
  147. {policyengine-4.2.0 → policyengine-4.3.0}/tests/fixtures/household_calculator_snapshots/uk_single_adult_employment_income.json +0 -0
  148. {policyengine-4.2.0 → policyengine-4.3.0}/tests/fixtures/household_calculator_snapshots/uk_single_adult_no_income.json +0 -0
  149. {policyengine-4.2.0 → policyengine-4.3.0}/tests/fixtures/household_calculator_snapshots/uk_single_parent_one_child.json +0 -0
  150. {policyengine-4.2.0 → policyengine-4.3.0}/tests/fixtures/household_calculator_snapshots/us_married_two_kids_high_income.json +0 -0
  151. {policyengine-4.2.0 → policyengine-4.3.0}/tests/fixtures/household_calculator_snapshots/us_model_surface.json +0 -0
  152. {policyengine-4.2.0 → policyengine-4.3.0}/tests/fixtures/household_calculator_snapshots/us_single_adult_employment_income.json +0 -0
  153. {policyengine-4.2.0 → policyengine-4.3.0}/tests/fixtures/household_calculator_snapshots/us_single_adult_no_income.json +0 -0
  154. {policyengine-4.2.0 → policyengine-4.3.0}/tests/fixtures/household_calculator_snapshots/us_single_parent_one_child.json +0 -0
  155. {policyengine-4.2.0 → policyengine-4.3.0}/tests/fixtures/parameter_labels_fixtures.py +0 -0
  156. {policyengine-4.2.0 → policyengine-4.3.0}/tests/fixtures/parametric_reforms_fixtures.py +0 -0
  157. {policyengine-4.2.0 → policyengine-4.3.0}/tests/fixtures/poverty_by_demographics_fixtures.py +0 -0
  158. {policyengine-4.2.0 → policyengine-4.3.0}/tests/fixtures/region_fixtures.py +0 -0
  159. {policyengine-4.2.0 → policyengine-4.3.0}/tests/fixtures/us_reform_fixtures.py +0 -0
  160. {policyengine-4.2.0 → policyengine-4.3.0}/tests/fixtures/variable_label_fixtures.py +0 -0
  161. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_aggregate.py +0 -0
  162. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_bump_version.py +0 -0
  163. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_cache.py +0 -0
  164. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_change_aggregate.py +0 -0
  165. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_congressional_district_impact.py +0 -0
  166. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_constituency_impact.py +0 -0
  167. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_dict_reforms_on_simulation.py +0 -0
  168. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_entity_mapping.py +0 -0
  169. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_entity_utils.py +0 -0
  170. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_extra_variables.py +0 -0
  171. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_filtering.py +0 -0
  172. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_graph/__init__.py +0 -0
  173. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_graph/conftest.py +0 -0
  174. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_graph/test_extractor.py +0 -0
  175. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_household_calculator_snapshot.py +0 -0
  176. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_household_impact.py +0 -0
  177. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_inequality.py +0 -0
  178. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_intra_decile_impact.py +0 -0
  179. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_local_authority_impact.py +0 -0
  180. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_manifest_version_mismatch.py +0 -0
  181. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_models.py +0 -0
  182. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_pandas3_compatibility.py +0 -0
  183. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_parameter_labels.py +0 -0
  184. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_parametric_reforms.py +0 -0
  185. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_poverty.py +0 -0
  186. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_poverty_by_demographics.py +0 -0
  187. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_poverty_run.py +0 -0
  188. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_region.py +0 -0
  189. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_release_manifests.py +0 -0
  190. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_results.py +0 -0
  191. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_scoping_strategy.py +0 -0
  192. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_trace_tro.py +0 -0
  193. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_uk_regions.py +0 -0
  194. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_us_microsim_structural_reforms.py +0 -0
  195. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_us_reform_application.py +0 -0
  196. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_us_regions.py +0 -0
  197. {policyengine-4.2.0 → policyengine-4.3.0}/tests/test_variable_labels.py +0 -0
  198. {policyengine-4.2.0 → policyengine-4.3.0}/uv.lock +0 -0
@@ -1,3 +1,17 @@
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
+
1
15
  ## [4.2.0] - 2026-04-20
2
16
 
3
17
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: policyengine
3
- Version: 4.2.0
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
@@ -14,27 +14,38 @@ website:
14
14
  left:
15
15
  - href: index.md
16
16
  text: Overview
17
- - core-concepts.md
18
- - economic-impact-analysis.md
19
- - country-models-us.md
20
- - country-models-uk.md
17
+ - getting-started.md
18
+ - households.md
19
+ - reforms.md
20
+ - microsim.md
21
+ - impact-analysis.md
21
22
  - examples.md
22
23
  - dev.md
23
24
  sidebar:
24
25
  style: "floating"
25
26
  collapse-level: 2
26
27
  contents:
27
- - index.md
28
- - core-concepts.md
29
- - economic-impact-analysis.md
30
- - advanced-outputs.md
31
- - regions-and-scoping.md
32
- - country-models-uk.md
33
- - country-models-us.md
34
- - examples.md
35
- - visualisation.md
36
- - release-bundles.md
37
- - dev.md
28
+ - section: "Get started"
29
+ contents:
30
+ - index.md
31
+ - getting-started.md
32
+ - section: "Calculate"
33
+ contents:
34
+ - households.md
35
+ - reforms.md
36
+ - microsim.md
37
+ - section: "Analyse"
38
+ contents:
39
+ - impact-analysis.md
40
+ - outputs.md
41
+ - regions.md
42
+ - visualisation.md
43
+ - section: "Reference"
44
+ contents:
45
+ - countries.md
46
+ - release-bundles.md
47
+ - examples.md
48
+ - dev.md
38
49
 
39
50
  format:
40
51
  html:
@@ -0,0 +1,83 @@
1
+ ---
2
+ title: "Country models"
3
+ ---
4
+
5
+ The `policyengine` package is country-agnostic; country-specific rules live in separate packages (`policyengine-us`, `policyengine-uk`). This page captures the differences that matter to users.
6
+
7
+ ## Entities
8
+
9
+ | US | UK |
10
+ |---|---|
11
+ | `person` | `person` |
12
+ | `family` | — |
13
+ | `marital_unit` | — |
14
+ | `tax_unit` | `benunit` |
15
+ | `spm_unit` | — |
16
+ | `household` | `household` |
17
+
18
+ The UK `benunit` is the closest analog to the US `tax_unit` for means-testing — a single adult or married couple plus dependent children.
19
+
20
+ ## Default income variable
21
+
22
+ Net-income calculations use country-specific defaults:
23
+
24
+ | | Variable |
25
+ |---|---|
26
+ | US | `spm_unit_net_income` |
27
+ | UK | `hbai_household_net_income` |
28
+
29
+ Override in any output with `income_variable=`.
30
+
31
+ ## Default dataset
32
+
33
+ | | Dataset |
34
+ |---|---|
35
+ | US | Enhanced CPS 2024 (`enhanced_cps_2024.h5`) |
36
+ | UK | Enhanced FRS 2023/24 (`enhanced_frs_2023_24.h5`) |
37
+
38
+ ## State / regional breakdown
39
+
40
+ US: `state_code` and `congressional_district` on every household.
41
+
42
+ UK: constituency code and local authority code on every household where available.
43
+
44
+ ## Poverty
45
+
46
+ US: SPM (Supplemental Poverty Measure) and deep SPM (below half the threshold). Tracked measures are listed in `US_POVERTY_VARIABLES`.
47
+
48
+ UK: AHC (After Housing Costs) and BHC (Before Housing Costs), both relative (60 % of median) and absolute.
49
+
50
+ ## Reform targeting
51
+
52
+ Parameter paths mirror the country's rule-making structure:
53
+
54
+ - US: `gov.irs.*`, `gov.states.<st>.*`, `gov.usda.*`, `gov.hhs.*`
55
+ - UK: `gov.hmrc.*`, `gov.dwp.*`, `gov.obr.*`
56
+
57
+ See [Reforms](reforms.md) for how to express changes in either tree.
58
+
59
+ ## Switching countries
60
+
61
+ Most analysis patterns are identical — swap `pe.us` for `pe.uk`:
62
+
63
+ ```python
64
+ # US
65
+ pe.us.calculate_household(
66
+ people=[{"age": 35, "employment_income": 60_000}],
67
+ tax_unit={"filing_status": "SINGLE"},
68
+ household={"state_code": "CA"},
69
+ year=2026,
70
+ )
71
+
72
+ # UK
73
+ pe.uk.calculate_household(
74
+ people=[{"age": 35, "employment_income": 50_000}],
75
+ year=2026,
76
+ )
77
+ ```
78
+
79
+ Microsim is similarly parallel: `pe.us.ensure_datasets` / `pe.uk.ensure_datasets`, `Simulation(tax_benefit_model_version=pe.us.model)` / `pe.uk.model`.
80
+
81
+ ## Pinned versions
82
+
83
+ Each `policyengine` release pins specific `policyengine-us` and `policyengine-uk` versions. Check them via `pe.us.model.manifest` and `pe.uk.model.manifest`. If the installed country package version diverges, the model warns — see [Release bundles](release-bundles.md).
@@ -70,7 +70,7 @@ This project uses [towncrier](https://towncrier.readthedocs.io/) for changelog m
70
70
 
71
71
  ```bash
72
72
  # Fragment types: breaking, added, changed, fixed, removed
73
- echo "Description of change" > changelog.d/my-change.added
73
+ echo "Description of change" > changelog.d/my-branch.added.md
74
74
  ```
75
75
 
76
76
  On merge, the versioning workflow bumps the version, builds the changelog, and creates a GitHub Release.
@@ -84,14 +84,17 @@ For the target release-bundle architecture, see [Release bundles](release-bundle
84
84
  ```
85
85
  src/policyengine/
86
86
  ├── __init__.py # Public surface: `pe.uk`, `pe.us`, `pe.Simulation`
87
+ ├── cli.py # `policyengine` entry point (e.g. TRACE TRO emission)
87
88
  ├── core/ # Domain models (Simulation, Dataset, Policy, etc.)
88
89
  ├── tax_benefit_models/
89
90
  │ ├── common/ # MicrosimulationModelVersion base, result types, reform compiler
90
91
  │ ├── uk/ # UK model, datasets, household calculator, reform analysis
91
92
  │ └── us/ # US model, datasets, household calculator, reform analysis
92
93
  ├── outputs/ # Output templates (Aggregate, Poverty, etc.)
94
+ ├── results/ # Typed results + schema validation
93
95
  ├── provenance/ # Release manifests + TRACE TRO export
94
96
  ├── countries/ # Geographic region registries (scoping, constituencies, districts)
97
+ ├── data/ # Bundled release manifests and schemas
95
98
  └── utils/ # Helpers (reforms, entity mapping, plotting)
96
99
  ```
97
100
 
@@ -0,0 +1,113 @@
1
+ ---
2
+ title: "Getting started"
3
+ ---
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pip install policyengine
9
+ ```
10
+
11
+ The base install contains the wrapper API. Install each country's rules alongside:
12
+
13
+ ```bash
14
+ pip install policyengine[us] # US
15
+ pip install policyengine[uk] # UK
16
+ pip install policyengine[us,uk] # both
17
+ ```
18
+
19
+ Country modules (`pe.us`, `pe.uk`) are only importable if the matching country package is installed.
20
+
21
+ ## Compute one household
22
+
23
+ ```python
24
+ import policyengine as pe
25
+
26
+ result = pe.us.calculate_household(
27
+ people=[{"age": 35, "employment_income": 60_000}],
28
+ tax_unit={"filing_status": "SINGLE"},
29
+ household={"state_code": "CA"},
30
+ year=2026,
31
+ )
32
+
33
+ result.tax_unit.income_tax
34
+ result.tax_unit.eitc
35
+ result.household.household_net_income
36
+ ```
37
+
38
+ Each `.*` lookup is a regular Python scalar. The result is a typed `HouseholdResult` with entity sections (`person[i]`, `tax_unit`, `spm_unit`, `household`) populated from every variable in the country model.
39
+
40
+ ## Apply a reform
41
+
42
+ Reforms are parameter-path → value dicts:
43
+
44
+ ```python
45
+ reformed = pe.us.calculate_household(
46
+ people=[{"age": 35, "employment_income": 60_000}],
47
+ tax_unit={"filing_status": "SINGLE"},
48
+ year=2026,
49
+ reform={"gov.irs.credits.ctc.amount.adult_dependent": 1_000},
50
+ )
51
+ ```
52
+
53
+ For values effective on specific dates, pass a nested dict:
54
+
55
+ ```python
56
+ reform = {
57
+ "gov.irs.credits.ctc.amount.adult_dependent": {
58
+ "2026-01-01": 1_000,
59
+ "2028-01-01": 2_000,
60
+ },
61
+ }
62
+ ```
63
+
64
+ Scale parameters are addressed by bracket index:
65
+
66
+ ```python
67
+ reform = {"gov.irs.credits.ctc.amount.base[0].amount": 3_000}
68
+ ```
69
+
70
+ See [Reforms](reforms.md) for structural reforms and the `Simulation.policy=` counterpart for population analysis.
71
+
72
+ ## Scale up
73
+
74
+ For population estimates — budget cost, distributional impact, poverty — move to a microsimulation over calibrated microdata. The reform dict carries over unchanged; only the constructor changes.
75
+
76
+ ```python
77
+ from policyengine.core import Simulation
78
+
79
+ datasets = pe.us.ensure_datasets(
80
+ datasets=["hf://policyengine/policyengine-us-data/enhanced_cps_2024.h5"],
81
+ years=[2026],
82
+ )
83
+ dataset = datasets["enhanced_cps_2024_2026"]
84
+
85
+ baseline = Simulation(
86
+ dataset=dataset,
87
+ tax_benefit_model_version=pe.us.model,
88
+ )
89
+ reformed = Simulation(
90
+ dataset=dataset,
91
+ tax_benefit_model_version=pe.us.model,
92
+ policy={"gov.irs.credits.ctc.amount.adult_dependent": 1_000},
93
+ )
94
+ ```
95
+
96
+ (Note: `reform=` for household calc, `policy=` for `Simulation` — same dict shape.)
97
+
98
+ ## What you get back
99
+
100
+ Every calculation returns a typed result with sections per entity:
101
+
102
+ - **US**: `person`, `family`, `marital_unit`, `tax_unit`, `spm_unit`, `household`
103
+ - **UK**: `person`, `benunit`, `household`
104
+
105
+ Person-level lookups index the list: `result.person[0].age`. Group-entity lookups don't: `result.tax_unit.income_tax`.
106
+
107
+ Unknown variable names raise with suggestions — no silent zero returns.
108
+
109
+ ## Next
110
+
111
+ - [Households](households.md) — full reference for `calculate_household`
112
+ - [Reforms](reforms.md) — parametric and structural reforms
113
+ - [Microsimulation](microsim.md) — population-level analysis
@@ -0,0 +1,129 @@
1
+ ---
2
+ title: "Households"
3
+ ---
4
+
5
+ `pe.us.calculate_household` and `pe.uk.calculate_household` compute every variable in the country model for a single household. Same keyword arguments, different entity structures.
6
+
7
+ ## US
8
+
9
+ ```python
10
+ result = pe.us.calculate_household(
11
+ people=[
12
+ {"age": 35, "employment_income": 40_000},
13
+ {"age": 33},
14
+ {"age": 8},
15
+ {"age": 5},
16
+ ],
17
+ tax_unit={"filing_status": "JOINT"},
18
+ household={"state_code": "TX"},
19
+ year=2026,
20
+ )
21
+ ```
22
+
23
+ ### Entities
24
+
25
+ | Argument | Purpose |
26
+ |---|---|
27
+ | `people` | List of person dicts. Keys are any person-level variable on the model. |
28
+ | `tax_unit` | Tax-unit inputs (e.g. `filing_status`). |
29
+ | `spm_unit` | SPM-unit inputs. |
30
+ | `household` | Household inputs. `state_code` is essentially always needed. |
31
+ | `family` | Family-level inputs. |
32
+ | `marital_unit` | Marital-unit inputs. |
33
+
34
+ All adults default to one shared tax unit and household. For separate tax units (e.g. two adult roommates), construct the `Simulation` directly and set the entity-membership arrays.
35
+
36
+ ## UK
37
+
38
+ ```python
39
+ result = pe.uk.calculate_household(
40
+ people=[
41
+ {"age": 35, "employment_income": 50_000},
42
+ {"age": 33, "employment_income": 30_000},
43
+ {"age": 4},
44
+ ],
45
+ benunit={},
46
+ household={},
47
+ year=2026,
48
+ )
49
+ ```
50
+
51
+ | Argument | Purpose |
52
+ |---|---|
53
+ | `people` | Person-level inputs. |
54
+ | `benunit` | Benefit unit (closest analog to US tax unit — single adult or couple plus their dependent children). |
55
+ | `household` | Household-level inputs. |
56
+
57
+ ## Reforms
58
+
59
+ Pass a `reform` dict of parameter-path to value:
60
+
61
+ ```python
62
+ pe.us.calculate_household(
63
+ ...,
64
+ reform={"gov.irs.credits.ctc.amount.adult_dependent": 1_000},
65
+ )
66
+ ```
67
+
68
+ Scale parameters use bracket indexing:
69
+
70
+ ```python
71
+ reform = {"gov.irs.credits.ctc.amount.base[0].amount": 3_000}
72
+ ```
73
+
74
+ Time-varying reforms use a nested dict of `YYYY-MM-DD → value`:
75
+
76
+ ```python
77
+ reform = {
78
+ "gov.irs.credits.ctc.amount.adult_dependent": {
79
+ "2026-01-01": 1_000,
80
+ "2028-01-01": 2_000,
81
+ },
82
+ }
83
+ ```
84
+
85
+ Structural reforms (new variables, formula swaps) require the `Simulation` path — see [Reforms](reforms.md).
86
+
87
+ ## Year
88
+
89
+ ```python
90
+ pe.us.calculate_household(..., year=2026)
91
+ ```
92
+
93
+ The year determines which parameter values apply. For multi-year analysis, call the function once per year rather than building a custom reform.
94
+
95
+ ## Extra variables
96
+
97
+ The result exposes every variable in the model by default. To surface variables that aren't in the default catalog explicitly:
98
+
99
+ ```python
100
+ result = pe.us.calculate_household(
101
+ ...,
102
+ extra_variables=["medicaid_income_level", "spm_unit_spm_threshold"],
103
+ )
104
+ ```
105
+
106
+ ## Accessing the result
107
+
108
+ ```python
109
+ result.person[0].income_tax # first person
110
+ result.person[2].age # third person
111
+ result.tax_unit.income_tax # single tax unit
112
+ result.household.household_net_income # single household
113
+ ```
114
+
115
+ The result is a Pydantic model — `.model_dump()` gives you a dict, individual sections are regular attribute lookups.
116
+
117
+ ## Errors
118
+
119
+ Unknown variables raise with the closest match:
120
+
121
+ ```
122
+ ValueError: Unknown variable 'income_ax'. Did you mean 'income_tax'?
123
+ ```
124
+
125
+ Unknown parameters in reforms raise similarly. Misplaced inputs (a person-level variable under `tax_unit=...`) raise with entity hints. The catalog is enumerated at construction time — typos fail fast.
126
+
127
+ ## When not to use this
128
+
129
+ Loops over many households are much slower than a single `Simulation` call. For population analysis, see [Microsimulation](microsim.md) — the reform dict carries over identically.
@@ -0,0 +1,110 @@
1
+ ---
2
+ title: "Impact analysis"
3
+ ---
4
+
5
+ `economic_impact_analysis` runs a baseline and a reform simulation through a bundled set of outputs — decile impacts, program statistics, poverty, and inequality — and returns a typed `PolicyReformAnalysis`.
6
+
7
+ ## Usage
8
+
9
+ ```python
10
+ import policyengine as pe
11
+ from policyengine.core import Simulation
12
+
13
+ datasets = pe.us.ensure_datasets(
14
+ datasets=["hf://policyengine/policyengine-us-data/enhanced_cps_2024.h5"],
15
+ years=[2026],
16
+ )
17
+ dataset = datasets["enhanced_cps_2024_2026"]
18
+
19
+ baseline = Simulation(dataset=dataset, tax_benefit_model_version=pe.us.model)
20
+ reformed = Simulation(
21
+ dataset=dataset,
22
+ tax_benefit_model_version=pe.us.model,
23
+ policy={"gov.irs.credits.ctc.amount.base[0].amount": 3_000},
24
+ )
25
+
26
+ analysis = pe.us.economic_impact_analysis(baseline, reformed)
27
+ ```
28
+
29
+ The UK equivalent is `pe.uk.economic_impact_analysis`. Both call `Simulation.ensure()` internally — run/cached simulations are reused, fresh ones are computed and cached.
30
+
31
+ ## What it returns
32
+
33
+ A `PolicyReformAnalysis` with:
34
+
35
+ | Attribute | Type | Content |
36
+ |---|---|---|
37
+ | `decile_impacts` | `OutputCollection[DecileImpact]` | Mean baseline / reform / change and winner-loser counts per decile |
38
+ | `program_statistics` | `OutputCollection[ProgramStatistics]` | Totals, counts, winners/losers per program |
39
+ | `baseline_poverty` | `OutputCollection[Poverty]` | Baseline rates by measure and demographic group |
40
+ | `reform_poverty` | `OutputCollection[Poverty]` | Reform rates, same schema as baseline |
41
+ | `baseline_inequality` | `Inequality` | Gini plus top / bottom income shares (baseline) |
42
+ | `reform_inequality` | `Inequality` | Same, under the reform |
43
+
44
+ `OutputCollection` exposes `.outputs` (typed list) and `.dataframe` (flat DataFrame).
45
+
46
+ ```python
47
+ for prog in analysis.program_statistics.outputs:
48
+ print(prog.program_name, prog.change)
49
+
50
+ for d in analysis.decile_impacts.outputs:
51
+ print(d.decile, d.absolute_change, d.relative_change)
52
+
53
+ analysis.reform_inequality.gini - analysis.baseline_inequality.gini
54
+ ```
55
+
56
+ ## When to call it
57
+
58
+ - Producing a reform brief covering multiple metrics
59
+ - Standardising reporting across reforms where each run should cover the same bundle
60
+
61
+ ## When not to
62
+
63
+ - If you only need one number (a budget cost, a single poverty rate), `ChangeAggregate` / `Aggregate` / `Poverty` avoids running ~30+ aggregations.
64
+ - If you're sweeping a parameter, cache the baseline and build a new reform simulation per iteration:
65
+
66
+ ```python
67
+ baseline = Simulation(dataset=dataset, tax_benefit_model_version=pe.us.model)
68
+ for amount in [0, 1_000, 2_000, 3_000]:
69
+ reformed = Simulation(
70
+ dataset=dataset,
71
+ tax_benefit_model_version=pe.us.model,
72
+ policy={"gov.irs.credits.ctc.amount.base[0].amount": amount},
73
+ )
74
+ analysis = pe.us.economic_impact_analysis(baseline, reformed)
75
+ ```
76
+
77
+ ## Composing manually
78
+
79
+ `economic_impact_analysis` is a thin wrapper over the convenience functions in `policyengine.outputs`. Replicate it if you need a different bundle or can skip sections:
80
+
81
+ ```python
82
+ from policyengine.outputs import (
83
+ ChangeAggregate, ChangeAggregateType,
84
+ calculate_decile_impacts,
85
+ calculate_us_poverty_rates,
86
+ calculate_us_inequality,
87
+ )
88
+
89
+ budget = ChangeAggregate(
90
+ baseline_simulation=baseline,
91
+ reform_simulation=reformed,
92
+ variable="household_net_income",
93
+ aggregate_type=ChangeAggregateType.SUM,
94
+ )
95
+ budget.run()
96
+
97
+ deciles = calculate_decile_impacts(baseline_simulation=baseline, reform_simulation=reformed)
98
+
99
+ baseline_poverty = calculate_us_poverty_rates(simulation=baseline)
100
+ reform_poverty = calculate_us_poverty_rates(simulation=reformed)
101
+
102
+ baseline_ineq = calculate_us_inequality(simulation=baseline)
103
+ reform_ineq = calculate_us_inequality(simulation=reformed)
104
+ ```
105
+
106
+ ## Next
107
+
108
+ - [Outputs](outputs.md) — individual output classes and their options
109
+ - [Regions](regions.md) — state, constituency, and district breakdowns
110
+ - [Examples](examples.md) — runnable scripts using this helper
@@ -0,0 +1,46 @@
1
+ ---
2
+ title: "policyengine"
3
+ ---
4
+
5
+ `policyengine` is the Python wrapper for PolicyEngine's tax-benefit microsimulation models. One package for both single-household calculations and population-scale microsimulation, US and UK.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pip install policyengine[us] # US rules
11
+ pip install policyengine[uk] # UK rules
12
+ pip install policyengine[us,uk] # both
13
+ ```
14
+
15
+ ## Minimal example
16
+
17
+ ```python
18
+ import policyengine as pe
19
+
20
+ result = pe.us.calculate_household(
21
+ people=[{"age": 35, "employment_income": 60_000}],
22
+ tax_unit={"filing_status": "SINGLE"},
23
+ household={"state_code": "CA"},
24
+ year=2026,
25
+ )
26
+
27
+ result.tax_unit.income_tax
28
+ result.household.household_net_income
29
+ ```
30
+
31
+ ## Where to go next
32
+
33
+ | If you want to | Go to |
34
+ |---|---|
35
+ | Install and run your first calculation | [Getting started](getting-started.md) |
36
+ | Compute taxes and benefits for one family | [Households](households.md) |
37
+ | Express a policy change | [Reforms](reforms.md) |
38
+ | Produce population estimates (budget cost, poverty) | [Microsimulation](microsim.md) |
39
+ | See the full catalog of typed outputs | [Outputs](outputs.md) |
40
+ | Run the canonical baseline-vs-reform bundle | [Impact analysis](impact-analysis.md) |
41
+ | Break results down by state, constituency, district | [Regions](regions.md) |
42
+ | Understand US vs UK differences | [Countries](countries.md) |
43
+ | Build publication-ready charts | [Visualisation](visualisation.md) |
44
+ | Pin a reproducible model-plus-data version | [Release bundles](release-bundles.md) |
45
+ | See a full worked script | [Examples](examples.md) |
46
+ | Develop against the source | [Development](dev.md) |