policyengine-core 3.26.2__tar.gz → 3.26.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (386) hide show
  1. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/CHANGELOG.md +15 -0
  2. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/PKG-INFO +1 -1
  3. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/data_structures/parameter_node_metadata.py +2 -2
  4. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/holders/helpers.py +19 -5
  5. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/holders/holder.py +37 -18
  6. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/parameters/config.py +24 -9
  7. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/parameters/operations/homogenize_parameters.py +90 -2
  8. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/parameters/operations/uprate_parameters.py +171 -127
  9. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/parameters/parameter_node.py +1 -1
  10. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/parameters/parameter_scale_bracket.py +1 -1
  11. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/simulations/simulation.py +40 -12
  12. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/tools/test_runner.py +16 -3
  13. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/pyproject.toml +1 -1
  14. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameters/operations/test_uprating.py +100 -0
  15. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_apply_reform_preserves_user_inputs.py +111 -0
  16. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_holder_branch_fallback.py +15 -0
  17. policyengine_core-3.26.4/tests/core/test_parameter_security.py +130 -0
  18. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/tools/test_runner/test_yaml_runner.py +107 -0
  19. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/.github/ISSUE_TEMPLATE.md +0 -0
  20. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  21. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/.github/bump_version.py +0 -0
  22. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/.github/changelog_template.md +0 -0
  23. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/.github/get-changelog-diff.sh +0 -0
  24. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/.github/has-functional-changes.sh +0 -0
  25. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/.github/is-version-number-acceptable.sh +0 -0
  26. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/.github/publish-git-tag.sh +0 -0
  27. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/.github/workflows/pr.yaml +0 -0
  28. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/.github/workflows/push.yaml +0 -0
  29. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/.gitignore +0 -0
  30. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/.python-version +0 -0
  31. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/AGENTS.md +0 -0
  32. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/CLAUDE.md +0 -0
  33. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/CONTRIBUTING.md +0 -0
  34. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/LICENSE +0 -0
  35. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/MANIFEST.in +0 -0
  36. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/Makefile +0 -0
  37. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/README.md +0 -0
  38. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/_build/logs/myst.build.json +0 -0
  39. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/changelog.d/.gitkeep +0 -0
  40. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/_config.yml +0 -0
  41. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/_static/style.css +0 -0
  42. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/_toc.yml +0 -0
  43. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/add_plotly_to_book.py +0 -0
  44. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/contributing/intro.md +0 -0
  45. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/engineering/skills/README.md +0 -0
  46. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/engineering/skills/documentation_review.md +0 -0
  47. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/engineering/skills/github-prs.md +0 -0
  48. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/engineering/skills/testing.md +0 -0
  49. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/intro.md +0 -0
  50. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/logo.png +0 -0
  51. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/python_api/commons.md +0 -0
  52. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/python_api/country_template.md +0 -0
  53. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/python_api/data.md +0 -0
  54. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/python_api/data_storage.md +0 -0
  55. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/python_api/entities.md +0 -0
  56. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/python_api/enums.md +0 -0
  57. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/python_api/errors.md +0 -0
  58. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/python_api/experimental.md +0 -0
  59. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/python_api/extension_template.md +0 -0
  60. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/python_api/holders.md +0 -0
  61. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/python_api/parameters.md +0 -0
  62. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/python_api/periods.md +0 -0
  63. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/python_api/populations.md +0 -0
  64. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/python_api/projectors.md +0 -0
  65. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/python_api/reforms.md +0 -0
  66. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/python_api/scripts.md +0 -0
  67. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/python_api/simulations.md +0 -0
  68. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/python_api/taxbenefitsystems.md +0 -0
  69. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/python_api/taxscales.md +0 -0
  70. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/python_api/tools.md +0 -0
  71. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/python_api/tracers.md +0 -0
  72. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/python_api/types.md +0 -0
  73. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/python_api/variables.md +0 -0
  74. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/python_api/warnings.md +0 -0
  75. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/usage/country.ipynb +0 -0
  76. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/usage/datasets.ipynb +0 -0
  77. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/usage/parameters.md +0 -0
  78. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/usage/reforms.ipynb +0 -0
  79. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/docs/usage/simulation.ipynb +0 -0
  80. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/mypy.ini +0 -0
  81. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/__init__.py +0 -0
  82. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/build_metadata.py +0 -0
  83. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/charts/__init__.py +0 -0
  84. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/charts/api.py +0 -0
  85. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/charts/bar.py +0 -0
  86. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/charts/formatting.py +0 -0
  87. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/commons/__init__.py +0 -0
  88. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/commons/formulas.py +0 -0
  89. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/commons/misc.py +0 -0
  90. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/commons/rates.py +0 -0
  91. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/__init__.py +0 -0
  92. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/constants.py +0 -0
  93. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/data/__init__.py +0 -0
  94. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/data/datasets/__init__.py +0 -0
  95. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/data/datasets/country_template_dataset.py +0 -0
  96. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/entities.py +0 -0
  97. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/modelled_policies.yaml +0 -0
  98. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/parameters/benefits/basic_income.yaml +0 -0
  99. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/parameters/benefits/housing_allowance.yaml +0 -0
  100. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/parameters/benefits/index.yaml +0 -0
  101. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/parameters/benefits/parenting_allowance/amount.yaml +0 -0
  102. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/parameters/benefits/parenting_allowance/income_threshold.yaml +0 -0
  103. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/parameters/general/age_of_majority.yaml +0 -0
  104. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/parameters/general/age_of_retirement.yaml +0 -0
  105. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/parameters/taxes/housing_tax.yaml +0 -0
  106. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/parameters/taxes/income_tax_rate.yaml +0 -0
  107. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/parameters/taxes/social_security_contribution.yaml +0 -0
  108. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/reforms/__init__.py +0 -0
  109. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/reforms/add_dynamic_variable.py +0 -0
  110. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/reforms/add_new_tax.py +0 -0
  111. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/reforms/flat_social_security_contribution.py +0 -0
  112. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/reforms/modify_social_security_taxation.py +0 -0
  113. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/reforms/removal_basic_income.py +0 -0
  114. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/situation_examples/__init__.py +0 -0
  115. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/situation_examples/couple.json +0 -0
  116. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/situation_examples/housing.json +0 -0
  117. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/situation_examples/single.json +0 -0
  118. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/tests/age.yaml +0 -0
  119. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/tests/basic_income.yaml +0 -0
  120. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/tests/disposable_income.yaml +0 -0
  121. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/tests/housing_allowance.yaml +0 -0
  122. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/tests/housing_tax.yaml +0 -0
  123. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/tests/income_tax.yaml +0 -0
  124. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/tests/reforms/add_dynamic_variable.yaml +0 -0
  125. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/tests/reforms/add_new_tax.yaml +0 -0
  126. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/tests/reforms/modify_social_security_taxation.yaml +0 -0
  127. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/tests/situations/income_tax.yaml +0 -0
  128. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/tests/situations/parenting_allowance.yaml +0 -0
  129. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/tests/social_security_contribution.yaml +0 -0
  130. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/tests/test_microsimulation.py +0 -0
  131. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/variables/__init__.py +0 -0
  132. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/variables/benefits.py +0 -0
  133. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/variables/demographics.py +0 -0
  134. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/variables/housing.py +0 -0
  135. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/variables/ids.py +0 -0
  136. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/variables/income.py +0 -0
  137. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/variables/stats.py +0 -0
  138. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/country_template/variables/taxes.py +0 -0
  139. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/data/__init__.py +0 -0
  140. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/data/dataset.py +0 -0
  141. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/data_storage/__init__.py +0 -0
  142. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/data_storage/in_memory_storage.py +0 -0
  143. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/data_storage/on_disk_storage.py +0 -0
  144. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/data_structures/__init__.py +0 -0
  145. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/data_structures/parameter_metadata.py +0 -0
  146. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/data_structures/reference.py +0 -0
  147. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/data_structures/unit.py +0 -0
  148. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/entities/__init__.py +0 -0
  149. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/entities/entity.py +0 -0
  150. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/entities/group_entity.py +0 -0
  151. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/entities/helpers.py +0 -0
  152. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/entities/role.py +0 -0
  153. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/enums/__init__.py +0 -0
  154. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/enums/config.py +0 -0
  155. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/enums/enum.py +0 -0
  156. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/enums/enum_array.py +0 -0
  157. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/errors/__init__.py +0 -0
  158. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/errors/cycle_error.py +0 -0
  159. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/errors/empty_argument_error.py +0 -0
  160. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/errors/nan_creation_error.py +0 -0
  161. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/errors/parameter_not_found_error.py +0 -0
  162. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/errors/parameter_parsing_error.py +0 -0
  163. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/errors/period_mismatch_error.py +0 -0
  164. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/errors/situation_parsing_error.py +0 -0
  165. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/errors/spiral_error.py +0 -0
  166. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/errors/variable_name_conflict_error.py +0 -0
  167. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/errors/variable_not_found_error.py +0 -0
  168. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/experimental/__init__.py +0 -0
  169. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/experimental/memory_config.py +0 -0
  170. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/extension_template/__init__.py +0 -0
  171. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/extension_template/local_benefit.py +0 -0
  172. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/extension_template/parameters/local_town/child_allowance/amount.yaml +0 -0
  173. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/extension_template/parameters/local_town/child_allowance/index.yaml +0 -0
  174. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/extension_template/parameters/local_town/index.yaml +0 -0
  175. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/extension_template/tests/local_benefit.yaml +0 -0
  176. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/holders/__init__.py +0 -0
  177. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/model_api.py +0 -0
  178. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/parameters/__init__.py +0 -0
  179. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/parameters/at_instant_like.py +0 -0
  180. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/parameters/helpers.py +0 -0
  181. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/parameters/operations/__init__.py +0 -0
  182. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/parameters/operations/get_parameter.py +0 -0
  183. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/parameters/operations/interpolate_parameters.py +0 -0
  184. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/parameters/operations/propagate_parameter_metadata.py +0 -0
  185. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/parameters/parameter.py +0 -0
  186. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/parameters/parameter_at_instant.py +0 -0
  187. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/parameters/parameter_node_at_instant.py +0 -0
  188. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/parameters/parameter_scale.py +0 -0
  189. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/parameters/vectorial_parameter_node_at_instant.py +0 -0
  190. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/periods/__init__.py +0 -0
  191. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/periods/config.py +0 -0
  192. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/periods/helpers.py +0 -0
  193. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/periods/instant_.py +0 -0
  194. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/periods/period_.py +0 -0
  195. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/populations/__init__.py +0 -0
  196. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/populations/config.py +0 -0
  197. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/populations/group_population.py +0 -0
  198. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/populations/population.py +0 -0
  199. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/projectors/__init__.py +0 -0
  200. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/projectors/entity_to_person_projector.py +0 -0
  201. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/projectors/first_person_to_entity_projector.py +0 -0
  202. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/projectors/helpers.py +0 -0
  203. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/projectors/projector.py +0 -0
  204. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/projectors/unique_role_to_entity_projector.py +0 -0
  205. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/reforms/__init__.py +0 -0
  206. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/reforms/reform.py +0 -0
  207. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/scripts/__init__.py +0 -0
  208. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/scripts/assets/__init__.py +0 -0
  209. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/scripts/assets/index.html +0 -0
  210. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/scripts/policyengine_command.py +0 -0
  211. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/scripts/run_data.py +0 -0
  212. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/scripts/run_test.py +0 -0
  213. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/scripts/simulation_generator.py +0 -0
  214. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/simulations/__init__.py +0 -0
  215. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/simulations/helpers.py +0 -0
  216. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/simulations/individual_sim.py +0 -0
  217. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/simulations/microsimulation.py +0 -0
  218. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/simulations/simulation_builder.py +0 -0
  219. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/simulations/simulation_macro_cache.py +0 -0
  220. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/taxbenefitsystems/__init__.py +0 -0
  221. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/taxbenefitsystems/tax_benefit_system.py +0 -0
  222. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/taxscales/__init__.py +0 -0
  223. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/taxscales/abstract_rate_tax_scale.py +0 -0
  224. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/taxscales/abstract_tax_scale.py +0 -0
  225. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/taxscales/amount_tax_scale_like.py +0 -0
  226. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/taxscales/helpers.py +0 -0
  227. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/taxscales/linear_average_rate_tax_scale.py +0 -0
  228. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/taxscales/marginal_amount_tax_scale.py +0 -0
  229. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/taxscales/marginal_rate_tax_scale.py +0 -0
  230. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/taxscales/rate_tax_scale_like.py +0 -0
  231. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/taxscales/single_amount_tax_scale.py +0 -0
  232. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/taxscales/tax_scale_like.py +0 -0
  233. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/tools/__init__.py +0 -0
  234. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/tools/google_cloud.py +0 -0
  235. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/tools/hugging_face.py +0 -0
  236. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/tools/simulation_dumper.py +0 -0
  237. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/tools/test_from_situation.py +0 -0
  238. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/tools/win_file_manager.py +0 -0
  239. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/tracers/__init__.py +0 -0
  240. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/tracers/computation_log.py +0 -0
  241. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/tracers/flat_trace.py +0 -0
  242. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/tracers/full_tracer.py +0 -0
  243. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/tracers/performance_log.py +0 -0
  244. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/tracers/simple_tracer.py +0 -0
  245. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/tracers/trace_node.py +0 -0
  246. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/tracers/tracing_parameter_node_at_instant.py +0 -0
  247. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/tracers/variable_graph.py +0 -0
  248. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/types/__init__.py +0 -0
  249. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/types/data_types/__init__.py +0 -0
  250. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/types/data_types/arrays.py +0 -0
  251. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/variables/__init__.py +0 -0
  252. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/variables/config.py +0 -0
  253. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/variables/defined_for.py +0 -0
  254. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/variables/helpers.py +0 -0
  255. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/variables/typing.py +0 -0
  256. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/variables/variable.py +0 -0
  257. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/warnings/__init__.py +0 -0
  258. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/warnings/libyaml_warning.py +0 -0
  259. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/warnings/memory_config_warning.py +0 -0
  260. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/policyengine_core/warnings/tempfile_warning.py +0 -0
  261. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/pytest.ini +0 -0
  262. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/test.ipynb +0 -0
  263. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/__init__.py +0 -0
  264. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/conftest.py +0 -0
  265. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/__init__.py +0 -0
  266. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/commons/__init__.py +0 -0
  267. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/commons/test_between_function.py +0 -0
  268. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/commons/test_formulas.py +0 -0
  269. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/commons/test_is_in_function.py +0 -0
  270. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/commons/test_random_seed.py +0 -0
  271. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/commons/test_rates.py +0 -0
  272. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/data/test_dataset.py +0 -0
  273. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/enums/test_enum.py +0 -0
  274. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/model_api/test_index_.py +0 -0
  275. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameter_validation/__init__.py +0 -0
  276. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameter_validation/array_type.yaml +0 -0
  277. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameter_validation/duplicate_key.yaml +0 -0
  278. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameter_validation/filesystem_hierarchy/empty_index_file/index.yaml +0 -0
  279. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameter_validation/filesystem_hierarchy/node1/param.yaml +0 -0
  280. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameter_validation/indentation.yaml +0 -0
  281. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameter_validation/missing_value.yaml +0 -0
  282. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameter_validation/parameter_for_unit_propagation.yaml +0 -0
  283. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameter_validation/test_parameter_clone.py +0 -0
  284. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameter_validation/test_parameter_validation.py +0 -0
  285. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameter_validation/test_propagate_units.py +0 -0
  286. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameter_validation/unexpected_key_in_parameter.yaml +0 -0
  287. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameter_validation/unexpected_key_in_scale.yaml +0 -0
  288. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameter_validation/unexpected_key_in_value_at_instant.yaml +0 -0
  289. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameter_validation/unexpected_key_in_value_history.yaml +0 -0
  290. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameter_validation/wrong_date.yaml +0 -0
  291. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameter_validation/wrong_scale.yaml +0 -0
  292. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameter_validation/wrong_type_in_bracket.yaml +0 -0
  293. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameter_validation/wrong_type_in_brackets.yaml +0 -0
  294. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameter_validation/wrong_type_in_parameter.yaml +0 -0
  295. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameter_validation/wrong_type_in_scale.yaml +0 -0
  296. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameter_validation/wrong_type_in_value_history.yaml +0 -0
  297. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameter_validation/wrong_value.yaml +0 -0
  298. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameter_validation/yaml_hierarchy/node1.yaml +0 -0
  299. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameters/operations/test_interpolation.py +0 -0
  300. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameters/operations/test_nesting.py +0 -0
  301. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameters/operations/test_propagation.py +0 -0
  302. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameters/test_numpy2_structured_arrays.py +0 -0
  303. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameters_fancy_indexing/__init__.py +0 -0
  304. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameters_fancy_indexing/bareme.yaml +0 -0
  305. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameters_fancy_indexing/local_tax.yaml +0 -0
  306. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameters_fancy_indexing/rate.yaml +0 -0
  307. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/parameters_fancy_indexing/test_fancy_indexing.py +0 -0
  308. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/tax_scales/__init__.py +0 -0
  309. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/tax_scales/test_abstract_rate_tax_scale.py +0 -0
  310. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/tax_scales/test_abstract_tax_scale.py +0 -0
  311. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/tax_scales/test_linear_average_rate_tax_scale.py +0 -0
  312. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/tax_scales/test_marginal_amount_tax_scale.py +0 -0
  313. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/tax_scales/test_marginal_rate_tax_scale.py +0 -0
  314. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/tax_scales/test_rate_tax_scale_like.py +0 -0
  315. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/tax_scales/test_single_amount_tax_scale.py +0 -0
  316. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/tax_scales/test_tax_scales_commons.py +0 -0
  317. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_apply_reform_invalidates_cache.py +0 -0
  318. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_assert_near_precision.py +0 -0
  319. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_axes.py +0 -0
  320. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_bincount_minlength.py +0 -0
  321. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_build_metadata.py +0 -0
  322. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_calculate_output.py +0 -0
  323. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_countries.py +0 -0
  324. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_cycles.py +0 -0
  325. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_dataset_getattr.py +0 -0
  326. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_dump_restore.py +0 -0
  327. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_entities.py +0 -0
  328. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_eternity_subperiods.py +0 -0
  329. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_extensions.py +0 -0
  330. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_fast_cache.py +0 -0
  331. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_fast_cache_guards.py +0 -0
  332. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_formulas.py +0 -0
  333. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_holders.py +0 -0
  334. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_macro_cache_not_singleton.py +0 -0
  335. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_medium_fixes.py +0 -0
  336. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_microsimulation_person_accessor.py +0 -0
  337. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_opt_out_cache.py +0 -0
  338. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_pandas3_compatibility.py +0 -0
  339. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_parameters.py +0 -0
  340. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_periods.py +0 -0
  341. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_projectors.py +0 -0
  342. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_reform_parameter_isolation.py +0 -0
  343. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_reforms.py +0 -0
  344. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_simulation_builder.py +0 -0
  345. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_simulations.py +0 -0
  346. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_stable_hash_seed.py +0 -0
  347. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_storage_delete_branch.py +0 -0
  348. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_subsample_invalidates_cache.py +0 -0
  349. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_tax_benefit_system_cache_identity.py +0 -0
  350. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_tracers.py +0 -0
  351. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/test_yaml.py +0 -0
  352. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/tools/__init__.py +0 -0
  353. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/tools/test_assert_near.py +0 -0
  354. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/tools/test_google_cloud.py +0 -0
  355. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/tools/test_hugging_face.py +0 -0
  356. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/variables/test_adds.py +0 -0
  357. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/variables/test_annualize.py +0 -0
  358. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/variables/test_bounds.py +0 -0
  359. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/variables/test_defined_for.py +0 -0
  360. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/variables/test_subtracts.py +0 -0
  361. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/variables/test_subtracts_sign.py +0 -0
  362. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/core/variables/test_variables.py +0 -0
  363. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/fixtures/__init__.py +0 -0
  364. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/fixtures/appclient.py +0 -0
  365. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/fixtures/entities.py +0 -0
  366. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/fixtures/simulations.py +0 -0
  367. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/fixtures/taxbenefitsystems.py +0 -0
  368. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/fixtures/variables.py +0 -0
  369. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/fixtures/yaml_tests/__init__.py +0 -0
  370. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/fixtures/yaml_tests/directory/subdirectory/test_4.yaml +0 -0
  371. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/fixtures/yaml_tests/directory/test_1.yaml +0 -0
  372. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/fixtures/yaml_tests/directory/test_2.yaml +0 -0
  373. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/fixtures/yaml_tests/failing_test_absolute_error_margin.yaml +0 -0
  374. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/fixtures/yaml_tests/failing_test_relative_error_margin.yaml +0 -0
  375. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/fixtures/yaml_tests/test_absolute_error_margin.yaml +0 -0
  376. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/fixtures/yaml_tests/test_failure.yaml +0 -0
  377. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/fixtures/yaml_tests/test_name_filter.yaml +0 -0
  378. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/fixtures/yaml_tests/test_relative_error_margin.yaml +0 -0
  379. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/fixtures/yaml_tests/test_success.yml +0 -0
  380. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/fixtures/yaml_tests/test_with_anchors.yaml +0 -0
  381. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/fixtures/yaml_tests/test_with_extension.yaml +0 -0
  382. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/fixtures/yaml_tests/test_with_reform.yaml +0 -0
  383. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/fixtures/yaml_tests/test_with_reform_2.yaml +0 -0
  384. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/smoke/test_country_init.py +0 -0
  385. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/tests/smoke/test_us.py +0 -0
  386. {policyengine_core-3.26.2 → policyengine_core-3.26.4}/uv.lock +0 -0
@@ -1,3 +1,18 @@
1
+ ## [3.26.4] - 2026-05-14
2
+
3
+ ### Fixed
4
+
5
+ - Use safe YAML loaders and remove dynamic eval from parameter breakdown handling.
6
+
7
+
8
+ ## [3.26.3] - 2026-05-14
9
+
10
+ ### Fixed
11
+
12
+ - Preserve values passed through dispatched `set_input` handlers across cache invalidation.
13
+ - Apply chained parameter uprating dependencies in deterministic dependency order.
14
+
15
+
1
16
  ## [3.26.2] - 2026-05-14
2
17
 
3
18
  ### Fixed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: policyengine-core
3
- Version: 3.26.2
3
+ Version: 3.26.4
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>
@@ -37,8 +37,8 @@ class ParameterNodeMetadata:
37
37
  metadata:
38
38
  breakdown:
39
39
  - region # If `region` is an Enum-type variable with possible values `[ENGLAND, WALES]` then these children will be added.
40
- - range(1, 7) # This code is `eval`uated to produce the list `[1, 2, 3, 4, 5, 6]` which are then added as grandchildren.
41
- - [True, False] # This list is added as great-grandchildren (using the same `eval` method as above).
40
+ - range(1, 7) # Safe dynamic form producing `[1, 2, 3, 4, 5, 6]`, which are then added as grandchildren.
41
+ - [True, False] # Literal collection form added as great-grandchildren.
42
42
 
43
43
  """
44
44
 
@@ -10,6 +10,18 @@ from policyengine_core.periods import Period
10
10
  log = logging.getLogger(__name__)
11
11
 
12
12
 
13
+ def get_input_branch(holder: Holder) -> str:
14
+ simulation = getattr(holder, "simulation", None)
15
+ user_input_contexts = getattr(simulation, "_user_input_contexts", None)
16
+ if user_input_contexts:
17
+ return user_input_contexts[-1]
18
+ return "default"
19
+
20
+
21
+ def get_stored_array(holder: Holder, period: Period, branch_name: str) -> ArrayLike:
22
+ return holder._get_array_from_storage(period, branch_name)
23
+
24
+
13
25
  def set_input_dispatch_by_period(holder: Holder, period: Period, array: ArrayLike):
14
26
  """
15
27
  This function can be declared as a ``set_input`` attribute of a variable.
@@ -35,11 +47,12 @@ def set_input_dispatch_by_period(holder: Holder, period: Period, array: ArrayLik
35
47
  after_instant = period.start.offset(period_size, period_unit)
36
48
 
37
49
  # Cache the input data, skipping the existing cached months
50
+ branch_name = get_input_branch(holder)
38
51
  sub_period = period.start.period(cached_period_unit)
39
52
  while sub_period.start < after_instant:
40
- existing_array = holder.get_array(sub_period)
53
+ existing_array = get_stored_array(holder, sub_period, branch_name)
41
54
  if existing_array is None:
42
- holder._set(sub_period, array)
55
+ holder._set(sub_period, array, branch_name)
43
56
  else:
44
57
  # The array of the current sub-period is reused for the next ones.
45
58
  # TODO: refactor or document this behavior
@@ -72,11 +85,12 @@ def set_input_divide_by_period(holder: Holder, period: Period, array: ArrayLike)
72
85
  after_instant = period.start.offset(period_size, period_unit)
73
86
 
74
87
  # Count the number of elementary periods to change, and the difference with what is already known.
88
+ branch_name = get_input_branch(holder)
75
89
  remaining_array = array.copy()
76
90
  sub_period = period.start.period(cached_period_unit)
77
91
  sub_periods_count = 0
78
92
  while sub_period.start < after_instant:
79
- existing_array = holder.get_array(sub_period)
93
+ existing_array = get_stored_array(holder, sub_period, branch_name)
80
94
  if existing_array is not None:
81
95
  remaining_array -= existing_array
82
96
  else:
@@ -88,8 +102,8 @@ def set_input_divide_by_period(holder: Holder, period: Period, array: ArrayLike)
88
102
  divided_array = remaining_array / sub_periods_count
89
103
  sub_period = period.start.period(cached_period_unit)
90
104
  while sub_period.start < after_instant:
91
- if holder.get_array(sub_period) is None:
92
- holder._set(sub_period, divided_array)
105
+ if get_stored_array(holder, sub_period, branch_name) is None:
106
+ holder._set(sub_period, divided_array, branch_name)
93
107
  sub_period = sub_period.offset(1)
94
108
  elif not (remaining_array == 0).all():
95
109
  raise ValueError(
@@ -94,6 +94,14 @@ class Holder:
94
94
  if self._disk_storage:
95
95
  self._disk_storage.delete(period, branch_name)
96
96
 
97
+ def _get_array_from_storage(
98
+ self, period: Period, branch_name: str = "default"
99
+ ) -> ArrayLike:
100
+ value = self._memory_storage.get(period, branch_name)
101
+ if value is None and self._disk_storage:
102
+ value = self._disk_storage.get(period, branch_name)
103
+ return value
104
+
97
105
  def get_array(self, period: Period, branch_name: str = "default") -> ArrayLike:
98
106
  """
99
107
  Get the value of the variable for the given period.
@@ -102,7 +110,9 @@ class Holder:
102
110
  """
103
111
  if self.variable.is_neutralized:
104
112
  return self.default_array()
105
- value = self._memory_storage.get(period, branch_name)
113
+ value = self._get_array_from_storage(period, branch_name)
114
+ if value is not None:
115
+ return value
106
116
  if value is None and branch_name != "default":
107
117
  # Walk up ``simulation.parent_branch`` so nested branches inherit
108
118
  # values from their parent (e.g. a ``no_salt`` branch cloned
@@ -121,17 +131,16 @@ class Holder:
121
131
  else None
122
132
  )
123
133
  while parent is not None:
124
- ancestor_value = self._memory_storage.get(period, parent.branch_name)
134
+ ancestor_value = self._get_array_from_storage(
135
+ period,
136
+ parent.branch_name,
137
+ )
125
138
  if ancestor_value is not None:
126
139
  return ancestor_value
127
140
  parent = getattr(parent, "parent_branch", None)
128
- default_value = self._memory_storage.get(period, "default")
141
+ default_value = self._get_array_from_storage(period, "default")
129
142
  if default_value is not None:
130
143
  return default_value
131
- if value is not None:
132
- return value
133
- if self._disk_storage:
134
- return self._disk_storage.get(period, branch_name)
135
144
 
136
145
  def get_memory_usage(self) -> dict:
137
146
  """
@@ -241,21 +250,23 @@ class Holder:
241
250
  return warnings.warn(warning_message, Warning)
242
251
  if self.variable.value_type in (float, int) and isinstance(array, str):
243
252
  array = tools.eval_expression(array)
244
- # Track user-provided inputs on the simulation so
245
- # ``Simulation._invalidate_all_caches`` can preserve them across
246
- # ``apply_reform``. ``Simulation.set_input`` also records this, but
247
- # ``SimulationBuilder.finalize_variables_init`` (the situation-dict
248
- # path) and country-package dataset loaders call
249
- # ``holder.set_input`` directly, bypassing the simulation-level hook.
250
- # Recording here covers both paths.
251
253
  simulation = getattr(self, "simulation", None)
252
254
  if simulation is not None:
253
255
  if not hasattr(simulation, "_user_input_keys"):
254
256
  simulation._user_input_keys = set()
255
- simulation._user_input_keys.add((self.variable.name, branch_name, period))
256
- if self.variable.set_input and period.unit != self.variable.definition_period:
257
- return self.variable.set_input(self, period, array)
258
- return self._set(period, array, branch_name)
257
+ if not hasattr(simulation, "_user_input_contexts"):
258
+ simulation._user_input_contexts = []
259
+ simulation._user_input_contexts.append(branch_name)
260
+ try:
261
+ if (
262
+ self.variable.set_input
263
+ and period.unit != self.variable.definition_period
264
+ ):
265
+ return self.variable.set_input(self, period, array)
266
+ return self._set(period, array, branch_name)
267
+ finally:
268
+ if simulation is not None:
269
+ simulation._user_input_contexts.pop()
259
270
 
260
271
  def _to_array(self, value: Any) -> ArrayLike:
261
272
  if not isinstance(value, numpy.ndarray):
@@ -295,6 +306,10 @@ class Holder:
295
306
  def _set(
296
307
  self, period: Period, value: ArrayLike, branch_name: str = "default"
297
308
  ) -> None:
309
+ simulation = getattr(self, "simulation", None)
310
+ user_input_contexts = getattr(simulation, "_user_input_contexts", None)
311
+ if user_input_contexts and branch_name == "default":
312
+ branch_name = user_input_contexts[-1]
298
313
  value = self._to_array(value)
299
314
  if self.variable.definition_period != periods.ETERNITY:
300
315
  if period is None:
@@ -313,6 +328,10 @@ class Holder:
313
328
  self._disk_storage.put(value, period, branch_name)
314
329
  else:
315
330
  self._memory_storage.put(value, period, branch_name)
331
+ if user_input_contexts:
332
+ if not hasattr(simulation, "_user_input_keys"):
333
+ simulation._user_input_keys = set()
334
+ simulation._user_input_keys.add((self.variable.name, branch_name, period))
316
335
 
317
336
  def put_in_cache(
318
337
  self, value: ArrayLike, period: Period, branch_name: str = "default"
@@ -7,7 +7,7 @@ import yaml
7
7
  from policyengine_core.warnings import LibYAMLWarning
8
8
 
9
9
  try:
10
- from yaml import CLoader as Loader
10
+ from yaml import CSafeLoader as Loader
11
11
  except ImportError:
12
12
  message = [
13
13
  "libyaml is not installed in your environment.",
@@ -17,7 +17,7 @@ except ImportError:
17
17
  ]
18
18
  warnings.warn(" ".join(message), LibYAMLWarning)
19
19
  from yaml import (
20
- Loader,
20
+ SafeLoader as Loader,
21
21
  ) # type: ignore # (see https://github.com/python/mypy/issues/1153#issuecomment-455802270)
22
22
 
23
23
  ALLOWED_PARAM_TYPES = (float, int, bool, type(None), typing.List)
@@ -33,15 +33,30 @@ yaml.add_constructor("tag:yaml.org,2002:timestamp", date_constructor, Loader=Loa
33
33
 
34
34
 
35
35
  def dict_no_duplicate_constructor(loader, node, deep=False):
36
- keys = [key.value for key, value in node.value]
36
+ explicit_keys = {}
37
+ for key_node, _value_node in node.value:
38
+ if key_node.tag == "tag:yaml.org,2002:merge":
39
+ continue
40
+ key = loader.construct_object(key_node, deep=deep)
41
+ try:
42
+ if key in explicit_keys:
43
+ raise yaml.parser.ParserError(
44
+ "", node.start_mark, f"Found duplicate key '{key}'"
45
+ )
46
+ except TypeError as exc:
47
+ raise yaml.constructor.ConstructorError(
48
+ "", node.start_mark, f"Found unhashable key '{key}'"
49
+ ) from exc
50
+ explicit_keys[key] = True
37
51
 
38
- if len(keys) != len(set(keys)):
39
- duplicate = next((key for key in keys if keys.count(key) > 1))
40
- raise yaml.parser.ParserError(
41
- "", node.start_mark, f"Found duplicate key '{duplicate}'"
42
- )
52
+ loader.flatten_mapping(node)
53
+ pairs = loader.construct_pairs(node, deep=deep)
54
+ mapping = {}
43
55
 
44
- return loader.construct_mapping(node, deep)
56
+ for key, value in pairs:
57
+ mapping[key] = value
58
+
59
+ return mapping
45
60
 
46
61
 
47
62
  yaml.add_constructor(
@@ -1,3 +1,4 @@
1
+ import ast
1
2
  import logging
2
3
  from typing import Any, Dict, List, Type
3
4
 
@@ -6,6 +7,8 @@ from policyengine_core.parameters.parameter import Parameter
6
7
  from policyengine_core.parameters.parameter_node import ParameterNode
7
8
  from policyengine_core.variables import Variable
8
9
 
10
+ MAX_DYNAMIC_BREAKDOWN_VALUES = 10_000
11
+
9
12
 
10
13
  def homogenize_parameter_structures(
11
14
  root: ParameterNode, variables: Dict[str, Variable], default_value: Any = 0
@@ -43,6 +46,11 @@ def get_breakdown_variables(node: ParameterNode) -> List[str]:
43
46
  f"Invalid breakdown metadata for parameter {node.name}: {type(breakdown)}"
44
47
  )
45
48
  return None
49
+ if len(breakdown) == 0:
50
+ logging.warning(
51
+ f"Invalid breakdown metadata for parameter {node.name}: empty list"
52
+ )
53
+ return None
46
54
  return breakdown
47
55
  else:
48
56
  return None
@@ -71,8 +79,7 @@ def homogenize_parameter_node(
71
79
  elif dtype == bool:
72
80
  possible_values = [True, False]
73
81
  else:
74
- # Try to execute the breakdown as Python code
75
- possible_values = list(eval(first_breakdown))
82
+ possible_values = evaluate_dynamic_breakdown(first_breakdown)
76
83
  if not hasattr(node, "children"):
77
84
  node = ParameterNode(
78
85
  node.name,
@@ -119,3 +126,84 @@ def homogenize_parameter_node(
119
126
  node.children[child], breakdown[1:], variables, default_value
120
127
  )
121
128
  return node
129
+
130
+
131
+ def evaluate_dynamic_breakdown(expression: str) -> List[Any]:
132
+ """Safely evaluate a dynamic breakdown expression.
133
+
134
+ The parameter metadata only needs literal collections and the documented
135
+ ``range(...)`` / ``list(range(...))`` forms. Anything else is rejected.
136
+ """
137
+
138
+ parsed = ast.parse(expression, mode="eval")
139
+ evaluated = evaluate_dynamic_breakdown_node(parsed.body)
140
+ if isinstance(evaluated, range):
141
+ validate_dynamic_breakdown_range_cardinality(evaluated, expression)
142
+ return list(evaluated)
143
+ if isinstance(evaluated, (list, tuple)):
144
+ validate_dynamic_breakdown_cardinality(len(evaluated), expression)
145
+ return list(evaluated)
146
+ if isinstance(evaluated, set):
147
+ validate_dynamic_breakdown_cardinality(len(evaluated), expression)
148
+ return list(evaluated)
149
+ raise ValueError(
150
+ f"Invalid dynamic breakdown expression '{expression}'. "
151
+ "Only literal collections and range() calls are allowed."
152
+ )
153
+
154
+
155
+ def validate_dynamic_breakdown_cardinality(count: int, expression: str) -> None:
156
+ if count > MAX_DYNAMIC_BREAKDOWN_VALUES:
157
+ raise ValueError(
158
+ f"Dynamic breakdown expression '{expression}' produces {count} values, "
159
+ f"which exceeds the maximum of {MAX_DYNAMIC_BREAKDOWN_VALUES}."
160
+ )
161
+
162
+
163
+ def validate_dynamic_breakdown_range_cardinality(
164
+ values: range, expression: str
165
+ ) -> None:
166
+ try:
167
+ count = len(values)
168
+ except OverflowError as exc:
169
+ raise ValueError(
170
+ f"Dynamic breakdown expression '{expression}' produces too many values."
171
+ ) from exc
172
+ validate_dynamic_breakdown_cardinality(count, expression)
173
+
174
+
175
+ def evaluate_dynamic_breakdown_node(node: ast.AST) -> Any:
176
+ if isinstance(node, ast.Constant):
177
+ return node.value
178
+ if isinstance(node, ast.List):
179
+ validate_dynamic_breakdown_cardinality(len(node.elts), ast.unparse(node))
180
+ return [evaluate_dynamic_breakdown_node(element) for element in node.elts]
181
+ if isinstance(node, ast.Tuple):
182
+ validate_dynamic_breakdown_cardinality(len(node.elts), ast.unparse(node))
183
+ return tuple(evaluate_dynamic_breakdown_node(element) for element in node.elts)
184
+ if isinstance(node, ast.Set):
185
+ validate_dynamic_breakdown_cardinality(len(node.elts), ast.unparse(node))
186
+ return {evaluate_dynamic_breakdown_node(element) for element in node.elts}
187
+ if isinstance(node, ast.UnaryOp) and isinstance(node.op, (ast.UAdd, ast.USub)):
188
+ operand = evaluate_dynamic_breakdown_node(node.operand)
189
+ return operand if isinstance(node.op, ast.UAdd) else -operand
190
+ if isinstance(node, ast.Call) and isinstance(node.func, ast.Name):
191
+ if node.func.id == "range":
192
+ args = [evaluate_dynamic_breakdown_node(arg) for arg in node.args]
193
+ if node.keywords:
194
+ raise ValueError("range() keyword arguments are not allowed")
195
+ result = range(*args)
196
+ validate_dynamic_breakdown_range_cardinality(result, ast.unparse(node))
197
+ return result
198
+ if node.func.id == "list":
199
+ if len(node.args) != 1 or node.keywords:
200
+ raise ValueError("list() must contain a single positional argument")
201
+ evaluated = evaluate_dynamic_breakdown_node(node.args[0])
202
+ if isinstance(evaluated, (range, list, tuple, set)):
203
+ return evaluated
204
+ raise ValueError(
205
+ "list() only supports range() and literal collection expressions"
206
+ )
207
+ raise ValueError(
208
+ f"Unsupported dynamic breakdown expression: {ast.unparse(node) if hasattr(ast, 'unparse') else type(node).__name__}"
209
+ )