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