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 {
10321032 pybind11_fail (" Could not set capsule context!" );
10331033 }
10341034
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+
10351045 template <typename T> operator T *() const {
10361046 T * result = static_cast <T *>(PyCapsule_GetPointer (m_ptr, nullptr ));
10371047 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) {
470470 m.def (" return_none_bool" , []() -> bool * { return nullptr ; });
471471 m.def (" return_none_int" , []() -> int * { return nullptr ; });
472472 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+ );
473491});
474492
475493#if defined(_MSC_VER)
Original file line number Diff line number Diff line change @@ -512,3 +512,22 @@ def test_builtins_cast_return_none():
512512 assert m .return_none_bool () is None
513513 assert m .return_none_int () is None
514514 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