Skip to content
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

[For debugging only] class_sh_shared_ptr_copy_move_master #5231

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ set(PYBIND11_TEST_FILES
test_callbacks
test_chrono
test_class
test_class_sh_shared_ptr_copy_move
test_const_name
test_constants_and_functions
test_copy_move
Expand Down
87 changes: 87 additions & 0 deletions tests/test_class_sh_shared_ptr_copy_move.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#include "pybind11_tests.h"

#include <memory>
#include <string>
#include <vector>

namespace pybind11_tests {
namespace {

const std::string fooNames[] = {"ShPtr_"};

template <int SerNo>
struct Foo {
std::string history;
explicit Foo(const std::string &history_) : history(history_) {}
Foo(const Foo &other) : history(other.history + "_CpCtor") {}
Foo(Foo &&other) noexcept : history(other.history + "_MvCtor") {}
Foo &operator=(const Foo &other) {
history = other.history + "_OpEqLv";
return *this;
}
Foo &operator=(Foo &&other) noexcept {
history = other.history + "_OpEqRv";
return *this;
}
std::string get_history() const { return "Foo" + fooNames[SerNo] + history; }
};

using FooShPtr = Foo<0>;

struct Outer {
std::shared_ptr<FooShPtr> ShPtr;
Outer() : ShPtr(std::make_shared<FooShPtr>("Outer")) {}
std::shared_ptr<FooShPtr> getShPtr() const { return ShPtr; }
};

} // namespace
} // namespace pybind11_tests

namespace pybind11_tests {

TEST_SUBMODULE(class_sh_shared_ptr_copy_move, m) {
namespace py = pybind11;

py::class_<FooShPtr, std::shared_ptr<FooShPtr>>(m, "FooShPtr")
.def("get_history", &FooShPtr::get_history);

auto outer = py::class_<Outer>(m, "Outer").def(py::init());
#define MAKE_PROP(PropTyp) MAKE_PROP_FOO(ShPtr, PropTyp)

#define MAKE_PROP_FOO(FooTyp, PropTyp) \
.def_##PropTyp(#FooTyp "_" #PropTyp "_default", &Outer::FooTyp) \
.def_##PropTyp( \
#FooTyp "_" #PropTyp "_copy", &Outer::FooTyp, py::return_value_policy::copy) \
.def_##PropTyp( \
#FooTyp "_" #PropTyp "_move", &Outer::FooTyp, py::return_value_policy::move)
outer MAKE_PROP(readonly) MAKE_PROP(readwrite);
#undef MAKE_PROP_FOO

#define MAKE_PROP_FOO(FooTyp, PropTyp) \
.def_##PropTyp(#FooTyp "_property_" #PropTyp "_default", &Outer::FooTyp) \
.def_property_##PropTyp(#FooTyp "_property_" #PropTyp "_copy", \
&Outer::get##FooTyp, \
py::return_value_policy::copy) \
.def_property_##PropTyp(#FooTyp "_property_" #PropTyp "_move", \
&Outer::get##FooTyp, \
py::return_value_policy::move)
outer MAKE_PROP(readonly);
#undef MAKE_PROP_FOO
#undef MAKE_PROP

m.def("test_ShPtr_copy", []() {
auto o = std::make_shared<FooShPtr>("copy");
auto l = py::list();
l.append(o);
return l;
});

m.def("test_ShPtr_move", []() {
auto o = std::make_shared<FooShPtr>("move");
auto l = py::list();
l.append(std::move(o));
return l;
});
}

} // namespace pybind11_tests
31 changes: 31 additions & 0 deletions tests/test_class_sh_shared_ptr_copy_move.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from __future__ import annotations

from pybind11_tests import class_sh_shared_ptr_copy_move as m


def test_shptr_copy():
txt = m.test_ShPtr_copy()[0].get_history()
assert txt == "FooShPtr_copy"


def test_shptr_move():
txt = m.test_ShPtr_move()[0].get_history()
assert txt == "FooShPtr_move"


def _check_property(foo_typ, prop_typ, policy):
o = m.Outer()
name = f"{foo_typ}_{prop_typ}_{policy}"
history = f"Foo{foo_typ}_Outer"
f = getattr(o, name)
assert f.get_history() == history
# and try again to check that o did not get changed
f = getattr(o, name)
assert f.get_history() == history


def test_properties():
for prop_typ in ("readonly", "readwrite", "property_readonly"):
for foo_typ in ("ShPtr",):
for policy in ("default", "copy", "move"):
_check_property(foo_typ, prop_typ, policy)