policyengine-core 3.34.7__tar.gz → 3.34.8__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 (508) hide show
  1. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/CHANGELOG.md +7 -0
  2. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/PKG-INFO +1 -1
  3. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/simulations/simulation.py +14 -1
  4. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/pyproject.toml +1 -1
  5. policyengine_core-3.34.8/tests/core/test_apply_reform_holders.py +295 -0
  6. policyengine_core-3.34.8/tests/core/test_apply_reform_holders_property.py +226 -0
  7. policyengine_core-3.34.8/tests/fixtures/reform_holders.py +115 -0
  8. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/.github/ISSUE_TEMPLATE.md +0 -0
  9. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  10. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/.github/actionlint.yaml +0 -0
  11. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/.github/bump_version.py +0 -0
  12. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/.github/changelog_template.md +0 -0
  13. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/.github/get-changelog-diff.sh +0 -0
  14. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/.github/has-functional-changes.sh +0 -0
  15. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/.github/is-version-number-acceptable.sh +0 -0
  16. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/.github/publish-git-tag.sh +0 -0
  17. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/.github/requirements/legacy-country-smoke.txt +0 -0
  18. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/.github/workflows/pr.yaml +0 -0
  19. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/.github/workflows/push.yaml +0 -0
  20. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/.gitignore +0 -0
  21. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/.python-version +0 -0
  22. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/AGENTS.md +0 -0
  23. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/CLAUDE.md +0 -0
  24. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/CONTRIBUTING.md +0 -0
  25. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/LICENSE +0 -0
  26. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/MANIFEST.in +0 -0
  27. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/Makefile +0 -0
  28. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/README.md +0 -0
  29. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/_build/logs/myst.build.json +0 -0
  30. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/changelog.d/.gitkeep +0 -0
  31. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/_config.yml +0 -0
  32. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/_static/style.css +0 -0
  33. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/_toc.yml +0 -0
  34. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/add_plotly_to_book.py +0 -0
  35. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/contributing/intro.md +0 -0
  36. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/engineering/skills/README.md +0 -0
  37. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/engineering/skills/documentation_review.md +0 -0
  38. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/engineering/skills/github-prs.md +0 -0
  39. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/engineering/skills/testing.md +0 -0
  40. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/intro.md +0 -0
  41. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/logo.png +0 -0
  42. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/python_api/commons.md +0 -0
  43. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/python_api/country_template.md +0 -0
  44. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/python_api/data.md +0 -0
  45. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/python_api/data_storage.md +0 -0
  46. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/python_api/entities.md +0 -0
  47. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/python_api/enums.md +0 -0
  48. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/python_api/errors.md +0 -0
  49. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/python_api/experimental.md +0 -0
  50. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/python_api/extension_template.md +0 -0
  51. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/python_api/holders.md +0 -0
  52. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/python_api/parameters.md +0 -0
  53. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/python_api/periods.md +0 -0
  54. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/python_api/populations.md +0 -0
  55. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/python_api/projectors.md +0 -0
  56. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/python_api/reforms.md +0 -0
  57. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/python_api/scripts.md +0 -0
  58. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/python_api/simulations.md +0 -0
  59. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/python_api/taxbenefitsystems.md +0 -0
  60. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/python_api/taxscales.md +0 -0
  61. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/python_api/tools.md +0 -0
  62. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/python_api/tracers.md +0 -0
  63. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/python_api/types.md +0 -0
  64. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/python_api/variables.md +0 -0
  65. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/python_api/warnings.md +0 -0
  66. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/usage/branches.md +0 -0
  67. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/usage/country.ipynb +0 -0
  68. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/usage/datasets.ipynb +0 -0
  69. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/usage/parameters.md +0 -0
  70. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/usage/reforms.ipynb +0 -0
  71. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/docs/usage/simulation.ipynb +0 -0
  72. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/mypy.ini +0 -0
  73. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/__init__.py +0 -0
  74. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/build_metadata.py +0 -0
  75. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/charts/__init__.py +0 -0
  76. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/charts/bar.py +0 -0
  77. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/charts/formatting.py +0 -0
  78. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/commons/__init__.py +0 -0
  79. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/commons/formulas.py +0 -0
  80. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/commons/misc.py +0 -0
  81. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/commons/rates.py +0 -0
  82. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/__init__.py +0 -0
  83. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/constants.py +0 -0
  84. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/data/__init__.py +0 -0
  85. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/data/datasets/__init__.py +0 -0
  86. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/data/datasets/country_template_dataset.py +0 -0
  87. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/entities.py +0 -0
  88. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/modelled_policies.yaml +0 -0
  89. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/parameters/benefits/basic_income.yaml +0 -0
  90. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/parameters/benefits/housing_allowance.yaml +0 -0
  91. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/parameters/benefits/index.yaml +0 -0
  92. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/parameters/benefits/parenting_allowance/amount.yaml +0 -0
  93. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/parameters/benefits/parenting_allowance/income_threshold.yaml +0 -0
  94. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/parameters/general/age_of_majority.yaml +0 -0
  95. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/parameters/general/age_of_retirement.yaml +0 -0
  96. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/parameters/taxes/housing_tax.yaml +0 -0
  97. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/parameters/taxes/income_tax_rate.yaml +0 -0
  98. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/parameters/taxes/social_security_contribution.yaml +0 -0
  99. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/reforms/__init__.py +0 -0
  100. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/reforms/add_dynamic_variable.py +0 -0
  101. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/reforms/add_new_tax.py +0 -0
  102. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/reforms/flat_social_security_contribution.py +0 -0
  103. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/reforms/modify_social_security_taxation.py +0 -0
  104. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/reforms/removal_basic_income.py +0 -0
  105. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/situation_examples/__init__.py +0 -0
  106. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/situation_examples/couple.json +0 -0
  107. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/situation_examples/housing.json +0 -0
  108. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/situation_examples/single.json +0 -0
  109. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/tests/age.yaml +0 -0
  110. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/tests/basic_income.yaml +0 -0
  111. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/tests/disposable_income.yaml +0 -0
  112. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/tests/housing_allowance.yaml +0 -0
  113. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/tests/housing_tax.yaml +0 -0
  114. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/tests/income_tax.yaml +0 -0
  115. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/tests/reforms/add_dynamic_variable.yaml +0 -0
  116. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/tests/reforms/add_new_tax.yaml +0 -0
  117. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/tests/reforms/modify_social_security_taxation.yaml +0 -0
  118. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/tests/situations/income_tax.yaml +0 -0
  119. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/tests/situations/parenting_allowance.yaml +0 -0
  120. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/tests/social_security_contribution.yaml +0 -0
  121. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/tests/test_microsimulation.py +0 -0
  122. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/variables/__init__.py +0 -0
  123. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/variables/benefits.py +0 -0
  124. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/variables/demographics.py +0 -0
  125. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/variables/housing.py +0 -0
  126. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/variables/ids.py +0 -0
  127. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/variables/income.py +0 -0
  128. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/variables/stats.py +0 -0
  129. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/country_template/variables/taxes.py +0 -0
  130. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/data/__init__.py +0 -0
  131. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/data/dataset.py +0 -0
  132. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/data_storage/__init__.py +0 -0
  133. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/data_storage/in_memory_storage.py +0 -0
  134. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/data_storage/on_disk_storage.py +0 -0
  135. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/data_storage/storage_directory.py +0 -0
  136. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/data_storage/store_history.py +0 -0
  137. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/data_structures/__init__.py +0 -0
  138. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/data_structures/parameter_metadata.py +0 -0
  139. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/data_structures/parameter_node_metadata.py +0 -0
  140. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/data_structures/reference.py +0 -0
  141. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/data_structures/unit.py +0 -0
  142. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/entities/__init__.py +0 -0
  143. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/entities/entity.py +0 -0
  144. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/entities/group_entity.py +0 -0
  145. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/entities/helpers.py +0 -0
  146. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/entities/role.py +0 -0
  147. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/enums/__init__.py +0 -0
  148. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/enums/config.py +0 -0
  149. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/enums/enum.py +0 -0
  150. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/enums/enum_array.py +0 -0
  151. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/errors/__init__.py +0 -0
  152. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/errors/cycle_error.py +0 -0
  153. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/errors/empty_argument_error.py +0 -0
  154. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/errors/nan_creation_error.py +0 -0
  155. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/errors/non_deterministic_formula_error.py +0 -0
  156. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/errors/parameter_not_found_error.py +0 -0
  157. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/errors/parameter_parsing_error.py +0 -0
  158. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/errors/period_mismatch_error.py +0 -0
  159. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/errors/situation_parsing_error.py +0 -0
  160. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/errors/spiral_error.py +0 -0
  161. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/errors/variable_name_conflict_error.py +0 -0
  162. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/errors/variable_not_found_error.py +0 -0
  163. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/experimental/__init__.py +0 -0
  164. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/experimental/memory_config.py +0 -0
  165. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/extension_template/__init__.py +0 -0
  166. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/extension_template/local_benefit.py +0 -0
  167. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/extension_template/parameters/local_town/child_allowance/amount.yaml +0 -0
  168. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/extension_template/parameters/local_town/child_allowance/index.yaml +0 -0
  169. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/extension_template/parameters/local_town/index.yaml +0 -0
  170. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/extension_template/tests/local_benefit.yaml +0 -0
  171. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/holders/__init__.py +0 -0
  172. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/holders/helpers.py +0 -0
  173. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/holders/holder.py +0 -0
  174. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/model_api.py +0 -0
  175. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/parameters/__init__.py +0 -0
  176. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/parameters/at_instant_like.py +0 -0
  177. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/parameters/config.py +0 -0
  178. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/parameters/helpers.py +0 -0
  179. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/parameters/operations/__init__.py +0 -0
  180. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/parameters/operations/get_parameter.py +0 -0
  181. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/parameters/operations/homogenize_parameters.py +0 -0
  182. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/parameters/operations/interpolate_parameters.py +0 -0
  183. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/parameters/operations/propagate_parameter_metadata.py +0 -0
  184. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/parameters/operations/uprate_parameters.py +0 -0
  185. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/parameters/parameter.py +0 -0
  186. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/parameters/parameter_at_instant.py +0 -0
  187. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/parameters/parameter_node.py +0 -0
  188. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/parameters/parameter_node_at_instant.py +0 -0
  189. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/parameters/parameter_scale.py +0 -0
  190. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/parameters/parameter_scale_bracket.py +0 -0
  191. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/parameters/vectorial_parameter_node_at_instant.py +0 -0
  192. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/periods/__init__.py +0 -0
  193. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/periods/config.py +0 -0
  194. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/periods/helpers.py +0 -0
  195. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/periods/instant_.py +0 -0
  196. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/periods/period_.py +0 -0
  197. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/populations/__init__.py +0 -0
  198. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/populations/config.py +0 -0
  199. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/populations/group_population.py +0 -0
  200. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/populations/population.py +0 -0
  201. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/projectors/__init__.py +0 -0
  202. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/projectors/entity_to_person_projector.py +0 -0
  203. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/projectors/first_person_to_entity_projector.py +0 -0
  204. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/projectors/helpers.py +0 -0
  205. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/projectors/projector.py +0 -0
  206. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/projectors/unique_role_to_entity_projector.py +0 -0
  207. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/reforms/__init__.py +0 -0
  208. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/reforms/reform.py +0 -0
  209. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/scripts/__init__.py +0 -0
  210. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/scripts/assets/__init__.py +0 -0
  211. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/scripts/assets/index.html +0 -0
  212. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/scripts/policyengine_command.py +0 -0
  213. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/scripts/run_data.py +0 -0
  214. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/scripts/run_test.py +0 -0
  215. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/scripts/simulation_generator.py +0 -0
  216. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/simulations/__init__.py +0 -0
  217. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/simulations/helpers.py +0 -0
  218. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/simulations/individual_sim.py +0 -0
  219. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/simulations/microsimulation.py +0 -0
  220. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/simulations/simulation_builder.py +0 -0
  221. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/simulations/simulation_macro_cache.py +0 -0
  222. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/taxbenefitsystems/__init__.py +0 -0
  223. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/taxbenefitsystems/tax_benefit_system.py +0 -0
  224. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/taxscales/__init__.py +0 -0
  225. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/taxscales/abstract_rate_tax_scale.py +0 -0
  226. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/taxscales/abstract_tax_scale.py +0 -0
  227. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/taxscales/amount_tax_scale_like.py +0 -0
  228. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/taxscales/helpers.py +0 -0
  229. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/taxscales/linear_average_rate_tax_scale.py +0 -0
  230. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/taxscales/marginal_amount_tax_scale.py +0 -0
  231. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/taxscales/marginal_rate_tax_scale.py +0 -0
  232. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/taxscales/rate_tax_scale_like.py +0 -0
  233. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/taxscales/single_amount_tax_scale.py +0 -0
  234. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/taxscales/tax_scale_like.py +0 -0
  235. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/tools/__init__.py +0 -0
  236. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/tools/google_cloud.py +0 -0
  237. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/tools/hugging_face.py +0 -0
  238. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/tools/simulation_dumper.py +0 -0
  239. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/tools/test_from_situation.py +0 -0
  240. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/tools/test_runner.py +0 -0
  241. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/tools/win_file_manager.py +0 -0
  242. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/tracers/__init__.py +0 -0
  243. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/tracers/computation_log.py +0 -0
  244. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/tracers/flat_trace.py +0 -0
  245. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/tracers/full_tracer.py +0 -0
  246. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/tracers/performance_log.py +0 -0
  247. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/tracers/simple_tracer.py +0 -0
  248. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/tracers/trace_node.py +0 -0
  249. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/tracers/tracing_parameter_node_at_instant.py +0 -0
  250. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/tracers/variable_graph.py +0 -0
  251. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/types/__init__.py +0 -0
  252. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/types/data_types/__init__.py +0 -0
  253. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/types/data_types/arrays.py +0 -0
  254. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/variables/__init__.py +0 -0
  255. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/variables/config.py +0 -0
  256. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/variables/defined_for.py +0 -0
  257. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/variables/formula_randomness.py +0 -0
  258. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/variables/helpers.py +0 -0
  259. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/variables/typing.py +0 -0
  260. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/variables/variable.py +0 -0
  261. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/warnings/__init__.py +0 -0
  262. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/warnings/libyaml_warning.py +0 -0
  263. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/warnings/memory_config_warning.py +0 -0
  264. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/warnings/parameter_key_warning.py +0 -0
  265. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/policyengine_core/warnings/tempfile_warning.py +0 -0
  266. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/pytest.ini +0 -0
  267. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/__init__.py +0 -0
  268. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/conftest.py +0 -0
  269. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/__init__.py +0 -0
  270. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/commons/__init__.py +0 -0
  271. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/commons/test_between_function.py +0 -0
  272. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/commons/test_formulas.py +0 -0
  273. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/commons/test_is_in_function.py +0 -0
  274. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/commons/test_random_seed.py +0 -0
  275. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/commons/test_rates.py +0 -0
  276. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/data/test_dataset.py +0 -0
  277. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/enums/test_enum.py +0 -0
  278. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/model_api/test_index_.py +0 -0
  279. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameter_validation/__init__.py +0 -0
  280. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameter_validation/array_type.yaml +0 -0
  281. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameter_validation/duplicate_key.yaml +0 -0
  282. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameter_validation/filesystem_hierarchy/empty_index_file/index.yaml +0 -0
  283. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameter_validation/filesystem_hierarchy/node1/param.yaml +0 -0
  284. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameter_validation/indentation.yaml +0 -0
  285. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameter_validation/missing_value.yaml +0 -0
  286. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameter_validation/parameter_for_unit_propagation.yaml +0 -0
  287. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameter_validation/test_parameter_clone.py +0 -0
  288. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameter_validation/test_parameter_validation.py +0 -0
  289. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameter_validation/test_propagate_units.py +0 -0
  290. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameter_validation/test_unknown_keys.py +0 -0
  291. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameter_validation/unexpected_key_in_parameter.yaml +0 -0
  292. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameter_validation/unexpected_key_in_scale.yaml +0 -0
  293. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameter_validation/unexpected_key_in_value_at_instant.yaml +0 -0
  294. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameter_validation/unexpected_key_in_value_history.yaml +0 -0
  295. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameter_validation/unknown_key_beside_values.yaml +0 -0
  296. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameter_validation/uprating_under_metadata.yaml +0 -0
  297. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameter_validation/wrong_date.yaml +0 -0
  298. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameter_validation/wrong_scale.yaml +0 -0
  299. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameter_validation/wrong_type_in_bracket.yaml +0 -0
  300. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameter_validation/wrong_type_in_brackets.yaml +0 -0
  301. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameter_validation/wrong_type_in_parameter.yaml +0 -0
  302. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameter_validation/wrong_type_in_scale.yaml +0 -0
  303. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameter_validation/wrong_type_in_value_history.yaml +0 -0
  304. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameter_validation/wrong_value.yaml +0 -0
  305. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameter_validation/yaml_hierarchy/node1.yaml +0 -0
  306. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameters/operations/test_interpolation.py +0 -0
  307. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameters/operations/test_nesting.py +0 -0
  308. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameters/operations/test_propagation.py +0 -0
  309. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameters/operations/test_scale_threshold_uprating.py +0 -0
  310. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameters/operations/test_uprating.py +0 -0
  311. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameters/test_numpy2_structured_arrays.py +0 -0
  312. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameters/test_parameter_metadata_clone.py +0 -0
  313. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameters/test_parameter_metadata_clone_property.py +0 -0
  314. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameters/test_vectorial_parameter_node_copy.py +0 -0
  315. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameters/test_vectorial_parameter_node_copy_property.py +0 -0
  316. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameters_fancy_indexing/__init__.py +0 -0
  317. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameters_fancy_indexing/bareme.yaml +0 -0
  318. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameters_fancy_indexing/local_tax.yaml +0 -0
  319. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameters_fancy_indexing/rate.yaml +0 -0
  320. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameters_fancy_indexing/test_fancy_indexing.py +0 -0
  321. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/parameters_fancy_indexing/test_fancy_indexing_property.py +0 -0
  322. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/simulations/test_formula_randomness_concurrency.py +0 -0
  323. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/tax_scales/__init__.py +0 -0
  324. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/tax_scales/test_abstract_rate_tax_scale.py +0 -0
  325. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/tax_scales/test_abstract_tax_scale.py +0 -0
  326. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/tax_scales/test_linear_average_rate_tax_scale.py +0 -0
  327. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/tax_scales/test_linear_average_rate_tax_scale_property.py +0 -0
  328. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/tax_scales/test_marginal_amount_tax_scale.py +0 -0
  329. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/tax_scales/test_marginal_rate_tax_scale.py +0 -0
  330. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/tax_scales/test_rate_scale_conversion_property.py +0 -0
  331. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/tax_scales/test_rate_tax_scale_like.py +0 -0
  332. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/tax_scales/test_single_amount_tax_scale.py +0 -0
  333. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/tax_scales/test_tax_scales_commons.py +0 -0
  334. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_apply_reform_invalidates_cache.py +0 -0
  335. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_apply_reform_preserves_user_inputs.py +0 -0
  336. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_assert_near_precision.py +0 -0
  337. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_axes.py +0 -0
  338. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_bincount_minlength.py +0 -0
  339. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_branch_helper_invalidation.py +0 -0
  340. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_branch_input_fixed_point.py +0 -0
  341. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_branch_input_fixed_point_property.py +0 -0
  342. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_branch_input_invalidation.py +0 -0
  343. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_branch_input_invalidation_property.py +0 -0
  344. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_branch_scoped_delete_arrays.py +0 -0
  345. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_branch_shared_arrays.py +0 -0
  346. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_branch_shared_arrays_differential.py +0 -0
  347. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_build_metadata.py +0 -0
  348. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_calculate_output.py +0 -0
  349. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_carry_over_order.py +0 -0
  350. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_carry_over_order_property.py +0 -0
  351. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_clone_invalidated_caches.py +0 -0
  352. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_clone_rebinding.py +0 -0
  353. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_clone_rebinding_property.py +0 -0
  354. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_clone_reform_baseline.py +0 -0
  355. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_clone_reform_baseline_property.py +0 -0
  356. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_countries.py +0 -0
  357. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_cycles.py +0 -0
  358. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_data_storage_dir.py +0 -0
  359. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_data_storage_dir_property.py +0 -0
  360. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_dataset_default_role.py +0 -0
  361. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_dataset_default_role_property.py +0 -0
  362. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_dataset_getattr.py +0 -0
  363. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_dataset_unknown_column_warning.py +0 -0
  364. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_default_simulation_count_property.py +0 -0
  365. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_disk_period_filenames.py +0 -0
  366. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_disk_storage_differential.py +0 -0
  367. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_disk_storage_ownership.py +0 -0
  368. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_docs_deployment.py +0 -0
  369. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_dump_restore.py +0 -0
  370. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_dump_restore_property.py +0 -0
  371. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_entities.py +0 -0
  372. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_eternity_subperiods.py +0 -0
  373. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_extensions.py +0 -0
  374. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_fast_cache.py +0 -0
  375. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_fast_cache_contained_periods.py +0 -0
  376. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_fast_cache_contained_periods_property.py +0 -0
  377. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_fast_cache_guards.py +0 -0
  378. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_formulas.py +0 -0
  379. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_group_population_empty.py +0 -0
  380. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_group_population_reductions_property.py +0 -0
  381. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_holder_branch_fallback.py +0 -0
  382. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_holder_write_fast_cache.py +0 -0
  383. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_holder_write_fast_cache_property.py +0 -0
  384. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_holders.py +0 -0
  385. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_input_tier_invalidation.py +0 -0
  386. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_join_with_persons_identity.py +0 -0
  387. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_join_with_persons_identity_property.py +0 -0
  388. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_macro_cache_not_singleton.py +0 -0
  389. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_medium_fixes.py +0 -0
  390. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_microsimulation_person_accessor.py +0 -0
  391. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_microsimulation_weights.py +0 -0
  392. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_on_disk_storage_clones.py +0 -0
  393. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_opt_out_cache.py +0 -0
  394. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_option_result_cache.py +0 -0
  395. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_option_result_cache_property.py +0 -0
  396. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_option_result_input_provenance.py +0 -0
  397. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_own_period_input_overlapping_cache.py +0 -0
  398. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_pandas3_compatibility.py +0 -0
  399. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_parameter_security.py +0 -0
  400. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_parameters.py +0 -0
  401. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_periods.py +0 -0
  402. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_projectors.py +0 -0
  403. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_reform_baseline_system.py +0 -0
  404. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_reform_parameter_isolation.py +0 -0
  405. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_reform_period_keys.py +0 -0
  406. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_reforms.py +0 -0
  407. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_registered_input_deletion.py +0 -0
  408. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_release_tagging.py +0 -0
  409. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_rerun_fixture_isolation.py +0 -0
  410. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_restore_input_provenance.py +0 -0
  411. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_restore_input_registry.py +0 -0
  412. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_restore_input_registry_property.py +0 -0
  413. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_set_input_helper_order.py +0 -0
  414. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_set_input_helper_order_property.py +0 -0
  415. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_simulation_builder.py +0 -0
  416. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_simulation_copy_pickle.py +0 -0
  417. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_simulation_copy_pickle_property.py +0 -0
  418. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_simulations.py +0 -0
  419. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_stable_hash_seed.py +0 -0
  420. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_stale_frame_cache.py +0 -0
  421. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_storage_anchored_periods.py +0 -0
  422. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_storage_delete_branch.py +0 -0
  423. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_storage_input_index.py +0 -0
  424. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_storage_shared_index.py +0 -0
  425. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_storage_shared_index_differential.py +0 -0
  426. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_subsample_baseline_branch.py +0 -0
  427. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_subsample_computed_values.py +0 -0
  428. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_subsample_computed_values_property.py +0 -0
  429. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_subsample_deleted_inputs.py +0 -0
  430. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_subsample_entity_weight_totals.py +0 -0
  431. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_subsample_inputs_only.py +0 -0
  432. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_subsample_inputs_only_property.py +0 -0
  433. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_subsample_invalidates_cache.py +0 -0
  434. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_subsample_membership_ids.py +0 -0
  435. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_subsample_restore_inputs.py +0 -0
  436. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_subsample_sampling_period.py +0 -0
  437. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_subsample_sampling_period_property.py +0 -0
  438. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_subsample_structural_ids.py +0 -0
  439. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_subsample_weight_fallback.py +0 -0
  440. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_tax_benefit_system_cache_identity.py +0 -0
  441. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_tracers.py +0 -0
  442. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_tracing_parameter_isolation.py +0 -0
  443. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_tracing_parameter_isolation_properties.py +0 -0
  444. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_uprating_order.py +0 -0
  445. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_uprating_order_property.py +0 -0
  446. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_user_input_keys.py +0 -0
  447. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_user_input_keys_property.py +0 -0
  448. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_user_input_keys_soundness.py +0 -0
  449. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_variable_code_sharing.py +0 -0
  450. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_variable_code_sharing_property.py +0 -0
  451. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/test_yaml.py +0 -0
  452. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/tools/__init__.py +0 -0
  453. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/tools/test_assert_near.py +0 -0
  454. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/tools/test_google_cloud.py +0 -0
  455. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/tools/test_hugging_face.py +0 -0
  456. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/tools/test_runner/test_gc_pause.py +0 -0
  457. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/tools/test_runner/test_yaml_runner.py +0 -0
  458. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/variables/test_adds.py +0 -0
  459. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/variables/test_annualize.py +0 -0
  460. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/variables/test_bounds.py +0 -0
  461. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/variables/test_defined_for.py +0 -0
  462. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/variables/test_formula_randomness.py +0 -0
  463. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/variables/test_non_numeric_uprating_and_defined_for.py +0 -0
  464. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/variables/test_subtracts.py +0 -0
  465. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/variables/test_subtracts_sign.py +0 -0
  466. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/variables/test_variable_clone.py +0 -0
  467. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/variables/test_variable_formula_determinism.py +0 -0
  468. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/variables/test_variable_uprating.py +0 -0
  469. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/core/variables/test_variables.py +0 -0
  470. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/__init__.py +0 -0
  471. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/appclient.py +0 -0
  472. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/branch_input_invalidation.py +0 -0
  473. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/branch_shared_arrays.py +0 -0
  474. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/carry_over.py +0 -0
  475. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/data_storage_dir.py +0 -0
  476. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/disk_storage.py +0 -0
  477. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/entities.py +0 -0
  478. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/fast_cache_contained_periods.py +0 -0
  479. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/option_caches.py +0 -0
  480. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/parameter_metadata_clones.py +0 -0
  481. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/set_input_helper_order.py +0 -0
  482. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/simulation_copy.py +0 -0
  483. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/simulations.py +0 -0
  484. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/subsample_inputs.py +0 -0
  485. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/taxbenefitsystems.py +0 -0
  486. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/tracing.py +0 -0
  487. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/uprated_inputs.py +0 -0
  488. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/uprating_order.py +0 -0
  489. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/variables.py +0 -0
  490. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/vectorial_parameter_nodes.py +0 -0
  491. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/yaml_tests/__init__.py +0 -0
  492. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/yaml_tests/directory/subdirectory/test_4.yaml +0 -0
  493. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/yaml_tests/directory/test_1.yaml +0 -0
  494. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/yaml_tests/directory/test_2.yaml +0 -0
  495. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/yaml_tests/failing_test_absolute_error_margin.yaml +0 -0
  496. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/yaml_tests/failing_test_relative_error_margin.yaml +0 -0
  497. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/yaml_tests/test_absolute_error_margin.yaml +0 -0
  498. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/yaml_tests/test_failure.yaml +0 -0
  499. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/yaml_tests/test_name_filter.yaml +0 -0
  500. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/yaml_tests/test_relative_error_margin.yaml +0 -0
  501. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/yaml_tests/test_success.yml +0 -0
  502. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/yaml_tests/test_with_anchors.yaml +0 -0
  503. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/yaml_tests/test_with_extension.yaml +0 -0
  504. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/yaml_tests/test_with_reform.yaml +0 -0
  505. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/fixtures/yaml_tests/test_with_reform_2.yaml +0 -0
  506. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/smoke/test_country_init.py +0 -0
  507. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/tests/smoke/test_us.py +0 -0
  508. {policyengine_core-3.34.7 → policyengine_core-3.34.8}/uv.lock +0 -0
@@ -1,3 +1,10 @@
1
+ ## [3.34.8] - 2026-11-06
2
+
3
+ ### Fixed
4
+
5
+ - Simulation.apply_reform now rebinds existing holders to each branch's system before clearing cached calculations.
6
+
7
+
1
8
  ## [3.34.7] - 2026-11-05
2
9
 
3
10
  ### Changed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: policyengine-core
3
- Version: 3.34.7
3
+ Version: 3.34.8
4
4
  Summary: Core microsimulation engine enabling country-specific policy models.
5
5
  Project-URL: Homepage, https://github.com/policyengine/policyengine-core
6
6
  Author-email: PolicyEngine <hello@policyengine.org>
@@ -932,6 +932,8 @@ class Simulation:
932
932
  if isinstance(reform, dict):
933
933
  reform = Reform.from_dict(reform)
934
934
  reform.apply(self.tax_benefit_system)
935
+ # Refresh holders before input replay looks them up in the new system.
936
+ self._bind_to_tax_benefit_system()
935
937
  # Invalidate every cached value so the simulation recomputes under
936
938
  # the new tax-benefit system. Previously ``apply_reform`` left
937
939
  # ``_fast_cache``, in-memory holder storage, and on-disk holder
@@ -1318,6 +1320,11 @@ class Simulation:
1318
1320
  holder was built for the reform's definition in a way a new variable
1319
1321
  cannot change: in another entity's population, or with storage for
1320
1322
  (or not for) an ``ETERNITY`` variable.
1323
+
1324
+ After an in-place reform, compatible holders keep their storage and
1325
+ recorded inputs. Each existing branch binds to its own system, so
1326
+ shared-system branches follow the reform and a baseline keeps its
1327
+ baseline variables.
1321
1328
  """
1322
1329
  system = self.tax_benefit_system
1323
1330
  if system is None:
@@ -1346,7 +1353,11 @@ class Simulation:
1346
1353
  holder.variable = variable
1347
1354
 
1348
1355
  def kept(name):
1349
- return name in variables and name not in dropped
1356
+ # A reform may supply a new entity's input before we drop the old holder.
1357
+ return name in variables and (
1358
+ name not in dropped
1359
+ or name in self.populations[variables[name].entity.key]._holders
1360
+ )
1350
1361
 
1351
1362
  if getattr(self, "_user_input_keys", None) is not None:
1352
1363
  self._user_input_keys = {
@@ -1354,6 +1365,8 @@ class Simulation:
1354
1365
  }
1355
1366
  if getattr(self, "input_variables", None) is not None:
1356
1367
  self.input_variables = [name for name in self.input_variables if kept(name)]
1368
+ for branch in self.branches.values():
1369
+ branch._bind_to_tax_benefit_system()
1357
1370
 
1358
1371
  def create_shortcuts(self) -> None:
1359
1372
  for _key, population in self.populations.items():
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "policyengine-core"
3
- version = "3.34.7"
3
+ version = "3.34.8"
4
4
  description = "Core microsimulation engine enabling country-specific policy models."
5
5
  readme = "README.md"
6
6
  authors = [
@@ -0,0 +1,295 @@
1
+ """Reforms refresh existing holders without discarding compatible inputs."""
2
+
3
+ import numpy as np
4
+ import pytest
5
+
6
+ from policyengine_core.errors import VariableNotFoundError
7
+ from policyengine_core.parameters import ParameterNode
8
+ from policyengine_core.periods import ETERNITY, YEAR, period
9
+ from policyengine_core.reforms import Reform
10
+ from policyengine_core.variables import Variable
11
+ from tests.fixtures.reform_holders import (
12
+ Household,
13
+ Person,
14
+ build,
15
+ change_default,
16
+ store_on_disk,
17
+ )
18
+
19
+ PERIOD = "2025"
20
+
21
+
22
+ def assert_bound(simulation):
23
+ for population in simulation.populations.values():
24
+ for name, holder in population._holders.items():
25
+ assert holder.variable is simulation.tax_benefit_system.variables[name]
26
+ assert holder.variable.entity.key == population.entity.key
27
+ assert holder._memory_storage.is_eternal == (
28
+ holder.variable.definition_period == ETERNITY
29
+ )
30
+
31
+
32
+ def test_defined_for_default_does_not_depend_on_other_people():
33
+ results = []
34
+ for mask in ([False], [False, True]):
35
+ simulation = build(mask)
36
+ old_holder = simulation.get_holder("award")
37
+ simulation.apply_reform(change_default(20))
38
+ results.append(simulation.calculate("award", PERIOD).tolist())
39
+ assert simulation.get_holder("award") is old_holder
40
+
41
+ assert results == [[20], [20, 100]]
42
+
43
+
44
+ @pytest.mark.parametrize("on_disk", [False, True])
45
+ def test_replaced_variable_keeps_recorded_inputs(on_disk):
46
+ simulation = build()
47
+ if on_disk:
48
+ store_on_disk(simulation, "award")
49
+ simulation.set_input("award", PERIOD, [7, 9])
50
+ holder = simulation.get_holder("award")
51
+ records = simulation._user_input_keys.copy()
52
+ simulation.input_variables = ["award", "eligible"]
53
+
54
+ simulation.apply_reform(change_default(20))
55
+
56
+ assert simulation.get_holder("award") is holder
57
+ assert_bound(simulation)
58
+ assert simulation._user_input_keys == records
59
+ assert simulation.input_variables == ["award", "eligible"]
60
+ np.testing.assert_array_equal(simulation.calculate("award", PERIOD), [7, 9])
61
+ np.testing.assert_array_equal(holder._get_array_from_storage(PERIOD), [7, 9])
62
+
63
+
64
+ class NeutralizeAward(Reform):
65
+ def apply(self):
66
+ self.neutralize_variable("award")
67
+
68
+
69
+ @pytest.mark.parametrize("on_disk", [False, True])
70
+ def test_neutralized_variable_keeps_input_storage_but_reads_its_default(on_disk):
71
+ simulation = build()
72
+ if on_disk:
73
+ store_on_disk(simulation, "award")
74
+ simulation.set_input("award", PERIOD, [7, 9])
75
+ records = simulation._user_input_keys.copy()
76
+
77
+ simulation.apply_reform(NeutralizeAward)
78
+
79
+ holder = simulation.get_holder("award")
80
+ assert_bound(simulation)
81
+ assert holder.variable.is_neutralized
82
+ assert simulation._user_input_keys == records
83
+ np.testing.assert_array_equal(holder._get_array_from_storage(PERIOD), [7, 9])
84
+ np.testing.assert_array_equal(simulation.calculate("award", PERIOD), [0, 0])
85
+
86
+
87
+ class added(Variable):
88
+ value_type = float
89
+ entity = Person
90
+ definition_period = YEAR
91
+ default_value = 13
92
+ label = "Added amount"
93
+
94
+
95
+ class AddAndRemove(Reform):
96
+ def apply(self):
97
+ self.add_variable(added)
98
+ del self.variables["annual_value"]
99
+
100
+
101
+ @pytest.mark.parametrize("on_disk", [False, True])
102
+ def test_added_variable_is_lazy_and_removed_variable_drops_holder_and_inputs(on_disk):
103
+ simulation = build()
104
+ if on_disk:
105
+ store_on_disk(simulation, "annual_value")
106
+ simulation.set_input("annual_value", PERIOD, [7, 9])
107
+ simulation.input_variables = ["annual_value", "eligible"]
108
+
109
+ simulation.apply_reform(AddAndRemove)
110
+
111
+ assert_bound(simulation)
112
+ assert "annual_value" not in simulation.persons._holders
113
+ assert "annual_value" not in simulation.input_variables
114
+ assert all(key[0] != "annual_value" for key in simulation._user_input_keys)
115
+ with pytest.raises(VariableNotFoundError):
116
+ simulation.get_holder("annual_value")
117
+ assert "added" not in simulation.persons._holders
118
+ np.testing.assert_array_equal(simulation.calculate("added", PERIOD), [13, 13])
119
+ assert_bound(simulation)
120
+
121
+
122
+ def test_tuple_reform_rebinds_after_each_reform():
123
+ class CheckFirstReform(Reform):
124
+ def apply(self):
125
+ assert (
126
+ self.simulation.get_holder("award").variable is self.variables["award"]
127
+ )
128
+ change_default(30).apply(self)
129
+
130
+ simulation = build([False])
131
+ simulation.apply_reform((change_default(20), CheckFirstReform))
132
+
133
+ assert_bound(simulation)
134
+ np.testing.assert_array_equal(simulation.calculate("award", PERIOD), [30])
135
+
136
+
137
+ def test_dict_reform_keeps_inputs_and_rebinds_stale_holders():
138
+ simulation = build([False])
139
+ simulation.tax_benefit_system.parameters = ParameterNode(
140
+ "", data={"amount": {"values": {"2025-01-01": {"value": 1}}}}
141
+ )
142
+ simulation.set_input("income", PERIOD, [7])
143
+ change_default(20).apply(simulation.tax_benefit_system)
144
+
145
+ simulation.apply_reform({"amount": {"2025": 2}})
146
+
147
+ assert_bound(simulation)
148
+ assert simulation.tax_benefit_system.parameters("2025-01-01").amount == 2
149
+ np.testing.assert_array_equal(simulation.calculate("income", PERIOD), [7])
150
+ np.testing.assert_array_equal(simulation.calculate("award", PERIOD), [20])
151
+
152
+
153
+ def test_existing_baseline_keeps_its_own_system():
154
+ simulation = build([False])
155
+ baseline = simulation.get_branch("baseline", clone_system=True)
156
+ simulation.baseline = baseline
157
+ baseline_system = baseline.tax_benefit_system
158
+ np.testing.assert_array_equal(baseline.calculate("award", PERIOD), [0])
159
+
160
+ simulation.apply_reform(change_default(20))
161
+
162
+ assert simulation.baseline is baseline
163
+ assert baseline.tax_benefit_system is baseline_system
164
+ assert_bound(simulation)
165
+ assert_bound(baseline)
166
+ np.testing.assert_array_equal(baseline.calculate("award", PERIOD), [0])
167
+ np.testing.assert_array_equal(simulation.calculate("award", PERIOD), [20])
168
+
169
+
170
+ def test_existing_branches_rebind_to_their_own_systems():
171
+ simulation = build([False])
172
+ shared = simulation.get_branch("shared")
173
+ nested = shared.get_branch("nested")
174
+ independent = simulation.get_branch("independent", clone_system=True)
175
+ independent.apply_reform(change_default(40))
176
+ for branch in (simulation, shared, nested, independent):
177
+ branch.set_input("income", PERIOD, [7])
178
+ branch.calculate("award", PERIOD)
179
+
180
+ simulation.apply_reform(change_default(20))
181
+
182
+ for branch, expected in (
183
+ (simulation, 20),
184
+ (shared, 20),
185
+ (nested, 20),
186
+ (independent, 40),
187
+ ):
188
+ assert_bound(branch)
189
+ np.testing.assert_array_equal(branch.calculate("award", PERIOD), [expected])
190
+ np.testing.assert_array_equal(branch.calculate("income", PERIOD), [7])
191
+
192
+
193
+ class MoveAnnualToHousehold(Reform):
194
+ def apply(self):
195
+ class annual_value(Variable):
196
+ entity = Household
197
+ default_value = 17
198
+
199
+ self.update_variable(annual_value)
200
+
201
+
202
+ def test_entity_change_drops_orphaned_holder_and_input_records():
203
+ simulation = build()
204
+ simulation.set_input("annual_value", PERIOD, [7, 9])
205
+ simulation.input_variables = ["annual_value", "eligible"]
206
+
207
+ simulation.apply_reform(MoveAnnualToHousehold)
208
+
209
+ assert "annual_value" not in simulation.persons._holders
210
+ assert "annual_value" not in simulation.input_variables
211
+ assert all(key[0] != "annual_value" for key in simulation._user_input_keys)
212
+ np.testing.assert_array_equal(simulation.calculate("annual_value", PERIOD), [17])
213
+ assert_bound(simulation)
214
+
215
+
216
+ @pytest.mark.parametrize("on_disk", [False, True])
217
+ def test_entity_change_keeps_inputs_supplied_to_the_new_holder(on_disk):
218
+ class MoveAndSupply(Reform):
219
+ def apply(self):
220
+ MoveAnnualToHousehold.apply(self)
221
+ self.simulation.set_input("annual_value", PERIOD, [31])
222
+
223
+ simulation = build()
224
+ if on_disk:
225
+ store_on_disk(simulation, "annual_value")
226
+ simulation.set_input("annual_value", PERIOD, [7, 9])
227
+ simulation.input_variables = ["annual_value", "eligible"]
228
+
229
+ simulation.apply_reform(MoveAndSupply)
230
+
231
+ assert "annual_value" not in simulation.persons._holders
232
+ assert "annual_value" in simulation.input_variables
233
+ assert ("annual_value", "default", period(PERIOD)) in simulation._user_input_keys
234
+ np.testing.assert_array_equal(simulation.calculate("annual_value", PERIOD), [31])
235
+ assert_bound(simulation)
236
+
237
+
238
+ class MakeAnnual(Reform):
239
+ def apply(self):
240
+ class eternal_value(Variable):
241
+ definition_period = YEAR
242
+
243
+ def formula(person, period):
244
+ return person.filled_array(period.start.year)
245
+
246
+ self.update_variable(eternal_value)
247
+
248
+
249
+ class MakeEternal(Reform):
250
+ def apply(self):
251
+ class annual_value(Variable):
252
+ definition_period = ETERNITY
253
+
254
+ self.update_variable(annual_value)
255
+
256
+
257
+ @pytest.mark.parametrize("on_disk", [False, True])
258
+ def test_eternity_to_year_drops_incompatible_storage_and_inputs(on_disk):
259
+ simulation = build()
260
+ if on_disk:
261
+ store_on_disk(simulation, "eternal_value")
262
+ simulation.set_input("eternal_value", PERIOD, [7, 9])
263
+ simulation.input_variables = ["eternal_value", "eligible"]
264
+
265
+ simulation.apply_reform(MakeAnnual)
266
+
267
+ np.testing.assert_array_equal(
268
+ simulation.calculate("eternal_value", "2025"), [2025, 2025]
269
+ )
270
+ np.testing.assert_array_equal(
271
+ simulation.calculate("eternal_value", "2026"), [2026, 2026]
272
+ )
273
+ assert "eternal_value" not in simulation.input_variables
274
+ assert all(key[0] != "eternal_value" for key in simulation._user_input_keys)
275
+ assert_bound(simulation)
276
+
277
+
278
+ @pytest.mark.parametrize("on_disk", [False, True])
279
+ def test_year_to_eternity_uses_eternal_storage_for_new_inputs(on_disk):
280
+ simulation = build()
281
+ if on_disk:
282
+ store_on_disk(simulation, "annual_value")
283
+ simulation.set_input("annual_value", PERIOD, [7, 9])
284
+ simulation.apply_reform(MakeEternal)
285
+
286
+ assert all(key[0] != "annual_value" for key in simulation._user_input_keys)
287
+ simulation.set_input("annual_value", PERIOD, [11, 12])
288
+
289
+ assert_bound(simulation)
290
+ np.testing.assert_array_equal(
291
+ simulation.calculate("annual_value", "2025"), [11, 12]
292
+ )
293
+ np.testing.assert_array_equal(
294
+ simulation.calculate("annual_value", "2026"), [11, 12]
295
+ )
@@ -0,0 +1,226 @@
1
+ """Check holder identity, defaults and recorded inputs after a reform."""
2
+
3
+ import numpy as np
4
+ import pytest
5
+
6
+ hypothesis = pytest.importorskip("hypothesis")
7
+ st = hypothesis.strategies
8
+
9
+ from policyengine_core import periods
10
+ from policyengine_core.reforms import Reform
11
+ from policyengine_core.variables import Variable
12
+ from tests.fixtures.reform_holders import YEAR, build, change_default, store_on_disk
13
+
14
+ pytestmark = pytest.mark.filterwarnings(
15
+ "ignore:Memory configuration:policyengine_core.warnings.MemoryConfigWarning"
16
+ )
17
+
18
+ PROPERTY_SETTINGS = hypothesis.settings(max_examples=50, deadline=None, database=None)
19
+ MASKS = st.lists(st.booleans(), min_size=1, max_size=6)
20
+ DEFAULTS = st.integers(min_value=-1_000, max_value=1_000)
21
+ REPLACED = ("award", "annual_value", "group_value")
22
+
23
+
24
+ def assert_holder_identity(simulation):
25
+ for population in simulation.populations.values():
26
+ for name, holder in population._holders.items():
27
+ assert holder.variable is simulation.tax_benefit_system.variables[name]
28
+
29
+
30
+ def expected_award(mask, default):
31
+ return np.where(mask, 100.0, float(default))
32
+
33
+
34
+ def change_several_defaults(default):
35
+ class ChangeSeveralDefaults(Reform):
36
+ def apply(self):
37
+ for offset, name in enumerate(REPLACED):
38
+ attributes = {"default_value": float(default + offset)}
39
+ if name == "award":
40
+ attributes["defined_for"] = "eligible"
41
+ self.update_variable(type(name, (Variable,), attributes))
42
+
43
+ return ChangeSeveralDefaults
44
+
45
+
46
+ @PROPERTY_SETTINGS
47
+ @hypothesis.given(
48
+ mask=MASKS,
49
+ default=DEFAULTS,
50
+ order=st.permutations(REPLACED),
51
+ warm=st.booleans(),
52
+ branches=st.sampled_from(("none", "shared", "independent", "both")),
53
+ )
54
+ @hypothesis.example(
55
+ mask=[False, True],
56
+ default=7,
57
+ order=("group_value", "award", "annual_value"),
58
+ warm=True,
59
+ branches="both",
60
+ )
61
+ def test_every_existing_holder_uses_its_system_variable(
62
+ mask, default, order, warm, branches
63
+ ):
64
+ simulation = build(mask)
65
+ for name in REPLACED:
66
+ population = simulation.get_variable_population(name)
67
+ del population._holders[name]
68
+ for name in order:
69
+ simulation.get_holder(name)
70
+ if warm:
71
+ simulation.calculate(name, YEAR)
72
+ related = []
73
+ if branches in ("shared", "both"):
74
+ related.append((simulation.get_branch("shared"), default))
75
+ if branches in ("independent", "both"):
76
+ related.append((simulation.get_branch("independent", clone_system=True), 0))
77
+
78
+ simulation.apply_reform(change_several_defaults(default))
79
+
80
+ for member in [simulation, *(branch for branch, _ in related)]:
81
+ assert_holder_identity(member)
82
+ for member, expected_default in [(simulation, default), *related]:
83
+ np.testing.assert_array_equal(
84
+ member.calculate("award", YEAR), expected_award(mask, expected_default)
85
+ )
86
+ np.testing.assert_array_equal(
87
+ simulation.calculate("annual_value", YEAR),
88
+ np.full(len(mask), default + 1),
89
+ )
90
+ np.testing.assert_array_equal(
91
+ simulation.calculate("group_value", YEAR), [default + 2]
92
+ )
93
+
94
+
95
+ @PROPERTY_SETTINGS
96
+ @hypothesis.given(mask=MASKS, default=DEFAULTS, warm=st.booleans())
97
+ @hypothesis.example(mask=[False, False], default=7, warm=False)
98
+ @hypothesis.example(mask=[False, True], default=7, warm=True)
99
+ def test_person_result_does_not_depend_on_other_people(mask, default, warm):
100
+ combined = build(mask)
101
+ if warm:
102
+ combined.calculate("award", YEAR)
103
+ reform = change_default(default)
104
+ combined.apply_reform(reform)
105
+ together = combined.calculate("award", YEAR)
106
+ alone = []
107
+ for eligible in mask:
108
+ individual = build([eligible])
109
+ if warm:
110
+ individual.calculate("award", YEAR)
111
+ individual.apply_reform(reform)
112
+ alone.append(individual.calculate("award", YEAR)[0])
113
+
114
+ np.testing.assert_array_equal(together, expected_award(mask, default))
115
+ np.testing.assert_array_equal(alone, expected_award(mask, default))
116
+ np.testing.assert_array_equal(together, alone)
117
+
118
+
119
+ @PROPERTY_SETTINGS
120
+ @hypothesis.given(mask=MASKS, default=DEFAULTS, warm=st.booleans())
121
+ @hypothesis.example(mask=[False, False], default=7, warm=True)
122
+ @hypothesis.example(mask=[False, True], default=7, warm=False)
123
+ def test_reform_before_or_after_holder_creation_returns_same_values(
124
+ mask, default, warm
125
+ ):
126
+ before_holder = build(mask)
127
+ del before_holder.person._holders["award"]
128
+ after_holder = build(mask)
129
+ if warm:
130
+ after_holder.calculate("award", YEAR)
131
+ reform = change_default(default)
132
+
133
+ before_holder.apply_reform(reform)
134
+ after_holder.apply_reform(reform)
135
+
136
+ expected = expected_award(mask, default)
137
+ np.testing.assert_array_equal(before_holder.calculate("award", YEAR), expected)
138
+ np.testing.assert_array_equal(after_holder.calculate("award", YEAR), expected)
139
+ assert_holder_identity(before_holder)
140
+ assert_holder_identity(after_holder)
141
+
142
+
143
+ INPUT_ROWS = st.lists(
144
+ st.tuples(
145
+ st.booleans(),
146
+ st.integers(min_value=-10_000, max_value=10_000),
147
+ st.integers(min_value=-10_000, max_value=10_000),
148
+ ),
149
+ min_size=1,
150
+ max_size=6,
151
+ )
152
+
153
+
154
+ @PROPERTY_SETTINGS
155
+ @hypothesis.given(
156
+ rows=INPUT_ROWS,
157
+ defaults=st.lists(DEFAULTS, min_size=1, max_size=4),
158
+ on_disk=st.booleans(),
159
+ branch=st.booleans(),
160
+ )
161
+ @hypothesis.example(
162
+ rows=[(False, 12, 34), (True, -5, 9)],
163
+ defaults=[7, 11],
164
+ on_disk=True,
165
+ branch=True,
166
+ )
167
+ def test_unchanged_recorded_inputs_survive_reforms(rows, defaults, on_disk, branch):
168
+ mask, incomes, eternal = zip(*rows)
169
+ simulation = build(mask)
170
+ if on_disk:
171
+ store_on_disk(simulation, "income", "annual_value", "eternal_value")
172
+ supplied = {
173
+ "income": np.asarray(incomes, dtype=np.float32),
174
+ "annual_value": np.asarray(incomes, dtype=np.float32) + 1,
175
+ "eternal_value": np.asarray(eternal, dtype=np.float32),
176
+ }
177
+ for name, values in supplied.items():
178
+ simulation.set_input(name, YEAR, values)
179
+ if on_disk:
180
+ holder = simulation.get_holder(name)
181
+ assert holder._disk_storage.get(periods.period(YEAR)) is not None
182
+ assert holder._memory_storage.get(periods.period(YEAR)) is None
183
+ members = [simulation]
184
+ if branch:
185
+ members.append(simulation.get_branch("existing"))
186
+ input_keys = [set(member._user_input_keys) for member in members]
187
+
188
+ for default in defaults:
189
+ simulation.apply_reform(change_default(default))
190
+ for member, keys in zip(members, input_keys):
191
+ assert member._user_input_keys == keys
192
+ for name, expected in supplied.items():
193
+ np.testing.assert_array_equal(member.calculate(name, YEAR), expected)
194
+ np.testing.assert_array_equal(
195
+ member.calculate("award", YEAR), expected_award(mask, default)
196
+ )
197
+ assert_holder_identity(member)
198
+
199
+
200
+ @PROPERTY_SETTINGS
201
+ @hypothesis.given(mask=MASKS, default=DEFAULTS, warm=st.booleans())
202
+ @hypothesis.example(mask=[False, False], default=7, warm=True)
203
+ @hypothesis.example(mask=[False, True], default=7, warm=False)
204
+ def test_applying_same_reform_object_twice_returns_same_values(mask, default, warm):
205
+ once = build(mask)
206
+ twice = build(mask)
207
+ inputs = np.arange(len(mask), dtype=np.float32) + 5
208
+ for simulation in (once, twice):
209
+ simulation.set_input("income", YEAR, inputs)
210
+ if warm:
211
+ simulation.calculate("award", YEAR)
212
+ reform = change_default(default)
213
+
214
+ once.apply_reform(reform)
215
+ twice.apply_reform(reform)
216
+ twice.calculate("award", YEAR)
217
+ twice.apply_reform(reform)
218
+
219
+ expected = expected_award(mask, default)
220
+ for simulation in (once, twice):
221
+ np.testing.assert_array_equal(simulation.calculate("award", YEAR), expected)
222
+ np.testing.assert_array_equal(simulation.calculate("income", YEAR), inputs)
223
+ assert_holder_identity(simulation)
224
+ np.testing.assert_array_equal(
225
+ twice.calculate("award", YEAR), once.calculate("award", YEAR)
226
+ )