OpenFisca-Core 44.3.0__tar.gz → 44.6.0__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.
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/CHANGELOG.md +5 -11
- {openfisca_core-44.3.0 → openfisca_core-44.6.0/OpenFisca_Core.egg-info}/PKG-INFO +1 -1
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/OpenFisca_Core.egg-info/SOURCES.txt +0 -13
- {openfisca_core-44.3.0/OpenFisca_Core.egg-info → openfisca_core-44.6.0}/PKG-INFO +1 -1
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/entities/_core_entity.py +0 -40
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/indexed_enums/enum_array.py +4 -2
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/populations/group_population.py +15 -68
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/populations/population.py +5 -7
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/simulations/simulation.py +0 -48
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/taxscales/abstract_rate_tax_scale.py +1 -1
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/taxscales/abstract_tax_scale.py +2 -2
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/taxscales/tax_scale_like.py +2 -2
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/pyproject.toml +1 -1
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/setup.py +1 -1
- openfisca_core-44.3.0/openfisca_core/links/__init__.py +0 -36
- openfisca_core-44.3.0/openfisca_core/links/implicit.py +0 -73
- openfisca_core-44.3.0/openfisca_core/links/link.py +0 -109
- openfisca_core-44.3.0/openfisca_core/links/many2one.py +0 -227
- openfisca_core-44.3.0/openfisca_core/links/one2many.py +0 -242
- openfisca_core-44.3.0/openfisca_core/links/tests/__init__.py +0 -58
- openfisca_core-44.3.0/openfisca_core/links/tests/test_benchmark.py +0 -93
- openfisca_core-44.3.0/openfisca_core/links/tests/test_edge_cases.py +0 -467
- openfisca_core-44.3.0/openfisca_core/links/tests/test_implicit.py +0 -76
- openfisca_core-44.3.0/openfisca_core/links/tests/test_integration.py +0 -192
- openfisca_core-44.3.0/openfisca_core/links/tests/test_many2one.py +0 -121
- openfisca_core-44.3.0/openfisca_core/links/tests/test_one2many.py +0 -112
- openfisca_core-44.3.0/openfisca_core/links/tests/test_one2many_logic.py +0 -398
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/LICENSE +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/MANIFEST.in +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/OpenFisca_Core.egg-info/dependency_links.txt +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/OpenFisca_Core.egg-info/entry_points.txt +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/OpenFisca_Core.egg-info/requires.txt +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/OpenFisca_Core.egg-info/top_level.txt +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/README.md +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/commons/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/commons/dummy.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/commons/formulas.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/commons/misc.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/commons/py.typed +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/commons/rates.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/commons/tests/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/commons/tests/test_dummy.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/commons/tests/test_formulas.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/commons/tests/test_rates.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/data_storage/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/data_storage/in_memory_storage.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/data_storage/on_disk_storage.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/data_storage/types.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/entities/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/entities/_description.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/entities/entity.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/entities/group_entity.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/entities/helpers.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/entities/py.typed +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/entities/role.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/entities/tests/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/entities/tests/test_entity.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/entities/tests/test_group_entity.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/entities/tests/test_role.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/entities/types.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/errors/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/errors/cycle_error.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/errors/empty_argument_error.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/errors/nan_creation_error.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/errors/parameter_not_found_error.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/errors/parameter_parsing_error.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/errors/period_mismatch_error.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/errors/situation_parsing_error.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/errors/spiral_error.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/errors/variable_name_config_error.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/errors/variable_not_found_error.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/experimental/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/experimental/_errors.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/experimental/_memory_config.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/formula_helpers.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/holders/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/holders/helpers.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/holders/holder.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/holders/tests/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/holders/tests/test_helpers.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/holders/types.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/indexed_enums/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/indexed_enums/_enum_type.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/indexed_enums/_errors.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/indexed_enums/_guards.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/indexed_enums/_utils.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/indexed_enums/config.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/indexed_enums/enum.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/indexed_enums/py.typed +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/indexed_enums/tests/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/indexed_enums/tests/test_enum.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/indexed_enums/tests/test_enum_array.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/indexed_enums/types.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/memory_config.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/model_api.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/parameters/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/parameters/at_instant_like.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/parameters/config.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/parameters/helpers.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/parameters/parameter.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/parameters/parameter_at_instant.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/parameters/parameter_node.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/parameters/parameter_node_at_instant.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/parameters/parameter_scale.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/parameters/parameter_scale_bracket.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/parameters/values_history.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/parameters/vectorial_parameter_node_at_instant.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/_errors.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/_parsers.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/config.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/date_unit.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/helpers.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/instant_.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/period_.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/py.typed +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/tests/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/tests/helpers/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/tests/helpers/test_helpers.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/tests/helpers/test_instant.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/tests/helpers/test_period.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/tests/test_instant.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/tests/test_parsers.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/periods/tests/test_period.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/populations/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/populations/_core_population.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/populations/_errors.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/populations/tests/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/populations/tests/test_members_position.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/populations/types.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/projectors/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/projectors/entity_to_person_projector.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/projectors/first_person_to_entity_projector.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/projectors/helpers.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/projectors/projector.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/projectors/typing.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/projectors/unique_role_to_entity_projector.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/rates.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/reforms/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/reforms/in_yaml_test_reform.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/reforms/reform.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/reforms/reform_excel.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/assets/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/assets/index.html +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/find_placeholders.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/measure_numpy_condition_notations.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/measure_performances.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/measure_performances_fancy_indexing.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/migrations/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/migrations/v16_2_to_v17/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/migrations/v16_2_to_v17/legislation.xsd +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/migrations/v16_2_to_v17/xml_to_yaml_country_template.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/migrations/v16_2_to_v17/xml_to_yaml_extension_template.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/migrations/v24_to_25.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/openfisca_command.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/remove_fuzzy.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/run_test.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/scripts/simulation_generator.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/simulation_builder.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/simulations/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/simulations/_build_default_simulation.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/simulations/_build_from_variables.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/simulations/_type_guards.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/simulations/helpers.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/simulations/simulation_builder.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/simulations/typing.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/taxbenefitsystems/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/taxbenefitsystems/tax_benefit_system.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/taxscales/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/taxscales/amount_tax_scale_like.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/taxscales/helpers.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/taxscales/linear_average_rate_tax_scale.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/taxscales/marginal_amount_tax_scale.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/taxscales/marginal_rate_tax_scale.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/taxscales/rate_tax_scale_like.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/taxscales/single_amount_tax_scale.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/tools/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/tools/parallel_plugin.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/tools/simulation_dumper.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/tools/test_runner.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/tracers/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/tracers/computation_log.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/tracers/flat_trace.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/tracers/full_tracer.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/tracers/performance_log.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/tracers/simple_tracer.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/tracers/trace_node.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/tracers/tracing_parameter_node_at_instant.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/types.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/variables/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/variables/config.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/variables/helpers.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/variables/tests/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/variables/tests/test_definition_period.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/variables/variable.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/warnings/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/warnings/libyaml_warning.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/warnings/tempfile_warning.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_web_api/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_web_api/app.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_web_api/errors.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_web_api/handlers.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_web_api/loader/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_web_api/loader/entities.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_web_api/loader/parameters.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_web_api/loader/spec.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_web_api/loader/tax_benefit_system.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_web_api/loader/variables.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_web_api/openAPI.yml +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_web_api/scripts/__init__.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_web_api/scripts/serve.py +0 -0
- {openfisca_core-44.3.0 → openfisca_core-44.6.0}/setup.cfg +0 -0
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 44.
|
|
3
|
+
## 44.6.0
|
|
4
4
|
|
|
5
|
-
####
|
|
6
|
-
|
|
7
|
-
- **Generic Entity Links (Phase 1-6)**: Introduced a new Liam2-inspired generic entity linking system avoiding rigid hierarchies like `Person -> Household`.
|
|
8
|
-
- Added new `Many2OneLink` and `One2ManyLink` models to create powerful inter-entity networks (e.g., `Person -> Employer`).
|
|
9
|
-
- Added implicit links directly binding members arrays. This powers the new `population.links` property natively inside `TaxBenefitSystem.instantiate_entities()`.
|
|
10
|
-
- Full capability to chain relationships via python: `person.mother.household.get("rent", period)`.
|
|
11
|
-
- Powerful vectorized declarative aggregations out-of-the-box (e.g., `households.persons.sum("salary", period, condition=is_female)`).
|
|
12
|
-
|
|
13
|
-
#### Technical Changes
|
|
5
|
+
#### Technical changes
|
|
14
6
|
|
|
15
|
-
-
|
|
7
|
+
- Revert the codebase to commit `8d26af3` to align the repository with the currently published `44.2.2` baseline on PyPI.
|
|
8
|
+
- Mark versions `44.3.0`, `44.4.0`, `44.4.1`, and `44.5.0` as yanked.
|
|
9
|
+
- Bump version to `44.6.0` to restore continuous deployment from this reverted baseline.
|
|
16
10
|
|
|
17
11
|
## 44.2.2
|
|
18
12
|
|
|
@@ -78,19 +78,6 @@ openfisca_core/indexed_enums/types.py
|
|
|
78
78
|
openfisca_core/indexed_enums/tests/__init__.py
|
|
79
79
|
openfisca_core/indexed_enums/tests/test_enum.py
|
|
80
80
|
openfisca_core/indexed_enums/tests/test_enum_array.py
|
|
81
|
-
openfisca_core/links/__init__.py
|
|
82
|
-
openfisca_core/links/implicit.py
|
|
83
|
-
openfisca_core/links/link.py
|
|
84
|
-
openfisca_core/links/many2one.py
|
|
85
|
-
openfisca_core/links/one2many.py
|
|
86
|
-
openfisca_core/links/tests/__init__.py
|
|
87
|
-
openfisca_core/links/tests/test_benchmark.py
|
|
88
|
-
openfisca_core/links/tests/test_edge_cases.py
|
|
89
|
-
openfisca_core/links/tests/test_implicit.py
|
|
90
|
-
openfisca_core/links/tests/test_integration.py
|
|
91
|
-
openfisca_core/links/tests/test_many2one.py
|
|
92
|
-
openfisca_core/links/tests/test_one2many.py
|
|
93
|
-
openfisca_core/links/tests/test_one2many_logic.py
|
|
94
81
|
openfisca_core/parameters/__init__.py
|
|
95
82
|
openfisca_core/parameters/at_instant_like.py
|
|
96
83
|
openfisca_core/parameters/config.py
|
|
@@ -47,9 +47,6 @@ class CoreEntity:
|
|
|
47
47
|
#: A ``TaxBenefitSystem`` instance.
|
|
48
48
|
_tax_benefit_system: None | t.TaxBenefitSystem = None
|
|
49
49
|
|
|
50
|
-
#: Named links to other entities (Many2One, One2Many, etc.).
|
|
51
|
-
_links: dict
|
|
52
|
-
|
|
53
50
|
@abc.abstractmethod
|
|
54
51
|
def __init__(self, *__args: object, **__kwargs: object) -> None: ...
|
|
55
52
|
|
|
@@ -60,43 +57,6 @@ class CoreEntity:
|
|
|
60
57
|
"""A ``CoreEntity`` belongs to a ``TaxBenefitSystem``."""
|
|
61
58
|
self._tax_benefit_system = tax_benefit_system
|
|
62
59
|
|
|
63
|
-
# -- Link management --------------------------------------------------
|
|
64
|
-
|
|
65
|
-
def add_link(self, link) -> None:
|
|
66
|
-
"""Register a named link on this entity.
|
|
67
|
-
|
|
68
|
-
Args:
|
|
69
|
-
link: A ``Link`` instance (Many2OneLink, One2ManyLink, etc.).
|
|
70
|
-
|
|
71
|
-
Example::
|
|
72
|
-
|
|
73
|
-
from openfisca_core.links import Many2OneLink
|
|
74
|
-
|
|
75
|
-
mother = Many2OneLink(
|
|
76
|
-
name="mother",
|
|
77
|
-
link_field="mother_id",
|
|
78
|
-
target_entity_key="person",
|
|
79
|
-
)
|
|
80
|
-
person_entity.add_link(mother)
|
|
81
|
-
|
|
82
|
-
"""
|
|
83
|
-
if not hasattr(self, "_links") or self._links is None:
|
|
84
|
-
self._links = {}
|
|
85
|
-
self._links[link.name] = link
|
|
86
|
-
|
|
87
|
-
def get_link(self, name: str):
|
|
88
|
-
"""Retrieve a link by name, or ``None`` if not found."""
|
|
89
|
-
if not hasattr(self, "_links") or self._links is None:
|
|
90
|
-
return None
|
|
91
|
-
return self._links.get(name)
|
|
92
|
-
|
|
93
|
-
@property
|
|
94
|
-
def links(self) -> dict:
|
|
95
|
-
"""All links registered on this entity."""
|
|
96
|
-
if not hasattr(self, "_links") or self._links is None:
|
|
97
|
-
self._links = {}
|
|
98
|
-
return self._links
|
|
99
|
-
|
|
100
60
|
def get_variable(
|
|
101
61
|
self,
|
|
102
62
|
variable_name: t.VariableName,
|
|
@@ -266,7 +266,8 @@ class EnumArray(t.EnumArray):
|
|
|
266
266
|
result: t.ObjArray
|
|
267
267
|
if self.possible_values is None:
|
|
268
268
|
msg = (
|
|
269
|
-
f"The possible values of the {self.__class__.__name__} are
|
|
269
|
+
f"The possible values of the {self.__class__.__name__} are "
|
|
270
|
+
f"not defined."
|
|
270
271
|
)
|
|
271
272
|
raise TypeError(msg)
|
|
272
273
|
array = self.reshape(1).astype(t.EnumDType) if self.ndim == 0 else self
|
|
@@ -300,7 +301,8 @@ class EnumArray(t.EnumArray):
|
|
|
300
301
|
result: t.StrArray
|
|
301
302
|
if self.possible_values is None:
|
|
302
303
|
msg = (
|
|
303
|
-
f"The possible values of the {self.__class__.__name__} are
|
|
304
|
+
f"The possible values of the {self.__class__.__name__} are "
|
|
305
|
+
f"not defined."
|
|
304
306
|
)
|
|
305
307
|
raise TypeError(msg)
|
|
306
308
|
array = self.reshape(1).astype(t.EnumDType) if self.ndim == 0 else self
|
{openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/populations/group_population.py
RENAMED
|
@@ -96,42 +96,16 @@ class GroupPopulation(Population):
|
|
|
96
96
|
None,
|
|
97
97
|
)
|
|
98
98
|
|
|
99
|
-
# Filtering helpers
|
|
100
|
-
|
|
101
|
-
def _build_member_mask(self, role=None, condition=None):
|
|
102
|
-
"""Build a combined boolean mask from role and condition filters.
|
|
103
|
-
|
|
104
|
-
Returns None if no filtering is needed (both are None), otherwise
|
|
105
|
-
returns a boolean array of length ``members.count``.
|
|
106
|
-
"""
|
|
107
|
-
if role is None and condition is None:
|
|
108
|
-
return None
|
|
109
|
-
|
|
110
|
-
mask = numpy.ones(self.members.count, dtype=bool)
|
|
111
|
-
|
|
112
|
-
if role is not None:
|
|
113
|
-
role_filter = self.members.has_role(role)
|
|
114
|
-
mask &= role_filter
|
|
115
|
-
|
|
116
|
-
if condition is not None:
|
|
117
|
-
mask &= condition
|
|
118
|
-
|
|
119
|
-
return mask
|
|
120
|
-
|
|
121
99
|
# Aggregation persons -> entity
|
|
122
100
|
|
|
123
101
|
@projectors.projectable
|
|
124
|
-
def sum(self, array, role=None
|
|
102
|
+
def sum(self, array, role=None):
|
|
125
103
|
"""Return the sum of ``array`` for the members of the entity.
|
|
126
104
|
|
|
127
105
|
``array`` must have the dimension of the number of persons in the simulation
|
|
128
106
|
|
|
129
107
|
If ``role`` is provided, only the entity member with the given role are taken into account.
|
|
130
108
|
|
|
131
|
-
If ``condition`` is provided (a boolean array of the same size as the
|
|
132
|
-
person population), only members for whom the condition is ``True`` are
|
|
133
|
-
taken into account. ``role`` and ``condition`` can be combined.
|
|
134
|
-
|
|
135
109
|
Example:
|
|
136
110
|
>>> salaries = household.members(
|
|
137
111
|
... "salary", "2018-01"
|
|
@@ -142,27 +116,23 @@ class GroupPopulation(Population):
|
|
|
142
116
|
"""
|
|
143
117
|
self.entity.check_role_validity(role)
|
|
144
118
|
self.members.check_array_compatible_with_entity(array)
|
|
145
|
-
|
|
146
|
-
|
|
119
|
+
if role is not None:
|
|
120
|
+
role_filter = self.members.has_role(role)
|
|
147
121
|
return numpy.bincount(
|
|
148
|
-
self.members_entity_id[
|
|
149
|
-
weights=array[
|
|
122
|
+
self.members_entity_id[role_filter],
|
|
123
|
+
weights=array[role_filter],
|
|
150
124
|
minlength=self.count,
|
|
151
125
|
)
|
|
152
126
|
return numpy.bincount(self.members_entity_id, weights=array)
|
|
153
127
|
|
|
154
128
|
@projectors.projectable
|
|
155
|
-
def any(self, array, role=None
|
|
129
|
+
def any(self, array, role=None):
|
|
156
130
|
"""Return ``True`` if ``array`` is ``True`` for any members of the entity.
|
|
157
131
|
|
|
158
132
|
``array`` must have the dimension of the number of persons in the simulation
|
|
159
133
|
|
|
160
134
|
If ``role`` is provided, only the entity member with the given role are taken into account.
|
|
161
135
|
|
|
162
|
-
If ``condition`` is provided (a boolean array of the same size as the
|
|
163
|
-
person population), only members for whom the condition is ``True`` are
|
|
164
|
-
taken into account. ``role`` and ``condition`` can be combined.
|
|
165
|
-
|
|
166
136
|
Example:
|
|
167
137
|
>>> salaries = household.members(
|
|
168
138
|
... "salary", "2018-01"
|
|
@@ -171,18 +141,16 @@ class GroupPopulation(Population):
|
|
|
171
141
|
>>> array([True])
|
|
172
142
|
|
|
173
143
|
"""
|
|
174
|
-
sum_in_entity = self.sum(array, role=role
|
|
144
|
+
sum_in_entity = self.sum(array, role=role)
|
|
175
145
|
return sum_in_entity > 0
|
|
176
146
|
|
|
177
147
|
@projectors.projectable
|
|
178
|
-
def reduce(self, array, reducer, neutral_element, role=None
|
|
148
|
+
def reduce(self, array, reducer, neutral_element, role=None):
|
|
179
149
|
self.members.check_array_compatible_with_entity(array)
|
|
180
150
|
self.entity.check_role_validity(role)
|
|
181
151
|
position_in_entity = self.members_position
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
mask = True # scalar True broadcasts; preserves old upcast behavior
|
|
185
|
-
filtered_array = numpy.where(mask, array, neutral_element)
|
|
152
|
+
role_filter = self.members.has_role(role) if role is not None else True
|
|
153
|
+
filtered_array = numpy.where(role_filter, array, neutral_element)
|
|
186
154
|
|
|
187
155
|
result = self.filled_array(
|
|
188
156
|
neutral_element,
|
|
@@ -199,17 +167,13 @@ class GroupPopulation(Population):
|
|
|
199
167
|
return result
|
|
200
168
|
|
|
201
169
|
@projectors.projectable
|
|
202
|
-
def all(self, array, role=None
|
|
170
|
+
def all(self, array, role=None):
|
|
203
171
|
"""Return ``True`` if ``array`` is ``True`` for all members of the entity.
|
|
204
172
|
|
|
205
173
|
``array`` must have the dimension of the number of persons in the simulation
|
|
206
174
|
|
|
207
175
|
If ``role`` is provided, only the entity member with the given role are taken into account.
|
|
208
176
|
|
|
209
|
-
If ``condition`` is provided (a boolean array of the same size as the
|
|
210
|
-
person population), only members for whom the condition is ``True`` are
|
|
211
|
-
taken into account. ``role`` and ``condition`` can be combined.
|
|
212
|
-
|
|
213
177
|
Example:
|
|
214
178
|
>>> salaries = household.members(
|
|
215
179
|
... "salary", "2018-01"
|
|
@@ -223,21 +187,16 @@ class GroupPopulation(Population):
|
|
|
223
187
|
reducer=numpy.logical_and,
|
|
224
188
|
neutral_element=True,
|
|
225
189
|
role=role,
|
|
226
|
-
condition=condition,
|
|
227
190
|
)
|
|
228
191
|
|
|
229
192
|
@projectors.projectable
|
|
230
|
-
def max(self, array, role=None
|
|
193
|
+
def max(self, array, role=None):
|
|
231
194
|
"""Return the maximum value of ``array`` for the entity members.
|
|
232
195
|
|
|
233
196
|
``array`` must have the dimension of the number of persons in the simulation
|
|
234
197
|
|
|
235
198
|
If ``role`` is provided, only the entity member with the given role are taken into account.
|
|
236
199
|
|
|
237
|
-
If ``condition`` is provided (a boolean array of the same size as the
|
|
238
|
-
person population), only members for whom the condition is ``True`` are
|
|
239
|
-
taken into account. ``role`` and ``condition`` can be combined.
|
|
240
|
-
|
|
241
200
|
Example:
|
|
242
201
|
>>> salaries = household.members(
|
|
243
202
|
... "salary", "2018-01"
|
|
@@ -251,21 +210,16 @@ class GroupPopulation(Population):
|
|
|
251
210
|
reducer=numpy.maximum,
|
|
252
211
|
neutral_element=-numpy.inf,
|
|
253
212
|
role=role,
|
|
254
|
-
condition=condition,
|
|
255
213
|
)
|
|
256
214
|
|
|
257
215
|
@projectors.projectable
|
|
258
|
-
def min(self, array, role=None
|
|
216
|
+
def min(self, array, role=None):
|
|
259
217
|
"""Return the minimum value of ``array`` for the entity members.
|
|
260
218
|
|
|
261
219
|
``array`` must have the dimension of the number of persons in the simulation
|
|
262
220
|
|
|
263
221
|
If ``role`` is provided, only the entity member with the given role are taken into account.
|
|
264
222
|
|
|
265
|
-
If ``condition`` is provided (a boolean array of the same size as the
|
|
266
|
-
person population), only members for whom the condition is ``True`` are
|
|
267
|
-
taken into account. ``role`` and ``condition`` can be combined.
|
|
268
|
-
|
|
269
223
|
Example:
|
|
270
224
|
>>> salaries = household.members(
|
|
271
225
|
... "salary", "2018-01"
|
|
@@ -283,18 +237,13 @@ class GroupPopulation(Population):
|
|
|
283
237
|
reducer=numpy.minimum,
|
|
284
238
|
neutral_element=numpy.inf,
|
|
285
239
|
role=role,
|
|
286
|
-
condition=condition,
|
|
287
240
|
)
|
|
288
241
|
|
|
289
242
|
@projectors.projectable
|
|
290
|
-
def nb_persons(self, role=None
|
|
243
|
+
def nb_persons(self, role=None):
|
|
291
244
|
"""Returns the number of persons contained in the entity.
|
|
292
245
|
|
|
293
246
|
If ``role`` is provided, only the entity member with the given role are taken into account.
|
|
294
|
-
|
|
295
|
-
If ``condition`` is provided (a boolean array of the same size as the
|
|
296
|
-
person population), only members for whom the condition is ``True`` are
|
|
297
|
-
counted. ``role`` and ``condition`` can be combined.
|
|
298
247
|
"""
|
|
299
248
|
if role:
|
|
300
249
|
if role.subroles:
|
|
@@ -303,9 +252,7 @@ class GroupPopulation(Population):
|
|
|
303
252
|
)
|
|
304
253
|
else:
|
|
305
254
|
role_condition = self.members_role == role
|
|
306
|
-
return self.sum(role_condition
|
|
307
|
-
if condition is not None:
|
|
308
|
-
return self.sum(condition.astype(float)).astype(int)
|
|
255
|
+
return self.sum(role_condition)
|
|
309
256
|
return numpy.bincount(self.members_entity_id)
|
|
310
257
|
|
|
311
258
|
# Projection person -> entity
|
|
@@ -24,9 +24,6 @@ class Population(CorePopulation):
|
|
|
24
24
|
return result
|
|
25
25
|
|
|
26
26
|
def __getattr__(self, attribute: str) -> projectors.Projector:
|
|
27
|
-
if hasattr(self, "links") and attribute in self.links:
|
|
28
|
-
return self.links[attribute]
|
|
29
|
-
|
|
30
27
|
projector: projectors.Projector | None
|
|
31
28
|
projector = projectors.get_projector_from_shortcut(self, attribute)
|
|
32
29
|
|
|
@@ -114,10 +111,11 @@ class Population(CorePopulation):
|
|
|
114
111
|
|
|
115
112
|
"""
|
|
116
113
|
# If entity is for instance 'person.household', we get the reference entity 'household' behind the projector
|
|
117
|
-
|
|
118
|
-
entity
|
|
119
|
-
|
|
120
|
-
|
|
114
|
+
entity = (
|
|
115
|
+
entity
|
|
116
|
+
if not isinstance(entity, projectors.Projector)
|
|
117
|
+
else entity.reference_entity
|
|
118
|
+
)
|
|
121
119
|
|
|
122
120
|
positions = entity.members_position
|
|
123
121
|
biggest_entity_size = numpy.max(positions) + 1
|
|
@@ -47,7 +47,6 @@ class Simulation:
|
|
|
47
47
|
self.persons = self.populations[tax_benefit_system.person_entity.key]
|
|
48
48
|
self.link_to_entities_instances()
|
|
49
49
|
self.create_shortcuts()
|
|
50
|
-
self._resolve_links()
|
|
51
50
|
|
|
52
51
|
self.invalidated_caches = set()
|
|
53
52
|
|
|
@@ -83,53 +82,6 @@ class Simulation:
|
|
|
83
82
|
# create shortcut simulation.person and simulation.household (for instance)
|
|
84
83
|
setattr(self, population.entity.key, population)
|
|
85
84
|
|
|
86
|
-
def _resolve_links(self) -> None:
|
|
87
|
-
"""Attach and resolve all links declared on every entity.
|
|
88
|
-
|
|
89
|
-
This also auto-generates implicit links for each GroupEntity:
|
|
90
|
-
- A Many2One link on the person entity (e.g. ``person.household``)
|
|
91
|
-
- A One2Many link on the group entity (e.g. ``household.members``)
|
|
92
|
-
|
|
93
|
-
This is called once at ``__init__`` time, after
|
|
94
|
-
``link_to_entities_instances`` and ``create_shortcuts``.
|
|
95
|
-
"""
|
|
96
|
-
from openfisca_core.links.implicit import (
|
|
97
|
-
ImplicitMany2OneLink,
|
|
98
|
-
ImplicitOne2ManyLink,
|
|
99
|
-
)
|
|
100
|
-
from openfisca_core.populations.group_population import GroupPopulation
|
|
101
|
-
|
|
102
|
-
person_entity = self.persons.entity
|
|
103
|
-
|
|
104
|
-
# Auto-generate implicit links
|
|
105
|
-
for population in self.populations.values():
|
|
106
|
-
if not isinstance(population, GroupPopulation):
|
|
107
|
-
continue
|
|
108
|
-
group_key = population.entity.key
|
|
109
|
-
|
|
110
|
-
# person -> group (Many2One)
|
|
111
|
-
if not person_entity.get_link(group_key):
|
|
112
|
-
m2o = ImplicitMany2OneLink(group_key)
|
|
113
|
-
person_entity.add_link(m2o)
|
|
114
|
-
|
|
115
|
-
# group -> persons (One2Many)
|
|
116
|
-
o2m_name = person_entity.plural
|
|
117
|
-
if not population.entity.get_link(o2m_name):
|
|
118
|
-
o2m = ImplicitOne2ManyLink(o2m_name, group_key)
|
|
119
|
-
population.entity.add_link(o2m)
|
|
120
|
-
|
|
121
|
-
from copy import copy
|
|
122
|
-
|
|
123
|
-
# Attach and resolve all links, making a simulation-local copy
|
|
124
|
-
for _key, population in self.populations.items():
|
|
125
|
-
entity = population.entity
|
|
126
|
-
population.links = {}
|
|
127
|
-
for name, link in entity.links.items():
|
|
128
|
-
bound_link = copy(link)
|
|
129
|
-
bound_link.attach(population)
|
|
130
|
-
bound_link.resolve(self.populations)
|
|
131
|
-
population.links[name] = bound_link
|
|
132
|
-
|
|
133
85
|
@property
|
|
134
86
|
def data_storage_dir(self):
|
|
135
87
|
"""Temporary folder used to store intermediate calculation data in case the memory is saturated."""
|
{openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/taxscales/abstract_rate_tax_scale.py
RENAMED
|
@@ -36,7 +36,7 @@ class AbstractRateTaxScale(RateTaxScaleLike):
|
|
|
36
36
|
tax_base: NumericalArray,
|
|
37
37
|
right: bool,
|
|
38
38
|
) -> typing.NoReturn:
|
|
39
|
-
msg =
|
|
39
|
+
msg = "Method 'calc' is not implemented for " f"{self.__class__.__name__}"
|
|
40
40
|
raise NotImplementedError(
|
|
41
41
|
msg,
|
|
42
42
|
)
|
{openfisca_core-44.3.0 → openfisca_core-44.6.0}/openfisca_core/taxscales/abstract_tax_scale.py
RENAMED
|
@@ -32,7 +32,7 @@ class AbstractTaxScale(TaxScaleLike):
|
|
|
32
32
|
super().__init__(name, option, unit)
|
|
33
33
|
|
|
34
34
|
def __repr__(self) -> typing.NoReturn:
|
|
35
|
-
msg =
|
|
35
|
+
msg = "Method '__repr__' is not implemented for " f"{self.__class__.__name__}"
|
|
36
36
|
raise NotImplementedError(
|
|
37
37
|
msg,
|
|
38
38
|
)
|
|
@@ -42,7 +42,7 @@ class AbstractTaxScale(TaxScaleLike):
|
|
|
42
42
|
tax_base: NumericalArray,
|
|
43
43
|
right: bool,
|
|
44
44
|
) -> typing.NoReturn:
|
|
45
|
-
msg =
|
|
45
|
+
msg = "Method 'calc' is not implemented for " f"{self.__class__.__name__}"
|
|
46
46
|
raise NotImplementedError(
|
|
47
47
|
msg,
|
|
48
48
|
)
|
|
@@ -36,13 +36,13 @@ class TaxScaleLike(abc.ABC):
|
|
|
36
36
|
self.thresholds = []
|
|
37
37
|
|
|
38
38
|
def __eq__(self, _other: object) -> typing.NoReturn:
|
|
39
|
-
msg =
|
|
39
|
+
msg = "Method '__eq__' is not implemented for " f"{self.__class__.__name__}"
|
|
40
40
|
raise NotImplementedError(
|
|
41
41
|
msg,
|
|
42
42
|
)
|
|
43
43
|
|
|
44
44
|
def __ne__(self, _other: object) -> typing.NoReturn:
|
|
45
|
-
msg =
|
|
45
|
+
msg = "Method '__ne__' is not implemented for " f"{self.__class__.__name__}"
|
|
46
46
|
raise NotImplementedError(
|
|
47
47
|
msg,
|
|
48
48
|
)
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
"""Links between entities (Many2One, One2Many, chaining).
|
|
2
|
-
|
|
3
|
-
This module implements a generic link system inspired by LIAM2, enriched
|
|
4
|
-
with OpenFisca's role semantics. Links are orthogonal to the existing
|
|
5
|
-
GroupEntity/Projector machinery: current code keeps working unchanged,
|
|
6
|
-
and links provide additional capabilities (intra-entity links, chaining,
|
|
7
|
-
arbitrary named links).
|
|
8
|
-
|
|
9
|
-
Usage in a country package::
|
|
10
|
-
|
|
11
|
-
from openfisca_core.links import Many2OneLink, One2ManyLink
|
|
12
|
-
|
|
13
|
-
# Declare a person→person link (intra-entity)
|
|
14
|
-
mother = Many2OneLink(
|
|
15
|
-
name="mother",
|
|
16
|
-
link_field="mother_id",
|
|
17
|
-
target_entity_key="person",
|
|
18
|
-
)
|
|
19
|
-
|
|
20
|
-
# Declare a person→employer link (inter-entity)
|
|
21
|
-
employer = Many2OneLink(
|
|
22
|
-
name="employer",
|
|
23
|
-
link_field="employer_id",
|
|
24
|
-
target_entity_key="employer",
|
|
25
|
-
)
|
|
26
|
-
"""
|
|
27
|
-
|
|
28
|
-
from .link import Link
|
|
29
|
-
from .many2one import Many2OneLink
|
|
30
|
-
from .one2many import One2ManyLink
|
|
31
|
-
|
|
32
|
-
__all__ = [
|
|
33
|
-
"Link",
|
|
34
|
-
"Many2OneLink",
|
|
35
|
-
"One2ManyLink",
|
|
36
|
-
]
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
"""Implicit links dynamically inferred from OpenFisca's GroupPopulation system."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
import numpy
|
|
6
|
-
|
|
7
|
-
from .many2one import Many2OneLink
|
|
8
|
-
from .one2many import One2ManyLink
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class ImplicitMany2OneLink(Many2OneLink):
|
|
12
|
-
"""A person → group link using GroupPopulation's internal arrays.
|
|
13
|
-
|
|
14
|
-
This bypasses the usual Variable lookup (``simulation.calculate``)
|
|
15
|
-
and directly reads ``members_entity_id`` and ``members_role`` from
|
|
16
|
-
the target GroupPopulation.
|
|
17
|
-
"""
|
|
18
|
-
|
|
19
|
-
def __init__(self, group_entity_key: str):
|
|
20
|
-
super().__init__(
|
|
21
|
-
name=group_entity_key,
|
|
22
|
-
link_field="", # Not used
|
|
23
|
-
target_entity_key=group_entity_key,
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
def _get_target_ids(self, period) -> numpy.ndarray:
|
|
27
|
-
return self._target_population.members_entity_id
|
|
28
|
-
|
|
29
|
-
@property
|
|
30
|
-
def role(self) -> numpy.ndarray | None:
|
|
31
|
-
return self._target_population.members_role
|
|
32
|
-
|
|
33
|
-
def _project_implicit(self, result: numpy.ndarray) -> numpy.ndarray:
|
|
34
|
-
# Fully compatible with old Projector logic
|
|
35
|
-
return self._target_population.project(result)
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
class ImplicitOne2ManyLink(One2ManyLink):
|
|
39
|
-
"""A group → person link using GroupPopulation's internal arrays."""
|
|
40
|
-
|
|
41
|
-
def __init__(self, name: str, group_entity_key: str):
|
|
42
|
-
super().__init__(
|
|
43
|
-
name=name,
|
|
44
|
-
link_field="", # Not used
|
|
45
|
-
target_entity_key="person", # The target of the O2M is persons
|
|
46
|
-
)
|
|
47
|
-
self._group_entity_key = group_entity_key
|
|
48
|
-
|
|
49
|
-
def _source_rows(self, period) -> numpy.ndarray:
|
|
50
|
-
# For a group->person O2M, the source is the group, the target is the person.
|
|
51
|
-
# members_entity_id is an array of length person.count, containing the group index.
|
|
52
|
-
# So members_entity_id IS the array of source rows for each target member.
|
|
53
|
-
return self._source_population.members_entity_id
|
|
54
|
-
|
|
55
|
-
def _apply_filters(self, period, values, role, condition):
|
|
56
|
-
source_rows = self._source_rows(period)
|
|
57
|
-
mask = numpy.ones(len(source_rows), dtype=bool)
|
|
58
|
-
|
|
59
|
-
if role is not None:
|
|
60
|
-
roles = self._source_population.members_role
|
|
61
|
-
mask &= roles == role
|
|
62
|
-
|
|
63
|
-
if condition is not None:
|
|
64
|
-
mask &= condition
|
|
65
|
-
|
|
66
|
-
source_rows = source_rows[mask]
|
|
67
|
-
values = values[mask]
|
|
68
|
-
|
|
69
|
-
valid = source_rows >= 0
|
|
70
|
-
return source_rows[valid], values[valid]
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
__all__ = ["ImplicitMany2OneLink", "ImplicitOne2ManyLink"]
|