-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Add py::potentially_slicing_weak_ptr(handle)
function
#5624
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
50c3c1e
528d1cc
b160f6c
2fe82b2
ff70657
a481647
32858da
e978d93
1c0b700
4638e01
6cc6368
62d3265
2f672eb
888a295
b20f557
3b4b28c
56d23dc
ff0792e
eb1787c
10f6e78
121c8cf
b42bd11
f160450
78178d7
62d2242
0ecb396
faf1e61
222b4a7
7c4a8bc
03a8981
bad0c12
683fff4
9f379ea
b349e84
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// Copyright (c) 2021 The Pybind Development Team. | ||
// All rights reserved. Use of this source code is governed by a | ||
// BSD-style license that can be found in the LICENSE file. | ||
|
||
#include "pybind11_tests.h" | ||
|
||
#include <utility> | ||
|
||
namespace pybind11_tests { | ||
namespace class_sh_trampoline_weak_ptr { | ||
|
||
// // For testing whether a python subclass of a C++ object can be accessed from a C++ weak_ptr | ||
struct WpBase { | ||
// returns true if the base virtual function is called | ||
virtual bool is_base_used() { return true; } | ||
|
||
// returns true if there's an associated python instance | ||
bool has_python_instance() { | ||
auto *tinfo = py::detail::get_type_info(typeid(WpBase)); | ||
return (bool) py::detail::get_object_handle(this, tinfo); | ||
} | ||
|
||
WpBase() = default; | ||
WpBase(const WpBase &) = delete; | ||
virtual ~WpBase() = default; | ||
}; | ||
|
||
struct PyWpBase : WpBase { | ||
using WpBase::WpBase; | ||
bool is_base_used() override { PYBIND11_OVERRIDE(bool, WpBase, is_base_used); } | ||
}; | ||
|
||
struct WpBaseTester { | ||
std::shared_ptr<WpBase> get_object() const { return m_obj.lock(); } | ||
void set_object(std::shared_ptr<WpBase> obj) { m_obj = obj; } | ||
bool is_expired() { return m_obj.expired(); } | ||
bool is_base_used() { return m_obj.lock()->is_base_used(); } | ||
std::weak_ptr<WpBase> m_obj; | ||
}; | ||
|
||
} // namespace class_sh_trampoline_weak_ptr | ||
} // namespace pybind11_tests | ||
|
||
using namespace pybind11_tests::class_sh_trampoline_weak_ptr; | ||
|
||
TEST_SUBMODULE(class_sh_trampoline_weak_ptr, m) { | ||
// For testing whether a python subclass of a C++ object can be accessed from a C++ weak_ptr | ||
|
||
py::classh<WpBase, PyWpBase>(m, "WpBase") | ||
.def(py::init<>()) | ||
.def(py::init([](int) { return std::make_shared<PyWpBase>(); })) | ||
.def("is_base_used", &WpBase::is_base_used) | ||
.def("has_python_instance", &WpBase::has_python_instance); | ||
|
||
py::classh<WpBaseTester>(m, "WpBaseTester") | ||
.def(py::init<>()) | ||
.def("get_object", &WpBaseTester::get_object) | ||
.def("set_object", &WpBaseTester::set_object) | ||
.def("is_expired", &WpBaseTester::is_expired) | ||
.def("is_base_used", &WpBaseTester::is_base_used); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
from __future__ import annotations | ||
|
||
import pytest | ||
|
||
import env # noqa: F401 | ||
import pybind11_tests.class_sh_trampoline_weak_ptr as m | ||
|
||
|
||
@pytest.mark.skipif("env.GRAALPY", reason="Cannot reliably trigger GC") | ||
def test_weak_ptr_base(): | ||
tester = m.WpBaseTester() | ||
|
||
obj = m.WpBase() | ||
|
||
tester.set_object(obj) | ||
|
||
assert tester.is_expired() is False | ||
assert tester.is_base_used() is True | ||
assert tester.get_object().is_base_used() is True | ||
|
||
|
||
@pytest.mark.skipif("env.GRAALPY", reason="Cannot reliably trigger GC") | ||
def test_weak_ptr_child(): | ||
class PyChild(m.WpBase): | ||
def is_base_used(self): | ||
return False | ||
|
||
tester = m.WpBaseTester() | ||
|
||
obj = PyChild() | ||
|
||
tester.set_object(obj) | ||
|
||
assert tester.is_expired() is False | ||
Check failure on line 34 in tests/test_class_sh_trampoline_weak_ptr.py
|
||
assert tester.is_base_used() is False | ||
assert tester.get_object().is_base_used() is False |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does that help?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(I just fixed an oversight in my previous comment.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.