mirror of
https://github.com/pybind/pybind11.git
synced 2026-07-14 19:17:12 +00:00
[skip ci] Simplify test case.
This commit is contained in:
@@ -1,41 +1,37 @@
|
||||
// Copyright (c) 2021 The Pybind Development Team.
|
||||
// Copyright (c) 2025 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>
|
||||
#include <memory>
|
||||
|
||||
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; }
|
||||
struct VirtBase {
|
||||
virtual ~VirtBase() = default;
|
||||
virtual int get_code() { return 100; }
|
||||
};
|
||||
|
||||
// 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);
|
||||
struct PyVirtBase : VirtBase, py::trampoline_self_life_support {
|
||||
using VirtBase::VirtBase;
|
||||
int get_code() override { PYBIND11_OVERRIDE(int, VirtBase, get_code); }
|
||||
};
|
||||
|
||||
struct WpOwner {
|
||||
void set_wp(std::shared_ptr<VirtBase> sp) { wp = sp; }
|
||||
|
||||
int get_code() {
|
||||
auto sp = wp.lock();
|
||||
if (!sp) {
|
||||
return -999;
|
||||
}
|
||||
return sp->get_code();
|
||||
}
|
||||
|
||||
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;
|
||||
private:
|
||||
std::weak_ptr<VirtBase> wp;
|
||||
};
|
||||
|
||||
} // namespace class_sh_trampoline_weak_ptr
|
||||
@@ -44,18 +40,12 @@ struct WpBaseTester {
|
||||
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")
|
||||
py::classh<VirtBase, PyVirtBase>(m, "VirtBase")
|
||||
.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);
|
||||
.def("get_code", &VirtBase::get_code);
|
||||
|
||||
py::classh<WpBaseTester>(m, "WpBaseTester")
|
||||
py::classh<WpOwner>(m, "WpOwner")
|
||||
.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);
|
||||
.def("set_wp", &WpOwner::set_wp)
|
||||
.def("get_code", &WpOwner::get_code);
|
||||
}
|
||||
|
||||
@@ -6,31 +6,22 @@ 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
|
||||
class PyDrvd(m.VirtBase):
|
||||
def get_code(self):
|
||||
return 200
|
||||
|
||||
|
||||
@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
|
||||
@pytest.mark.parametrize(("vtype", "expected_code"), [(m.VirtBase, 100), (PyDrvd, 200)])
|
||||
def test_weak_ptr_base(vtype, expected_code):
|
||||
wpo = m.WpOwner()
|
||||
assert wpo.get_code() == -999
|
||||
|
||||
tester = m.WpBaseTester()
|
||||
obj = vtype()
|
||||
assert obj.get_code() == expected_code
|
||||
|
||||
obj = PyChild()
|
||||
wpo.set_wp(obj)
|
||||
assert wpo.get_code() == expected_code
|
||||
|
||||
tester.set_object(obj)
|
||||
|
||||
assert tester.is_expired() is False
|
||||
assert tester.is_base_used() is False
|
||||
assert tester.get_object().is_base_used() is False
|
||||
del obj
|
||||
assert wpo.get_code() == -999
|
||||
|
||||
Reference in New Issue
Block a user