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