Skip to content

Commit cea4246

Browse files
authored
fix py::cast<void *> (#1605)
Pybind11 provides a cast operator between opaque void* pointers on the C++ side and capsules on the Python side. The py::cast<void *> expression was not aware of this possibility and incorrectly triggered a compile-time assertion ("Unable to cast type to reference: value is local to type caster") that is now fixed.
1 parent e2eca4f commit cea4246

File tree

3 files changed

+13
-1
lines changed

3 files changed

+13
-1
lines changed

include/pybind11/cast.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -1611,7 +1611,8 @@ template <typename T> using move_never = none_of<move_always<T>, move_if_unrefer
16111611
// everything else returns a reference/pointer to a local variable.
16121612
template <typename type> using cast_is_temporary_value_reference = bool_constant<
16131613
(std::is_reference<type>::value || std::is_pointer<type>::value) &&
1614-
!std::is_base_of<type_caster_generic, make_caster<type>>::value
1614+
!std::is_base_of<type_caster_generic, make_caster<type>>::value &&
1615+
!std::is_same<intrinsic_t<type>, void>::value
16151616
>;
16161617

16171618
// When a value returned from a C++ function is being cast back to Python, we almost always want to

tests/test_builtin_casters.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -160,4 +160,11 @@ TEST_SUBMODULE(builtin_casters, m) {
160160
m.def("int_cast", []() {return (int) 42;});
161161
m.def("long_cast", []() {return (long) 42;});
162162
m.def("longlong_cast", []() {return ULLONG_MAX;});
163+
164+
/// test void* cast operator
165+
m.def("test_void_caster", []() -> bool {
166+
void *v = (void *) 0xabcd;
167+
py::object o = py::cast(v);
168+
return py::cast<void *>(o) == v;
169+
});
163170
}

tests/test_builtin_casters.py

+4
Original file line numberDiff line numberDiff line change
@@ -336,3 +336,7 @@ def test_int_long():
336336
assert isinstance(m.int_cast(), int)
337337
assert isinstance(m.long_cast(), int)
338338
assert isinstance(m.longlong_cast(), must_be_long)
339+
340+
341+
def test_void_caster_2():
342+
assert m.test_void_caster()

0 commit comments

Comments
 (0)