Skip to content

Commit 48543b1

Browse files
committed
Add failing test for pybind#1546
1 parent e76dff7 commit 48543b1

File tree

2 files changed

+58
-1
lines changed

2 files changed

+58
-1
lines changed

tests/test_virtual_functions.cpp

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,4 +475,46 @@ void initialize_inherited_virtuals(py::module &m) {
475475
// Fix issue #1454 (crash when acquiring/releasing GIL on another thread in Python 2.7)
476476
m.def("test_gil", &test_gil);
477477
m.def("test_gil_from_thread", &test_gil_from_thread);
478-
};
478+
479+
// Fix issue #1546 (Python object not kept alive by shared_ptr)
480+
struct SharedPtrBase
481+
{
482+
virtual void f (int i) const = 0;
483+
virtual ~SharedPtrBase () { };
484+
};
485+
486+
struct Trampoline : SharedPtrBase
487+
{
488+
void f (int i) const override
489+
{
490+
PYBIND11_OVERLOAD_PURE_NAME (
491+
void,
492+
SharedPtrBase,
493+
"f",
494+
impl,
495+
/* args */
496+
i);
497+
}
498+
};
499+
500+
struct SharedPtrHolder
501+
{
502+
SharedPtrHolder (std::shared_ptr<SharedPtrBase> ptr)
503+
: ptr (std::move (ptr))
504+
{ }
505+
506+
void run (int i)
507+
{
508+
ptr->f (i);
509+
}
510+
511+
std::shared_ptr<SharedPtrBase> ptr;
512+
};
513+
514+
py::class_<SharedPtrBase, Trampoline, std::shared_ptr<SharedPtrBase>> (m, "SharedPtrBase")
515+
.def (py::init<> ());
516+
517+
py::class_<SharedPtrHolder> (m, "SharedPtrHolder")
518+
.def (py::init<std::shared_ptr<SharedPtrBase>> ())
519+
.def ("run", &SharedPtrHolder::run);
520+
}

tests/test_virtual_functions.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,3 +375,18 @@ def test_issue_1454():
375375
# Fix issue #1454 (crash when acquiring/releasing GIL on another thread in Python 2.7)
376376
m.test_gil()
377377
m.test_gil_from_thread()
378+
379+
def test_issue_1546():
380+
# Fix issue #1546 (Python object not kept alive by shared_ptr)
381+
somelist = []
382+
class Derived(m.SharedPtrBase):
383+
def __init__(self):
384+
super(Derived, self).__init__()
385+
386+
def f(self, value):
387+
somelist.append (value)
388+
print("Right one", 42)
389+
390+
holder = m.SharedPtrHolder(Derived())
391+
holder.run(42);
392+
assert somelist == [42]

0 commit comments

Comments
 (0)