Skip to content

feat: add as_of attribute for persistent vector variables#1365

Merged
benjello merged 4 commits intomasterfrom
feat/as-of-variable
Mar 4, 2026
Merged

feat: add as_of attribute for persistent vector variables#1365
benjello merged 4 commits intomasterfrom
feat/as-of-variable

Conversation

@benjello
Copy link
Copy Markdown
Member

Summary

  • Introduces as_of = True / "start" / "end" on Variable: a value set at a given instant persists forward in time until explicitly overridden — the vectorial analogue of OpenFisca parameters
  • Holder.get_array falls back to _get_as_of() when no exact period match is found
  • O(log P) lookup via bisect on a sorted instants list, with a linear-scan fallback for cloned holders
  • Reference sharing: identical consecutive values reuse the same array object; new values are stored as read-only defensive copies
  • Guard against combining as_of with set_input helpers (semantically incompatible)
  • pyproject.toml: exclude docs/ from codespell (French-language design docs)

Test plan

  • 14 new unit tests in tests/core/test_asof_variable.py — all pass locally
  • Full test suite: 483 passed, 0 new failures (test_yaml shell-script failures are pre-existing)
  • Verify as_of = True normalises to "start"
  • Verify as_of = "end" uses period.stop as reference instant
  • Verify read-only guard: stored arrays have writeable=False, caller array untouched
  • Verify reference sharing: identical values share the same array object

🤖 Generated with Claude Code

Copy link
Copy Markdown
Member

@eraviart eraviart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needed for longitudinal simulations

@benjello benjello force-pushed the feat/as-of-variable branch from d100785 to 32ad81b Compare March 4, 2026 10:47
benjello and others added 4 commits March 4, 2026 11:49
Introduces as_of = True / "start" / "end" on Variable, enabling
values set at a given instant to persist forward in time until
explicitly overridden — the vectorial analogue of OpenFisca parameters.

- Variable: set_as_of() setter normalises True → "start", rejects
  invalid values, and guards against incompatible set_input helpers
- Holder.get_array: falls back to _get_as_of() when no exact match
- Holder._get_as_of: O(log P) lookup via bisect on _sorted_instants,
  with a linear-scan fallback for cloned holders
- Holder._set: reference sharing for unchanged arrays + defensive
  read-only copy to prevent in-place mutation of stored data
- Holder.clone: copies _sorted_instants independently
- 14 unit tests covering persistence, conventions, reference sharing,
  read-only guard, and declaration validation
- pyproject.toml: exclude docs/ from codespell (French design docs)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tion

- Add "Ce qui a été implémenté — v44.3.0" section: Variable.as_of
  attribute, Holder changes, mitigated risks, 14 tests, known gaps
- Add "Limite de l'implémentation actuelle : stockage dense" section:
  explains why reference sharing is ineffective for scattered individual
  changes (e.g. civil servants changing grade), quantifies the memory
  gap vs patch-based storage, and sketches the patch storage model
  that v_next should implement

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@benjello benjello force-pushed the feat/as-of-variable branch from 32ad81b to 8beb444 Compare March 4, 2026 10:49
@benjello benjello enabled auto-merge March 4, 2026 10:51
@benjello benjello merged commit 7195b07 into master Mar 4, 2026
24 checks passed
@benjello benjello deleted the feat/as-of-variable branch March 4, 2026 10:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants