Skip to content

Commit a5665e3

Browse files
authored
fix: type_caster_enum_type for pointer types (#5694) (#5776)
Add pointer overload to type_caster_enum_type::cast method to handle enum pointer casting. Fixes compilation error when returning pointers to enum types from bound functions. Experiment for validation: Temporarily undo the changes in include/pybind11/cast.h: ``` g++ -o pybind11/tests/test_native_enum.os -c -std=c++20 -fPIC -fvisibility=hidden -O0 -g -Wall -Wextra -Wconversion -Wcast-qual -Wdeprecated -Wundef -Wnon-virtual-dtor -Wunused-result -Werror -funsigned-char -Wpedantic -isystem /usr/include/python3.12 -isystem /usr/include/eigen3 -DPYBIND11_SMART_HOLDER_PADDING_ON -DPYBIND11_STRICT_ASSERTS_CLASS_HOLDER_VS_TYPE_CASTER_MIX -DPYBIND11_ENABLE_TYPE_CASTER_ODR_GUARD_IF_AVAILABLE -DPYBIND11_TEST_BOOST -Ipybind11/include -I/home/rgrossekunst/forked/pybind11/include -I/home/rgrossekunst/clone/pybind11/include /home/rgrossekunst/forked/pybind11/tests/test_native_enum.cpp In file included from /home/rgrossekunst/forked/pybind11/include/pybind11/native_enum.h:10, from /home/rgrossekunst/forked/pybind11/tests/test_native_enum.cpp:1: /home/rgrossekunst/forked/pybind11/include/pybind11/cast.h: In instantiation of ‘static pybind11::handle pybind11::detail::type_caster_enum_type<EnumType>::cast(SrcType&&, pybind11::return_value_policy, pybind11::handle) [with SrcType = const test_native_enum::color*; EnumType = test_native_enum::color]’: /home/rgrossekunst/forked/pybind11/include/pybind11/pybind11.h:429:40: required from ‘void pybind11::cpp_function::initialize(Func&&, Return (*)(Args ...), const Extra& ...) [with Func = test_submodule_native_enum(pybind11::module_&)::<lambda()>; Return = const test_native_enum::color*; Args = {}; Extra = {pybind11::name, pybind11::scope, pybind11::sibling}]’ /home/rgrossekunst/forked/pybind11/include/pybind11/pybind11.h:274:19: required from ‘pybind11::cpp_function::cpp_function(Func&&, const Extra& ...) [with Func = test_submodule_native_enum(pybind11::module_&)::<lambda()>; Extra = {pybind11::name, pybind11::scope, pybind11::sibling}; <template-parameter-1-3> = void]’ /home/rgrossekunst/forked/pybind11/include/pybind11/pybind11.h:1384:22: required from ‘pybind11::module_& pybind11::module_::def(const char*, Func&&, const Extra& ...) [with Func = test_submodule_native_enum(pybind11::module_&)::<lambda()>; Extra = {}]’ /home/rgrossekunst/forked/pybind11/tests/test_native_enum.cpp:139:10: required from here /home/rgrossekunst/forked/pybind11/include/pybind11/cast.h:70:32: error: invalid ‘static_cast’ from type ‘const test_native_enum::color*’ to type ‘pybind11::detail::type_caster_enum_type<test_native_enum::color>::Underlying’ {aka ‘unsigned int’} 70 | return native_enum(static_cast<Underlying>(src)).release(); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/rgrossekunst/forked/pybind11/include/pybind11/cast.h: In instantiation of ‘static pybind11::handle pybind11::detail::type_caster_enum_type<EnumType>::cast(SrcType&&, pybind11::return_value_policy, pybind11::handle) [with SrcType = test_native_enum::color*; EnumType = test_native_enum::color]’: /home/rgrossekunst/forked/pybind11/include/pybind11/pybind11.h:429:40: required from ‘void pybind11::cpp_function::initialize(Func&&, Return (*)(Args ...), const Extra& ...) [with Func = test_submodule_native_enum(pybind11::module_&)::<lambda()>; Return = test_native_enum::color*; Args = {}; Extra = {pybind11::name, pybind11::scope, pybind11::sibling}]’ /home/rgrossekunst/forked/pybind11/include/pybind11/pybind11.h:274:19: required from ‘pybind11::cpp_function::cpp_function(Func&&, const Extra& ...) [with Func = test_submodule_native_enum(pybind11::module_&)::<lambda()>; Extra = {pybind11::name, pybind11::scope, pybind11::sibling}; <template-parameter-1-3> = void]’ /home/rgrossekunst/forked/pybind11/include/pybind11/pybind11.h:1384:22: required from ‘pybind11::module_& pybind11::module_::def(const char*, Func&&, const Extra& ...) [with Func = test_submodule_native_enum(pybind11::module_&)::<lambda()>; Extra = {}]’ /home/rgrossekunst/forked/pybind11/tests/test_native_enum.cpp:143:10: required from here /home/rgrossekunst/forked/pybind11/include/pybind11/cast.h:70:32: error: invalid ‘static_cast’ from type ‘test_native_enum::color*’ to type ‘pybind11::detail::type_caster_enum_type<test_native_enum::color>::Underlying’ {aka ‘unsigned int’} ```
1 parent 9360553 commit a5665e3

File tree

3 files changed

+19
-0
lines changed

3 files changed

+19
-0
lines changed

include/pybind11/cast.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ class type_caster_enum_type {
7676
parent);
7777
}
7878

79+
template <typename SrcType>
80+
static handle cast(SrcType *src, return_value_policy policy, handle parent) {
81+
return cast(*src, policy, parent);
82+
}
83+
7984
bool load(handle src, bool convert) {
8085
handle native_enum
8186
= global_internals_native_enum_type_map_get_item(std::type_index(typeid(EnumType)));

tests/test_native_enum.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,15 @@ TEST_SUBMODULE(native_enum, m) {
136136
m.def("pass_color", [](color e) { return static_cast<int>(e); });
137137
m.def("return_color", [](int i) { return static_cast<color>(i); });
138138

139+
m.def("return_color_const_ptr", []() -> const color * {
140+
static const color test_color = color::red;
141+
return &test_color;
142+
});
143+
m.def("return_color_mutbl_ptr", []() -> color * {
144+
static color test_color = color::green;
145+
return &test_color;
146+
});
147+
139148
py::native_enum<func_sig_rendering>(m, "func_sig_rendering", "enum.Enum").finalize();
140149
m.def(
141150
"pass_and_return_func_sig_rendering",

tests/test_native_enum.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,11 @@ def test_return_color_fail():
153153
assert str(excinfo_cast.value) == str(excinfo_direct.value)
154154

155155

156+
def test_return_color_ptr():
157+
assert m.return_color_const_ptr() == m.color.red
158+
assert m.return_color_mutbl_ptr() == m.color.green
159+
160+
156161
def test_property_type_hint():
157162
prop = m.class_with_enum.__dict__["nested_value"]
158163
assert isinstance(prop, property)

0 commit comments

Comments
 (0)