Entity links: role-based accessors, rank, nth, and dynamic population period index#1364
Merged
Entity links: role-based accessors, rank, nth, and dynamic population period index#1364
Conversation
eraviart
approved these changes
Mar 4, 2026
Populate `_id_to_rownum` with the identity mapping `[0, 1, ..., n-1]` for all static simulations built via `build_default_simulation` and `build_from_dict` / `build_from_entities`, preparing the ground for dynamic populations (LIAM2-inspired). - Add `_BuildDefaultSimulation.add_id_to_rownum()` and chain it in `build_default_simulation()` - Set `population._id_to_rownum` in `finalize_variables_init()` after `count` and `ids` are known - Add tests: basic builder paths + edge cases (empty, single, group TBS, dtype check, index round-trip) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ation helpers) Made-with: Cursor
062a764 to
c1f28ee
Compare
…dd PYTHON to lint.mk Made-with: Cursor
…44.4.0 Made-with: Cursor
Member
|
This changeset added documentation that is partially in French and is not located in the See #1366 (comment) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR extends the entity links API with role-based and positional accessors, improves role handling when roles are stored as
Roleobjects, and adds optional dynamic-population period-index helpers onCorePopulation.Type of change
Changes
Entity links
has_role(role_value)Now supports both raw values (int/string) and
Roleobjects. When the role array hasdtype=object, comparison uses each element’s.keyso thatlink.has_role("parent")andlink.get_by_role(..., role_value="foo")work regardless of whether roles are stored as keys orRoleinstances. Applied inMany2OneLinkandImplicitOne2ManyLink._apply_filters.Many2OneLink.get_by_role(variable_name, period, role_value=...)Returns the target variable only for source members that have the given role; other rows get the variable’s default (e.g. 0). Uses the existing
role_fieldand the updatedhas_role().Many2OneLink.rank(variable_name, period)Ranks each source member within its group (same target entity) by the value of a variable on the source population. Delegates to
Population.get_rank. Also exposed on the chained link getter sopersons.links["mother"].household.rank("age", period)works.One2ManyLink.nth(n, variable_name, period, role=..., condition=...)Returns the value of the n-th target member for each source entity (same parameters as
sumplusn). Order is that of the underlying population arrays.One2ManyLink.get_by_role(variable_name, period, role_value, condition=...)Returns the value of the target that has the given role per source (using
role_fieldon the target). If multiple targets share the same role, the last encountered value is used (aligned withGroupPopulation.value_from_person). Requires a non-Nonerole_field.ImplicitOne2ManyLink_apply_filtersnow supports object arrays ofRoleinstances (compare by.key).get_by_roleto use_source_population.members_roleinstead of a targetrole_field, with the same “last value wins” semantics.Populations
CorePopulation_dynamic,_permanent_ids,_id_to_rownum,_next_id,_period_index.snapshot_period(period): stores the current_id_to_rownumfor the given period (creates a default identity mapping if none exists).get_period_id_to_rownum(period): returns the stored id→rownum mapping for the period, orNoneif not found.Tests and cleanup
openfisca_core/links/tests/test_many2one.pytest_many2one_role_helpers: now also checksget_by_role("rent", "2024", role_value=10).test_many2one_rank: checkslink.rank("age", "2024")and the chained getterpersons.links["mother"].household.rank(...).tests/core/parameters_date_indexing/test_date_indexing.pyfrom openfisca_core.model_api import *.tests/core/test_link_accessors.py(new)nthandget_by_roleon implicit one-to-many and many-to-one links (e.g. household ↔ persons with parent/child roles).Impacted areas
openfisca_core/links/implicit.pyopenfisca_core/links/many2one.pyopenfisca_core/links/one2many.pyopenfisca_core/populations/_core_population.pyBreaking changes
None. New methods and optional attributes only; existing call sites remain valid. Role comparison now accepts both raw values and
Roleobjects when the role array is an object array.Checklist
CHANGELOG.md(to be added if maintainers require it for this release).