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.
diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h
index 2dec23c..80abb2b 100644
--- a/include/pybind11/cast.h
+++ b/include/pybind11/cast.h
@@ -1611,7 +1611,8 @@
// everything else returns a reference/pointer to a local variable.
template <typename type> using cast_is_temporary_value_reference = bool_constant<
(std::is_reference<type>::value || std::is_pointer<type>::value) &&
- !std::is_base_of<type_caster_generic, make_caster<type>>::value
+ !std::is_base_of<type_caster_generic, make_caster<type>>::value &&
+ !std::is_same<intrinsic_t<type>, void>::value
>;
// When a value returned from a C++ function is being cast back to Python, we almost always want to
diff --git a/tests/test_builtin_casters.cpp b/tests/test_builtin_casters.cpp
index 4508134..e026127 100644
--- a/tests/test_builtin_casters.cpp
+++ b/tests/test_builtin_casters.cpp
@@ -160,4 +160,11 @@
m.def("int_cast", []() {return (int) 42;});
m.def("long_cast", []() {return (long) 42;});
m.def("longlong_cast", []() {return ULLONG_MAX;});
+
+ /// test void* cast operator
+ m.def("test_void_caster", []() -> bool {
+ void *v = (void *) 0xabcd;
+ py::object o = py::cast(v);
+ return py::cast<void *>(o) == v;
+ });
}
diff --git a/tests/test_builtin_casters.py b/tests/test_builtin_casters.py
index 01d0437..73cc465 100644
--- a/tests/test_builtin_casters.py
+++ b/tests/test_builtin_casters.py
@@ -336,3 +336,7 @@
assert isinstance(m.int_cast(), int)
assert isinstance(m.long_cast(), int)
assert isinstance(m.longlong_cast(), must_be_long)
+
+
+def test_void_caster_2():
+ assert m.test_void_caster()