policyengine-core 3.26.2__tar.gz → 3.26.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/CHANGELOG.md +8 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/PKG-INFO +1 -1
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/holders/helpers.py +19 -5
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/holders/holder.py +37 -18
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/parameters/operations/uprate_parameters.py +171 -127
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/parameters/parameter_node.py +1 -1
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/parameters/parameter_scale_bracket.py +1 -1
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/simulations/simulation.py +40 -12
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/pyproject.toml +1 -1
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameters/operations/test_uprating.py +100 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_apply_reform_preserves_user_inputs.py +111 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_holder_branch_fallback.py +15 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/.github/ISSUE_TEMPLATE.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/.github/bump_version.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/.github/changelog_template.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/.github/get-changelog-diff.sh +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/.github/has-functional-changes.sh +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/.github/is-version-number-acceptable.sh +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/.github/publish-git-tag.sh +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/.github/workflows/pr.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/.github/workflows/push.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/.gitignore +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/.python-version +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/AGENTS.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/CLAUDE.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/CONTRIBUTING.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/LICENSE +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/MANIFEST.in +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/Makefile +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/README.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/_build/logs/myst.build.json +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/changelog.d/.gitkeep +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/_config.yml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/_static/style.css +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/_toc.yml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/add_plotly_to_book.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/contributing/intro.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/engineering/skills/README.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/engineering/skills/documentation_review.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/engineering/skills/github-prs.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/engineering/skills/testing.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/intro.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/logo.png +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/python_api/commons.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/python_api/country_template.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/python_api/data.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/python_api/data_storage.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/python_api/entities.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/python_api/enums.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/python_api/errors.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/python_api/experimental.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/python_api/extension_template.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/python_api/holders.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/python_api/parameters.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/python_api/periods.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/python_api/populations.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/python_api/projectors.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/python_api/reforms.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/python_api/scripts.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/python_api/simulations.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/python_api/taxbenefitsystems.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/python_api/taxscales.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/python_api/tools.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/python_api/tracers.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/python_api/types.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/python_api/variables.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/python_api/warnings.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/usage/country.ipynb +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/usage/datasets.ipynb +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/usage/parameters.md +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/usage/reforms.ipynb +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/docs/usage/simulation.ipynb +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/mypy.ini +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/build_metadata.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/charts/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/charts/api.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/charts/bar.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/charts/formatting.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/commons/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/commons/formulas.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/commons/misc.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/commons/rates.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/constants.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/data/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/data/datasets/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/data/datasets/country_template_dataset.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/entities.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/modelled_policies.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/parameters/benefits/basic_income.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/parameters/benefits/housing_allowance.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/parameters/benefits/index.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/parameters/benefits/parenting_allowance/amount.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/parameters/benefits/parenting_allowance/income_threshold.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/parameters/general/age_of_majority.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/parameters/general/age_of_retirement.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/parameters/taxes/housing_tax.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/parameters/taxes/income_tax_rate.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/parameters/taxes/social_security_contribution.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/reforms/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/reforms/add_dynamic_variable.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/reforms/add_new_tax.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/reforms/flat_social_security_contribution.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/reforms/modify_social_security_taxation.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/reforms/removal_basic_income.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/situation_examples/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/situation_examples/couple.json +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/situation_examples/housing.json +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/situation_examples/single.json +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/tests/age.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/tests/basic_income.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/tests/disposable_income.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/tests/housing_allowance.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/tests/housing_tax.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/tests/income_tax.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/tests/reforms/add_dynamic_variable.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/tests/reforms/add_new_tax.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/tests/reforms/modify_social_security_taxation.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/tests/situations/income_tax.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/tests/situations/parenting_allowance.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/tests/social_security_contribution.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/tests/test_microsimulation.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/variables/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/variables/benefits.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/variables/demographics.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/variables/housing.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/variables/ids.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/variables/income.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/variables/stats.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/country_template/variables/taxes.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/data/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/data/dataset.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/data_storage/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/data_storage/in_memory_storage.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/data_storage/on_disk_storage.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/data_structures/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/data_structures/parameter_metadata.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/data_structures/parameter_node_metadata.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/data_structures/reference.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/data_structures/unit.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/entities/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/entities/entity.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/entities/group_entity.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/entities/helpers.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/entities/role.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/enums/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/enums/config.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/enums/enum.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/enums/enum_array.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/errors/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/errors/cycle_error.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/errors/empty_argument_error.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/errors/nan_creation_error.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/errors/parameter_not_found_error.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/errors/parameter_parsing_error.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/errors/period_mismatch_error.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/errors/situation_parsing_error.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/errors/spiral_error.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/errors/variable_name_conflict_error.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/errors/variable_not_found_error.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/experimental/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/experimental/memory_config.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/extension_template/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/extension_template/local_benefit.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/extension_template/parameters/local_town/child_allowance/amount.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/extension_template/parameters/local_town/child_allowance/index.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/extension_template/parameters/local_town/index.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/extension_template/tests/local_benefit.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/holders/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/model_api.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/parameters/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/parameters/at_instant_like.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/parameters/config.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/parameters/helpers.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/parameters/operations/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/parameters/operations/get_parameter.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/parameters/operations/homogenize_parameters.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/parameters/operations/interpolate_parameters.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/parameters/operations/propagate_parameter_metadata.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/parameters/parameter.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/parameters/parameter_at_instant.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/parameters/parameter_node_at_instant.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/parameters/parameter_scale.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/parameters/vectorial_parameter_node_at_instant.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/periods/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/periods/config.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/periods/helpers.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/periods/instant_.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/periods/period_.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/populations/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/populations/config.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/populations/group_population.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/populations/population.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/projectors/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/projectors/entity_to_person_projector.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/projectors/first_person_to_entity_projector.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/projectors/helpers.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/projectors/projector.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/projectors/unique_role_to_entity_projector.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/reforms/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/reforms/reform.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/scripts/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/scripts/assets/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/scripts/assets/index.html +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/scripts/policyengine_command.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/scripts/run_data.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/scripts/run_test.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/scripts/simulation_generator.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/simulations/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/simulations/helpers.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/simulations/individual_sim.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/simulations/microsimulation.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/simulations/simulation_builder.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/simulations/simulation_macro_cache.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/taxbenefitsystems/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/taxbenefitsystems/tax_benefit_system.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/taxscales/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/taxscales/abstract_rate_tax_scale.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/taxscales/abstract_tax_scale.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/taxscales/amount_tax_scale_like.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/taxscales/helpers.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/taxscales/linear_average_rate_tax_scale.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/taxscales/marginal_amount_tax_scale.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/taxscales/marginal_rate_tax_scale.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/taxscales/rate_tax_scale_like.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/taxscales/single_amount_tax_scale.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/taxscales/tax_scale_like.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/tools/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/tools/google_cloud.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/tools/hugging_face.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/tools/simulation_dumper.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/tools/test_from_situation.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/tools/test_runner.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/tools/win_file_manager.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/tracers/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/tracers/computation_log.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/tracers/flat_trace.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/tracers/full_tracer.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/tracers/performance_log.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/tracers/simple_tracer.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/tracers/trace_node.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/tracers/tracing_parameter_node_at_instant.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/tracers/variable_graph.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/types/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/types/data_types/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/types/data_types/arrays.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/variables/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/variables/config.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/variables/defined_for.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/variables/helpers.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/variables/typing.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/variables/variable.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/warnings/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/warnings/libyaml_warning.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/warnings/memory_config_warning.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/warnings/tempfile_warning.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/pytest.ini +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/test.ipynb +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/conftest.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/commons/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/commons/test_between_function.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/commons/test_formulas.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/commons/test_is_in_function.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/commons/test_random_seed.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/commons/test_rates.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/data/test_dataset.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/enums/test_enum.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/model_api/test_index_.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameter_validation/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameter_validation/array_type.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameter_validation/duplicate_key.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameter_validation/filesystem_hierarchy/empty_index_file/index.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameter_validation/filesystem_hierarchy/node1/param.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameter_validation/indentation.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameter_validation/missing_value.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameter_validation/parameter_for_unit_propagation.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameter_validation/test_parameter_clone.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameter_validation/test_parameter_validation.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameter_validation/test_propagate_units.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameter_validation/unexpected_key_in_parameter.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameter_validation/unexpected_key_in_scale.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameter_validation/unexpected_key_in_value_at_instant.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameter_validation/unexpected_key_in_value_history.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameter_validation/wrong_date.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameter_validation/wrong_scale.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameter_validation/wrong_type_in_bracket.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameter_validation/wrong_type_in_brackets.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameter_validation/wrong_type_in_parameter.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameter_validation/wrong_type_in_scale.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameter_validation/wrong_type_in_value_history.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameter_validation/wrong_value.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameter_validation/yaml_hierarchy/node1.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameters/operations/test_interpolation.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameters/operations/test_nesting.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameters/operations/test_propagation.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameters/test_numpy2_structured_arrays.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameters_fancy_indexing/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameters_fancy_indexing/bareme.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameters_fancy_indexing/local_tax.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameters_fancy_indexing/rate.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/parameters_fancy_indexing/test_fancy_indexing.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/tax_scales/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/tax_scales/test_abstract_rate_tax_scale.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/tax_scales/test_abstract_tax_scale.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/tax_scales/test_linear_average_rate_tax_scale.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/tax_scales/test_marginal_amount_tax_scale.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/tax_scales/test_marginal_rate_tax_scale.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/tax_scales/test_rate_tax_scale_like.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/tax_scales/test_single_amount_tax_scale.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/tax_scales/test_tax_scales_commons.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_apply_reform_invalidates_cache.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_assert_near_precision.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_axes.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_bincount_minlength.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_build_metadata.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_calculate_output.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_countries.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_cycles.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_dataset_getattr.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_dump_restore.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_entities.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_eternity_subperiods.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_extensions.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_fast_cache.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_fast_cache_guards.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_formulas.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_holders.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_macro_cache_not_singleton.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_medium_fixes.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_microsimulation_person_accessor.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_opt_out_cache.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_pandas3_compatibility.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_parameters.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_periods.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_projectors.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_reform_parameter_isolation.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_reforms.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_simulation_builder.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_simulations.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_stable_hash_seed.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_storage_delete_branch.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_subsample_invalidates_cache.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_tax_benefit_system_cache_identity.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_tracers.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/test_yaml.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/tools/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/tools/test_assert_near.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/tools/test_google_cloud.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/tools/test_hugging_face.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/tools/test_runner/test_yaml_runner.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/variables/test_adds.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/variables/test_annualize.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/variables/test_bounds.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/variables/test_defined_for.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/variables/test_subtracts.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/variables/test_subtracts_sign.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/core/variables/test_variables.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/fixtures/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/fixtures/appclient.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/fixtures/entities.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/fixtures/simulations.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/fixtures/taxbenefitsystems.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/fixtures/variables.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/fixtures/yaml_tests/__init__.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/fixtures/yaml_tests/directory/subdirectory/test_4.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/fixtures/yaml_tests/directory/test_1.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/fixtures/yaml_tests/directory/test_2.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/fixtures/yaml_tests/failing_test_absolute_error_margin.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/fixtures/yaml_tests/failing_test_relative_error_margin.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/fixtures/yaml_tests/test_absolute_error_margin.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/fixtures/yaml_tests/test_failure.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/fixtures/yaml_tests/test_name_filter.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/fixtures/yaml_tests/test_relative_error_margin.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/fixtures/yaml_tests/test_success.yml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/fixtures/yaml_tests/test_with_anchors.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/fixtures/yaml_tests/test_with_extension.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/fixtures/yaml_tests/test_with_reform.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/fixtures/yaml_tests/test_with_reform_2.yaml +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/smoke/test_country_init.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/tests/smoke/test_us.py +0 -0
- {policyengine_core-3.26.2 → policyengine_core-3.26.3}/uv.lock +0 -0
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## [3.26.3] - 2026-05-14
|
|
2
|
+
|
|
3
|
+
### Fixed
|
|
4
|
+
|
|
5
|
+
- Preserve values passed through dispatched `set_input` handlers across cache invalidation.
|
|
6
|
+
- Apply chained parameter uprating dependencies in deterministic dependency order.
|
|
7
|
+
|
|
8
|
+
|
|
1
9
|
## [3.26.2] - 2026-05-14
|
|
2
10
|
|
|
3
11
|
### Fixed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: policyengine-core
|
|
3
|
-
Version: 3.26.
|
|
3
|
+
Version: 3.26.3
|
|
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>
|
|
@@ -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
|
|
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
|
|
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
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
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"
|
|
@@ -6,6 +6,7 @@ from dateutil import rrule
|
|
|
6
6
|
from dateutil.relativedelta import relativedelta
|
|
7
7
|
from dateutil.parser import parse
|
|
8
8
|
from datetime import datetime
|
|
9
|
+
from typing import Optional, Union
|
|
9
10
|
|
|
10
11
|
from policyengine_core.parameters.operations.get_parameter import get_parameter
|
|
11
12
|
from policyengine_core.parameters.parameter import Parameter
|
|
@@ -13,8 +14,7 @@ from policyengine_core.parameters.parameter_at_instant import (
|
|
|
13
14
|
ParameterAtInstant,
|
|
14
15
|
)
|
|
15
16
|
from policyengine_core.parameters.parameter_node import ParameterNode
|
|
16
|
-
from policyengine_core.
|
|
17
|
-
from policyengine_core.periods import instant, Instant
|
|
17
|
+
from policyengine_core.periods import instant
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
def uprate_parameters(root: ParameterNode) -> ParameterNode:
|
|
@@ -27,135 +27,179 @@ def uprate_parameters(root: ParameterNode) -> ParameterNode:
|
|
|
27
27
|
ParameterNode: The same root, with uprating applied to descendants.
|
|
28
28
|
"""
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
for allowed_key in bracket._allowed_keys:
|
|
36
|
-
if hasattr(bracket, allowed_key):
|
|
37
|
-
descendants.append(getattr(bracket, allowed_key))
|
|
38
|
-
|
|
39
|
-
for parameter in descendants:
|
|
40
|
-
if isinstance(parameter, Parameter):
|
|
41
|
-
if parameter.metadata.get("uprating") is not None:
|
|
42
|
-
# Pull the uprating definition dict
|
|
43
|
-
meta = parameter.metadata["uprating"]
|
|
44
|
-
|
|
45
|
-
# If defined in short method (i.e. "uprating: PARAM"),
|
|
46
|
-
# redefine this as dict with param key
|
|
47
|
-
if meta == "self":
|
|
48
|
-
meta = dict(parameter="self")
|
|
49
|
-
elif isinstance(meta, str):
|
|
50
|
-
meta = dict(parameter=meta)
|
|
51
|
-
|
|
52
|
-
# If param is "self", construct the uprating table
|
|
53
|
-
if meta["parameter"] == "self":
|
|
54
|
-
uprating_parameter = construct_uprater_self(
|
|
55
|
-
parameter,
|
|
56
|
-
meta,
|
|
57
|
-
)
|
|
58
|
-
# Otherwise, pull uprating table from YAML
|
|
59
|
-
else:
|
|
60
|
-
uprating_parameter = get_parameter(root, meta["parameter"])
|
|
61
|
-
|
|
62
|
-
# If uprating with a set candence, ensure that all
|
|
63
|
-
# required values are present
|
|
64
|
-
cadence_meta = meta.get("at_defined_interval")
|
|
65
|
-
cadence_options = {}
|
|
66
|
-
if cadence_meta:
|
|
67
|
-
cadence_options_test = [
|
|
68
|
-
cadence_meta.get("start"),
|
|
69
|
-
cadence_meta.get("end"),
|
|
70
|
-
cadence_meta.get("enactment"),
|
|
71
|
-
]
|
|
72
|
-
|
|
73
|
-
# Ensure that all options are properly defined
|
|
74
|
-
if not all(cadence_options_test):
|
|
75
|
-
raise SyntaxError(
|
|
76
|
-
f"Failed to uprate {parameter.name} using cadence; start, end, and enactment must all be provided"
|
|
77
|
-
)
|
|
78
|
-
|
|
79
|
-
# Construct cadence options object
|
|
80
|
-
cadence_options = construct_cadence_options(cadence_meta, parameter)
|
|
81
|
-
|
|
82
|
-
# Ensure that end comes after start and enactment comes after end
|
|
83
|
-
if cadence_options["end"] <= cadence_options["start"]:
|
|
84
|
-
raise ValueError(
|
|
85
|
-
f"Failed to uprate {parameter.name} using {uprating_parameter.name}: end must come after start"
|
|
86
|
-
)
|
|
87
|
-
if cadence_options["enactment"] <= cadence_options["end"]:
|
|
88
|
-
raise ValueError(
|
|
89
|
-
f"Failed to uprate {parameter.name} using {uprating_parameter.name}: enactment must come after end"
|
|
90
|
-
)
|
|
91
|
-
|
|
92
|
-
# Determine the first date from which to start uprating -
|
|
93
|
-
# this should be the first application date (month, day)
|
|
94
|
-
# following the last defined param value (not including the
|
|
95
|
-
# final value)
|
|
96
|
-
uprating_first_date: datetime = find_cadence_first(
|
|
97
|
-
parameter, cadence_options
|
|
98
|
-
)
|
|
99
|
-
uprating_last_date: datetime = find_cadence_last(
|
|
100
|
-
uprating_parameter, cadence_options
|
|
101
|
-
)
|
|
102
|
-
|
|
103
|
-
# Uprate data
|
|
104
|
-
uprated_data = uprate_by_cadence(
|
|
105
|
-
parameter,
|
|
106
|
-
uprating_parameter,
|
|
107
|
-
cadence_options,
|
|
108
|
-
uprating_first_date,
|
|
109
|
-
uprating_last_date,
|
|
110
|
-
meta,
|
|
111
|
-
)
|
|
30
|
+
parameters = [
|
|
31
|
+
parameter
|
|
32
|
+
for parameter in root.get_descendants()
|
|
33
|
+
if isinstance(parameter, Parameter)
|
|
34
|
+
]
|
|
112
35
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
else:
|
|
117
|
-
# Start from the latest value
|
|
118
|
-
if "start_instant" in meta:
|
|
119
|
-
last_instant = instant(meta["start_instant"])
|
|
120
|
-
else:
|
|
121
|
-
last_instant = instant(parameter.values_list[0].instant_str)
|
|
122
|
-
|
|
123
|
-
# Pre-compute values that don't change in the loop
|
|
124
|
-
last_instant_str = str(last_instant)
|
|
125
|
-
value_at_start = parameter(last_instant)
|
|
126
|
-
uprater_at_start = uprating_parameter(last_instant)
|
|
127
|
-
|
|
128
|
-
if uprater_at_start is None:
|
|
129
|
-
raise ValueError(
|
|
130
|
-
f"Failed to uprate using {uprating_parameter.name} at {last_instant} for {parameter.name} because the uprating parameter is not defined at {last_instant}."
|
|
131
|
-
)
|
|
132
|
-
|
|
133
|
-
# Pre-compute uprater values for all entries to avoid repeated lookups
|
|
134
|
-
has_rounding = "rounding" in meta
|
|
135
|
-
|
|
136
|
-
# For each defined instant in the uprating parameter
|
|
137
|
-
for entry in uprating_parameter.values_list[::-1]:
|
|
138
|
-
entry_instant = instant(entry.instant_str)
|
|
139
|
-
# If the uprater instant is defined after the last parameter instant
|
|
140
|
-
if entry_instant > last_instant:
|
|
141
|
-
# Apply the uprater and add to the parameter
|
|
142
|
-
uprater_at_entry = uprating_parameter(entry_instant)
|
|
143
|
-
uprater_change = uprater_at_entry / uprater_at_start
|
|
144
|
-
uprated_value = value_at_start * uprater_change
|
|
145
|
-
if has_rounding:
|
|
146
|
-
uprated_value = round_uprated_value(meta, uprated_value)
|
|
147
|
-
parameter.values_list.append(
|
|
148
|
-
ParameterAtInstant(
|
|
149
|
-
parameter.name,
|
|
150
|
-
entry.instant_str,
|
|
151
|
-
data=uprated_value,
|
|
152
|
-
)
|
|
153
|
-
)
|
|
154
|
-
# Whether using cadence or not, sort the parameter values_list
|
|
155
|
-
parameter.values_list.sort(key=lambda x: x.instant_str, reverse=True)
|
|
36
|
+
for parameter in sort_parameters_by_uprating_dependencies(parameters):
|
|
37
|
+
uprate_parameter(parameter, root)
|
|
156
38
|
return root
|
|
157
39
|
|
|
158
40
|
|
|
41
|
+
def normalize_uprating_metadata(meta: Union[dict, str]) -> dict:
|
|
42
|
+
if meta == "self":
|
|
43
|
+
return dict(parameter="self")
|
|
44
|
+
if isinstance(meta, str):
|
|
45
|
+
return dict(parameter=meta)
|
|
46
|
+
return meta
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def get_uprating_dependency_name(parameter: Parameter) -> Optional[str]:
|
|
50
|
+
meta = parameter.metadata.get("uprating")
|
|
51
|
+
if meta is None:
|
|
52
|
+
return None
|
|
53
|
+
meta = normalize_uprating_metadata(meta)
|
|
54
|
+
dependency_name = meta["parameter"]
|
|
55
|
+
if dependency_name == "self":
|
|
56
|
+
return None
|
|
57
|
+
return dependency_name
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def sort_parameters_by_uprating_dependencies(
|
|
61
|
+
parameters: list[Parameter],
|
|
62
|
+
) -> list[Parameter]:
|
|
63
|
+
parameters_to_uprate = [
|
|
64
|
+
parameter
|
|
65
|
+
for parameter in parameters
|
|
66
|
+
if parameter.metadata.get("uprating") is not None
|
|
67
|
+
]
|
|
68
|
+
parameter_by_name = {
|
|
69
|
+
parameter.name: parameter for parameter in parameters_to_uprate
|
|
70
|
+
}
|
|
71
|
+
ordered_parameters = []
|
|
72
|
+
visited = set()
|
|
73
|
+
visiting = []
|
|
74
|
+
|
|
75
|
+
def visit(parameter: Parameter):
|
|
76
|
+
if parameter.name in visited:
|
|
77
|
+
return
|
|
78
|
+
if parameter.name in visiting:
|
|
79
|
+
cycle = visiting[visiting.index(parameter.name) :] + [parameter.name]
|
|
80
|
+
raise ValueError(
|
|
81
|
+
"Cyclic uprating dependency detected: " + " -> ".join(cycle)
|
|
82
|
+
)
|
|
83
|
+
visiting.append(parameter.name)
|
|
84
|
+
dependency_name = get_uprating_dependency_name(parameter)
|
|
85
|
+
if dependency_name in parameter_by_name:
|
|
86
|
+
visit(parameter_by_name[dependency_name])
|
|
87
|
+
visiting.pop()
|
|
88
|
+
visited.add(parameter.name)
|
|
89
|
+
ordered_parameters.append(parameter)
|
|
90
|
+
|
|
91
|
+
for parameter in sorted(parameters_to_uprate, key=lambda p: p.name):
|
|
92
|
+
visit(parameter)
|
|
93
|
+
|
|
94
|
+
return ordered_parameters
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def uprate_parameter(parameter: Parameter, root: ParameterNode) -> None:
|
|
98
|
+
# Pull the uprating definition dict
|
|
99
|
+
meta = normalize_uprating_metadata(parameter.metadata["uprating"])
|
|
100
|
+
|
|
101
|
+
# If param is "self", construct the uprating table
|
|
102
|
+
if meta["parameter"] == "self":
|
|
103
|
+
uprating_parameter = construct_uprater_self(
|
|
104
|
+
parameter,
|
|
105
|
+
meta,
|
|
106
|
+
)
|
|
107
|
+
# Otherwise, pull uprating table from YAML
|
|
108
|
+
else:
|
|
109
|
+
uprating_parameter = get_parameter(root, meta["parameter"])
|
|
110
|
+
|
|
111
|
+
# If uprating with a set candence, ensure that all
|
|
112
|
+
# required values are present
|
|
113
|
+
cadence_meta = meta.get("at_defined_interval")
|
|
114
|
+
cadence_options = {}
|
|
115
|
+
if cadence_meta:
|
|
116
|
+
cadence_options_test = [
|
|
117
|
+
cadence_meta.get("start"),
|
|
118
|
+
cadence_meta.get("end"),
|
|
119
|
+
cadence_meta.get("enactment"),
|
|
120
|
+
]
|
|
121
|
+
|
|
122
|
+
# Ensure that all options are properly defined
|
|
123
|
+
if not all(cadence_options_test):
|
|
124
|
+
raise SyntaxError(
|
|
125
|
+
f"Failed to uprate {parameter.name} using cadence; start, end, and enactment must all be provided"
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
# Construct cadence options object
|
|
129
|
+
cadence_options = construct_cadence_options(cadence_meta, parameter)
|
|
130
|
+
|
|
131
|
+
# Ensure that end comes after start and enactment comes after end
|
|
132
|
+
if cadence_options["end"] <= cadence_options["start"]:
|
|
133
|
+
raise ValueError(
|
|
134
|
+
f"Failed to uprate {parameter.name} using {uprating_parameter.name}: end must come after start"
|
|
135
|
+
)
|
|
136
|
+
if cadence_options["enactment"] <= cadence_options["end"]:
|
|
137
|
+
raise ValueError(
|
|
138
|
+
f"Failed to uprate {parameter.name} using {uprating_parameter.name}: enactment must come after end"
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
# Determine the first date from which to start uprating -
|
|
142
|
+
# this should be the first application date (month, day)
|
|
143
|
+
# following the last defined param value (not including the
|
|
144
|
+
# final value)
|
|
145
|
+
uprating_first_date: datetime = find_cadence_first(parameter, cadence_options)
|
|
146
|
+
uprating_last_date: datetime = find_cadence_last(
|
|
147
|
+
uprating_parameter, cadence_options
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
# Uprate data
|
|
151
|
+
uprated_data = uprate_by_cadence(
|
|
152
|
+
parameter,
|
|
153
|
+
uprating_parameter,
|
|
154
|
+
cadence_options,
|
|
155
|
+
uprating_first_date,
|
|
156
|
+
uprating_last_date,
|
|
157
|
+
meta,
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
# Append uprated data to parameter values list
|
|
161
|
+
parameter.values_list.extend(uprated_data)
|
|
162
|
+
|
|
163
|
+
else:
|
|
164
|
+
# Start from the latest value
|
|
165
|
+
if "start_instant" in meta:
|
|
166
|
+
last_instant = instant(meta["start_instant"])
|
|
167
|
+
else:
|
|
168
|
+
last_instant = instant(parameter.values_list[0].instant_str)
|
|
169
|
+
|
|
170
|
+
# Pre-compute values that don't change in the loop
|
|
171
|
+
value_at_start = parameter(last_instant)
|
|
172
|
+
uprater_at_start = uprating_parameter(last_instant)
|
|
173
|
+
|
|
174
|
+
if uprater_at_start is None:
|
|
175
|
+
raise ValueError(
|
|
176
|
+
f"Failed to uprate using {uprating_parameter.name} at {last_instant} for {parameter.name} because the uprating parameter is not defined at {last_instant}."
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
has_rounding = "rounding" in meta
|
|
180
|
+
|
|
181
|
+
# For each defined instant in the uprating parameter
|
|
182
|
+
for entry in uprating_parameter.values_list[::-1]:
|
|
183
|
+
entry_instant = instant(entry.instant_str)
|
|
184
|
+
# If the uprater instant is defined after the last parameter instant
|
|
185
|
+
if entry_instant > last_instant:
|
|
186
|
+
# Apply the uprater and add to the parameter
|
|
187
|
+
uprater_at_entry = uprating_parameter(entry_instant)
|
|
188
|
+
uprater_change = uprater_at_entry / uprater_at_start
|
|
189
|
+
uprated_value = value_at_start * uprater_change
|
|
190
|
+
if has_rounding:
|
|
191
|
+
uprated_value = round_uprated_value(meta, uprated_value)
|
|
192
|
+
parameter.values_list.append(
|
|
193
|
+
ParameterAtInstant(
|
|
194
|
+
parameter.name,
|
|
195
|
+
entry.instant_str,
|
|
196
|
+
data=uprated_value,
|
|
197
|
+
)
|
|
198
|
+
)
|
|
199
|
+
# Whether using cadence or not, sort the parameter values_list
|
|
200
|
+
parameter.values_list.sort(key=lambda x: x.instant_str, reverse=True)
|
|
201
|
+
|
|
202
|
+
|
|
159
203
|
def round_uprated_value(meta: dict, uprated_value: float) -> float:
|
|
160
204
|
rounding_config = meta["rounding"]
|
|
161
205
|
if isinstance(rounding_config, float):
|
{policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/parameters/parameter_node.py
RENAMED
|
@@ -89,7 +89,7 @@ class ParameterNode(AtInstantLike):
|
|
|
89
89
|
|
|
90
90
|
if directory_path:
|
|
91
91
|
self.file_path = directory_path
|
|
92
|
-
for child_name in os.listdir(directory_path):
|
|
92
|
+
for child_name in sorted(os.listdir(directory_path)):
|
|
93
93
|
child_path = os.path.join(directory_path, child_name)
|
|
94
94
|
if os.path.isfile(child_path):
|
|
95
95
|
child_name, ext = os.path.splitext(child_name)
|
|
@@ -7,7 +7,7 @@ class ParameterScaleBracket(ParameterNode):
|
|
|
7
7
|
A parameter scale bracket.
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
|
-
_allowed_keys =
|
|
10
|
+
_allowed_keys = ("amount", "threshold", "rate", "average_rate", "base")
|
|
11
11
|
|
|
12
12
|
@staticmethod
|
|
13
13
|
def allowed_unit_keys():
|
{policyengine_core-3.26.2 → policyengine_core-3.26.3}/policyengine_core/simulations/simulation.py
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import hashlib
|
|
2
2
|
import tempfile
|
|
3
3
|
from dataclasses import dataclass
|
|
4
|
-
from typing import TYPE_CHECKING, Any, Dict, List, Type, Union
|
|
4
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Type, Union
|
|
5
5
|
|
|
6
6
|
import numpy as np
|
|
7
7
|
import pandas as pd
|
|
@@ -64,6 +64,10 @@ class PreservedUserInput:
|
|
|
64
64
|
branch_name: str
|
|
65
65
|
period: Period
|
|
66
66
|
value: object
|
|
67
|
+
storage: str
|
|
68
|
+
disk_key: Optional[str] = None
|
|
69
|
+
disk_file: Optional[str] = None
|
|
70
|
+
disk_enum: object = None
|
|
67
71
|
|
|
68
72
|
|
|
69
73
|
class Simulation:
|
|
@@ -297,8 +301,31 @@ class Simulation:
|
|
|
297
301
|
branch_name=branch_name,
|
|
298
302
|
period=period,
|
|
299
303
|
value=stored_value,
|
|
304
|
+
storage="memory",
|
|
300
305
|
)
|
|
301
306
|
)
|
|
307
|
+
continue
|
|
308
|
+
if holder._disk_storage is not None:
|
|
309
|
+
disk_period = (
|
|
310
|
+
periods.period(periods.ETERNITY)
|
|
311
|
+
if holder._disk_storage.is_eternal
|
|
312
|
+
else periods.period(period)
|
|
313
|
+
)
|
|
314
|
+
disk_key = f"{branch_name}_{disk_period}"
|
|
315
|
+
disk_file = holder._disk_storage._files.get(disk_key)
|
|
316
|
+
if disk_file is not None:
|
|
317
|
+
preserved.append(
|
|
318
|
+
PreservedUserInput(
|
|
319
|
+
variable_name=variable_name,
|
|
320
|
+
branch_name=branch_name,
|
|
321
|
+
period=period,
|
|
322
|
+
value=None,
|
|
323
|
+
storage="disk",
|
|
324
|
+
disk_key=disk_key,
|
|
325
|
+
disk_file=disk_file,
|
|
326
|
+
disk_enum=holder._disk_storage._enums.get(disk_file),
|
|
327
|
+
)
|
|
328
|
+
)
|
|
302
329
|
# Iterate only over holders that already exist on each population —
|
|
303
330
|
# lazy-creating a holder for every variable in the tax-benefit
|
|
304
331
|
# system (thousands in policyengine-us) inflated the cost of
|
|
@@ -313,11 +340,18 @@ class Simulation:
|
|
|
313
340
|
# Replay preserved user inputs so ``calculate`` still sees them.
|
|
314
341
|
for user_input in preserved:
|
|
315
342
|
holder = self.get_holder(user_input.variable_name)
|
|
316
|
-
holder.
|
|
317
|
-
user_input.
|
|
318
|
-
user_input.
|
|
319
|
-
|
|
320
|
-
|
|
343
|
+
if user_input.storage == "disk" and holder._disk_storage is not None:
|
|
344
|
+
holder._disk_storage._files[user_input.disk_key] = user_input.disk_file
|
|
345
|
+
if user_input.disk_enum is not None:
|
|
346
|
+
holder._disk_storage._enums[user_input.disk_file] = (
|
|
347
|
+
user_input.disk_enum
|
|
348
|
+
)
|
|
349
|
+
else:
|
|
350
|
+
holder._memory_storage.put(
|
|
351
|
+
user_input.value,
|
|
352
|
+
user_input.period,
|
|
353
|
+
user_input.branch_name,
|
|
354
|
+
)
|
|
321
355
|
for branch in self.branches.values():
|
|
322
356
|
branch._invalidate_all_caches()
|
|
323
357
|
|
|
@@ -1302,12 +1336,6 @@ class Simulation:
|
|
|
1302
1336
|
if (variable.end is not None) and (period.start.date > variable.end):
|
|
1303
1337
|
return
|
|
1304
1338
|
self.get_holder(variable_name).set_input(period, value, self.branch_name)
|
|
1305
|
-
# Lazy-init ``_user_input_keys`` so country-package subclasses that
|
|
1306
|
-
# override ``__init__`` without calling ``super().__init__`` still
|
|
1307
|
-
# benefit from the set-input preservation across ``apply_reform``.
|
|
1308
|
-
if not hasattr(self, "_user_input_keys"):
|
|
1309
|
-
self._user_input_keys = set()
|
|
1310
|
-
self._user_input_keys.add((variable_name, self.branch_name, period))
|
|
1311
1339
|
_fast_cache = getattr(self, "_fast_cache", None)
|
|
1312
1340
|
if _fast_cache is not None:
|
|
1313
1341
|
_fast_cache.pop((variable_name, period), None)
|