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