Skip to content

Add holder caster traits tests in test_smart_ptr.cpp,py #5603

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

Merged
merged 2 commits into from
Apr 10, 2025
Merged
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
6 changes: 4 additions & 2 deletions tests/test_native_enum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,13 @@ struct is_proto_enum<some_proto_enum> : std::true_type {};
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
PYBIND11_NAMESPACE_BEGIN(detail)

// Negate this condition to demonstrate "ambiguous template instantiation" compilation error:
#if defined(PYBIND11_HAS_NATIVE_ENUM)
template <typename ProtoEnumType>
struct type_caster_enum_type_enabled<
ProtoEnumType,
detail::enable_if_t<test_native_enum::is_proto_enum<ProtoEnumType>::value>> : std::false_type {
};
enable_if_t<test_native_enum::is_proto_enum<ProtoEnumType>::value>> : std::false_type {};
#endif

// https://github.com/pybind/pybind11_protobuf/blob/a50899c2eb604fc5f25deeb8901eff6231b8b3c0/pybind11_protobuf/enum_type_caster.h#L101-L105
template <typename ProtoEnumType>
Expand Down
68 changes: 68 additions & 0 deletions tests/test_smart_ptr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,72 @@ PYBIND11_DECLARE_HOLDER_TYPE(T, custom_unique_ptr<T>)
PYBIND11_DECLARE_HOLDER_TYPE(T, shared_ptr_with_addressof_operator<T>)
PYBIND11_DECLARE_HOLDER_TYPE(T, unique_ptr_with_addressof_operator<T>)

namespace holder_caster_traits_test {
struct example_base {};
} // namespace holder_caster_traits_test

PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
PYBIND11_NAMESPACE_BEGIN(detail)

// Negate this condition to demonstrate "ambiguous template instantiation" compilation error:
#if defined(PYBIND11_HAS_INTERNALS_WITH_SMART_HOLDER_SUPPORT)
template <typename ExampleType>
struct copyable_holder_caster_shared_ptr_with_smart_holder_support_enabled<
ExampleType,
enable_if_t<std::is_base_of<holder_caster_traits_test::example_base, ExampleType>::value>>
: std::false_type {};
#endif

template <typename ExampleType, typename HolderType>
struct copyable_holder_caster<
ExampleType,
HolderType,
enable_if_t<std::is_base_of<holder_caster_traits_test::example_base, ExampleType>::value>> {
static constexpr auto name = const_name<ExampleType>();

static handle cast(const HolderType &, return_value_policy, handle) {
return str("copyable_holder_caster_traits_test").release();
}
};

// Negate this condition to demonstrate "ambiguous template instantiation" compilation error:
#if defined(PYBIND11_HAS_INTERNALS_WITH_SMART_HOLDER_SUPPORT)
template <typename ExampleType>
struct move_only_holder_caster_unique_ptr_with_smart_holder_support_enabled<
ExampleType,
enable_if_t<std::is_base_of<holder_caster_traits_test::example_base, ExampleType>::value>>
: std::false_type {};
#endif

template <typename ExampleType, typename HolderType>
struct move_only_holder_caster<
ExampleType,
HolderType,
enable_if_t<std::is_base_of<holder_caster_traits_test::example_base, ExampleType>::value>> {
static constexpr auto name = const_name<ExampleType>();

static handle cast(const HolderType &, return_value_policy, handle) {
return str("move_only_holder_caster_traits_test").release();
}
};

PYBIND11_NAMESPACE_END(detail)
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)

namespace holder_caster_traits_test {

struct example_drvd : example_base {};

void wrap(py::module_ &m) {
m.def("return_std_shared_ptr_example_drvd",
// NOLINTNEXTLINE(modernize-make-shared)
[]() { return std::shared_ptr<example_drvd>(new example_drvd()); });
m.def("return_std_unique_ptr_example_drvd",
[]() { return std::unique_ptr<example_drvd>(new example_drvd()); });
}

} // namespace holder_caster_traits_test

TEST_SUBMODULE(smart_ptr, m) {
// Please do not interleave `struct` and `class` definitions with bindings code,
// but implement `struct`s and `class`es in the anonymous namespace above.
Expand Down Expand Up @@ -482,4 +548,6 @@ TEST_SUBMODULE(smart_ptr, m) {
.def(py::init<>())
.def_readwrite("ptr",
&ContainerUsingPrivateESFT::ptr); // <- access ESFT through shared_ptr

holder_caster_traits_test::wrap(m);
}
12 changes: 12 additions & 0 deletions tests/test_smart_ptr.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,3 +338,15 @@ def test_private_esft_tolerance():
_ = c.ptr # getattr
with pytest.raises(TypeError):
c.ptr = None # setattr


def test_copyable_holder_caster_shared_ptr_with_smart_holder_support_enabled():
assert (
m.return_std_shared_ptr_example_drvd() == "copyable_holder_caster_traits_test"
)


def test_move_only_holder_caster_shared_ptr_with_smart_holder_support_enabled():
assert (
m.return_std_unique_ptr_example_drvd() == "move_only_holder_caster_traits_test"
)