Skip to content

feat(python): add mutable EventData proxy bindings with lifetime safety#5571

Merged
kodiakhq[bot] merged 5 commits into
acts-project:mainfrom
EliMe5:python-event-data-bindings-clean
Jun 18, 2026
Merged

feat(python): add mutable EventData proxy bindings with lifetime safety#5571
kodiakhq[bot] merged 5 commits into
acts-project:mainfrom
EliMe5:python-event-data-bindings-clean

Conversation

@EliMe5

@EliMe5 EliMe5 commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

feat(python): add mutable EventData proxy bindings with lifetime safety

Add mutable Python bindings for SpacePointContainer2,
SeedContainer2, and measurement containers, together with lifetime-safe
proxy 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 the
owning py::object and revalidates it before proxy access. If the
backing container has been disowned, access now raises ValueError
instead of causing undefined behaviour or a segfault.

Also guard optional SpacePointColumns access so missing columns raise
AttributeError instead of relying on C++ assertions.

--- END COMMIT MESSAGE ---

Changes

  • Add mutable SpacePointContainer2 / MutableSpacePointProxy2 bindings:

    • createSpacePoint()
    • __getitem__
    • __iter__
    • guarded read/write access for scalar and array columns
  • Add SeedContainer2 / MutableSeedProxy2 bindings:

    • createSeed()
    • assignSpacePointContainer()
    • assignSpacePointIndices()
    • read/write quality and vertexZ
  • Make MeasurementContainer / MeasurementSubset proxy access use tethered proxies.

  • Add checked iterator handling for example flat multimaps.

  • Add py::keep_alive to ConstTrackContainer proxy accessors.

ProxyTether

ProxyTether stores 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_holder has disowned the object after a unique_ptr<T> transfer, this fails and is translated into a Python ValueError.

This handles both relevant lifetime cases:

  • the ordinary Python GC path, because the owner py::object is retained;
  • the whiteboard/disown path, because the owner is revalidated before access.

Tests

Adds a test-only pybind11 module, _acts_core_test_bindings, with helpers that consume SpacePointContainer2 and SeedContainer2 via std::unique_ptr<T>. This reproduces the same disowning behaviour as the whiteboard without depending on acts.examples.

test_event_data.py now covers:

  • mutable space point proxy read/write,
  • all-columns round trip,
  • missing-column AttributeError,
  • seed container/proxy access,
  • fail-loud behaviour after disown for space point and seed proxies,
  • proxy survival after Python GC.

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:

  • sourceLinks sub-iterators whose underlying container is transferred after the iterator is created;
  • SeedContainer2 references to an assigned SpacePointContainer2 if future Python APIs expose dereferencing that relationship;
  • TrackProxy objects kept alive after makeConst() drains the mutable track container;
  • MeasurementSubset views after the original MeasurementContainer is independently transferred;
  • NumPy arrays that outlive move-only backing storage.

Those require separate true-owner or buffer-base lifetime handling and are left for follow-up PRs.

cc @benjaminhuth @andiwand

@github-actions github-actions Bot added this to the next milestone Jun 10, 2026
@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

📊: Physics performance monitoring for 587058d

Full contents

physmon summary

Comment thread Python/Utilities/include/ActsPython/Utilities/ProxyTether.hpp
@andiwand andiwand marked this pull request as draft June 11, 2026 08:09
@andiwand

Copy link
Copy Markdown
Contributor

drafting for now until we have a conclusion on the discussion which takes load off the gitlab ci

@benjaminhuth benjaminhuth left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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.

Comment thread Python/Utilities/include/ActsPython/Utilities/ProxyTether.hpp Outdated
Comment thread Python/Core/tests/DisownTestBindings.cpp Outdated
Comment thread Python/Utilities/include/ActsPython/Utilities/ProxyTether.hpp
Comment thread Python/Utilities/include/ActsPython/Utilities/ProxyTether.hpp
Comment thread Python/Utilities/include/ActsPython/Utilities/ProxyTether.hpp
Comment thread Python/Utilities/include/ActsPython/Utilities/ProxyTether.hpp Outdated
Comment thread Python/Utilities/include/ActsPython/Utilities/ProxyTether.hpp
Comment thread Python/Utilities/include/ActsPython/Utilities/ProxyTether.hpp
Comment thread Python/Core/tests/DisownTestBindings.cpp Outdated
- 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

@benjaminhuth benjaminhuth left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@benjaminhuth benjaminhuth marked this pull request as ready for review June 18, 2026 07:21
@sonarqubecloud

Copy link
Copy Markdown

@kodiakhq kodiakhq Bot merged commit d9cf7a2 into acts-project:main Jun 18, 2026
46 checks passed
@andiwand andiwand modified the milestones: next, v47.0.0 Jul 14, 2026
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.

4 participants