File tree Expand file tree Collapse file tree 3 files changed +47
-0
lines changed Expand file tree Collapse file tree 3 files changed +47
-0
lines changed Original file line number Diff line number Diff line change @@ -1032,6 +1032,16 @@ class capsule : public object {
1032
1032
pybind11_fail (" Could not set capsule context!" );
1033
1033
}
1034
1034
1035
+ capsule (void (*destructor)()) {
1036
+ m_ptr = PyCapsule_New (reinterpret_cast <void *>(destructor), nullptr , [](PyObject *o) {
1037
+ auto destructor = reinterpret_cast <void (*)()>(PyCapsule_GetPointer (o, nullptr ));
1038
+ destructor ();
1039
+ });
1040
+
1041
+ if (!m_ptr)
1042
+ pybind11_fail (" Could not allocate capsule object!" );
1043
+ }
1044
+
1035
1045
template <typename T> operator T *() const {
1036
1046
T * result = static_cast <T *>(PyCapsule_GetPointer (m_ptr, nullptr ));
1037
1047
if (!result) pybind11_fail (" Unable to extract capsule contents!" );
Original file line number Diff line number Diff line change @@ -470,6 +470,24 @@ test_initializer python_types([](py::module &m) {
470
470
m.def (" return_none_bool" , []() -> bool * { return nullptr ; });
471
471
m.def (" return_none_int" , []() -> int * { return nullptr ; });
472
472
m.def (" return_none_float" , []() -> float * { return nullptr ; });
473
+
474
+ m.def (" return_capsule_with_destructor" ,
475
+ []() {
476
+ py::print (" creating capsule" );
477
+ return py::capsule ([]() {
478
+ py::print (" destructing capsule" );
479
+ });
480
+ }
481
+ );
482
+
483
+ m.def (" return_capsule_with_destructor_2" ,
484
+ []() {
485
+ py::print (" creating capsule" );
486
+ return py::capsule ((void *) 1234 , [](void *ptr) {
487
+ py::print (" destructing capsule: {}" _s.format ((size_t ) ptr));
488
+ });
489
+ }
490
+ );
473
491
});
474
492
475
493
#if defined(_MSC_VER)
Original file line number Diff line number Diff line change @@ -512,3 +512,22 @@ def test_builtins_cast_return_none():
512
512
assert m .return_none_bool () is None
513
513
assert m .return_none_int () is None
514
514
assert m .return_none_float () is None
515
+
516
+ def test_capsule_with_destructor (capture ):
517
+ import pybind11_tests as m
518
+ with capture :
519
+ a = m .return_capsule_with_destructor ()
520
+ del a
521
+ assert capture .unordered == """
522
+ creating capsule
523
+ destructing capsule
524
+ """
525
+
526
+ with capture :
527
+ a = m .return_capsule_with_destructor_2 ()
528
+ del a
529
+ print (capture )
530
+ assert capture .unordered == """
531
+ creating capsule
532
+ destructing capsule: 1234
533
+ """
You can’t perform that action at this time.
0 commit comments