feat(python): add mutable EventData proxy bindings with lifetime safety#5571
Merged
kodiakhq[bot] merged 5 commits intoJun 18, 2026
Merged
Conversation
Contributor
andiwand
reviewed
Jun 11, 2026
Contributor
|
drafting for now until we have a conclusion on the discussion which takes load off the gitlab ci |
benjaminhuth
left a comment
Member
There was a problem hiding this comment.
Hi, really cool initiative. I think personally it would be cool to have a mechanism like this to avoid segfaults on the python-level that are due to our C++ ownership model.
I think there are still some things to be discussed about the implementation.
andiwand
reviewed
Jun 11, 2026
andiwand
reviewed
Jun 11, 2026
- Merge DisownTestBindings.cpp into EventData.cpp as acts._testing submodule - Add explicit constructor to ProxyTether to prevent uninitialized aliveFn - Add Owner template parameter to ProxyTether; single-owner proxies derive the alive check at compile time, multi-owner proxies (MeasTether) retain the runtime AliveFn override constructor - Rename CheckedIterator -> IteratorTether, CheckedIndexIterator -> IndexIteratorTether for naming consistency
|
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.



feat(python): add mutable EventData proxy bindings with lifetime safety
Add mutable Python bindings for
SpacePointContainer2,SeedContainer2, and measurement containers, together with lifetime-safeproxy and iterator handling.
Python proxies currently hold raw pointers into their backing C++
containers. If the container is consumed by a
std::unique_ptr<T>transfer, for example through the whiteboard, the Python wrapper can
remain alive while the C++ object has been moved out. Accessing an
existing proxy then dereferences freed memory.
This PR introduces
ProxyTether, a binding-side wrapper that keeps theowning
py::objectand revalidates it before proxy access. If thebacking container has been disowned, access now raises
ValueErrorinstead of causing undefined behaviour or a segfault.
Also guard optional
SpacePointColumnsaccess so missing columns raiseAttributeErrorinstead of relying on C++ assertions.--- END COMMIT MESSAGE ---
Changes
Add mutable
SpacePointContainer2/MutableSpacePointProxy2bindings:createSpacePoint()__getitem____iter__Add
SeedContainer2/MutableSeedProxy2bindings:createSeed()assignSpacePointContainer()assignSpacePointIndices()qualityandvertexZMake
MeasurementContainer/MeasurementSubsetproxy access use tethered proxies.Add checked iterator handling for example flat multimaps.
Add
py::keep_alivetoConstTrackContainerproxy accessors.ProxyTetherProxyTetherstores the Python owner object, the proxy value, and a type-erased owner-validity check.Before each proxy access, the owner is re-cast to the backing C++ type. If pybind11's
smart_holderhas disowned the object after aunique_ptr<T>transfer, this fails and is translated into a PythonValueError.This handles both relevant lifetime cases:
py::objectis retained;Tests
Adds a test-only pybind11 module,
_acts_core_test_bindings, with helpers that consumeSpacePointContainer2andSeedContainer2viastd::unique_ptr<T>. This reproduces the same disowning behaviour as the whiteboard without depending onacts.examples.test_event_data.pynow covers:AttributeError,All added tests pass.
Known follow-up work
This PR focuses on proxies and iterators whose own backing container has been consumed/disowned. It does not fully solve separate cross-owner or buffer-lifetime cases, including:
sourceLinkssub-iterators whose underlying container is transferred after the iterator is created;SeedContainer2references to an assignedSpacePointContainer2if future Python APIs expose dereferencing that relationship;TrackProxyobjects kept alive aftermakeConst()drains the mutable track container;MeasurementSubsetviews after the originalMeasurementContaineris independently transferred;Those require separate true-owner or buffer-base lifetime handling and are left for follow-up PRs.
cc @benjaminhuth @andiwand