2222#include < pybind11/detail/common.h>
2323#include < pybind11/numpy.h>
2424#include < pybind11/pybind11.h>
25+ #include < pybind11/pytypes.h>
2526#include < pybind11/stl.h>
2627
2728#include " openPMD/Dataset.hpp"
@@ -322,13 +323,16 @@ struct StoreChunkFromPythonArray
322323 Offset const &offset,
323324 Extent const &extent)
324325 {
325- // here, we increase a reference on the user-passed data so that
326+ a.inc_ref ();
327+ void *data = a.mutable_data ();
328+ // here, we store an owning handle in the lambda capture so that
326329 // temporary and lost-scope variables stay alive until we flush
327330 // note: this does not yet prevent the user, as in C++, to build
328331 // a race condition by manipulating the data that was passed
329- a.inc_ref ();
330- void *data = a.mutable_data ();
331- std::shared_ptr<T> shared ((T *)data, [a](T *) { a.dec_ref (); });
332+ std::shared_ptr<T> shared (
333+ (T *)data, [owning_handle = a.cast <py::object>()](T *) {
334+ // no-op
335+ });
332336 r.storeChunk (std::move (shared), offset, extent);
333337 }
334338
@@ -343,13 +347,15 @@ struct LoadChunkIntoPythonArray
343347 Offset const &offset,
344348 Extent const &extent)
345349 {
346- // here, we increase a reference on the user-passed data so that
350+ void *data = a.mutable_data ();
351+ // here, we store an owning handle in the lambda capture so that
347352 // temporary and lost-scope variables stay alive until we flush
348353 // note: this does not yet prevent the user, as in C++, to build
349354 // a race condition by manipulating the data that was passed
350- a.inc_ref ();
351- void *data = a.mutable_data ();
352- std::shared_ptr<T> shared ((T *)data, [a](T *) { a.dec_ref (); });
355+ std::shared_ptr<T> shared (
356+ (T *)data, [owning_handle = a.cast <py::object>()](T *) {
357+ // no-op
358+ });
353359 r.loadChunk (std::move (shared), offset, extent);
354360 }
355361
@@ -365,14 +371,15 @@ struct LoadChunkIntoPythonBuffer
365371 Offset const &offset,
366372 Extent const &extent)
367373 {
368- // here, we increase a reference on the user-passed data so that
374+ void *data = buffer_info.ptr ;
375+ // here, we store an owning handle in the lambda capture so that
369376 // temporary and lost-scope variables stay alive until we flush
370377 // note: this does not yet prevent the user, as in C++, to build
371378 // a race condition by manipulating the data that was passed
372- buffer.inc_ref ();
373- void *data = buffer_info.ptr ;
374379 std::shared_ptr<T> shared (
375- (T *)data, [buffer](T *) { buffer.dec_ref (); });
380+ (T *)data, [owning_handle = buffer.cast <py::object>()](T *) {
381+ // no-op
382+ });
376383 r.loadChunk (std::move (shared), offset, extent);
377384 }
378385
0 commit comments