Fix std::nullptr_t caster (#840)
* Fix compilation error with std::nullptr_t
* Enable conversion from None to std::nullptr_t and std::nullopt_t
Fixes #839.
diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h
index 6ca49a8..1514fab 100644
--- a/include/pybind11/cast.h
+++ b/include/pybind11/cast.h
@@ -602,7 +602,11 @@
template<typename T> struct void_caster {
public:
- bool load(handle, bool) { return false; }
+ bool load(handle src, bool) {
+ if (src && src.is_none())
+ return true;
+ return false;
+ }
static handle cast(T, return_value_policy /* policy */, handle /* parent */) {
return none().inc_ref();
}
@@ -653,7 +657,7 @@
void *value = nullptr;
};
-template <> class type_caster<std::nullptr_t> : public type_caster<void_type> { };
+template <> class type_caster<std::nullptr_t> : public void_caster<std::nullptr_t> { };
template <> class type_caster<bool> {
public:
diff --git a/tests/test_python_types.cpp b/tests/test_python_types.cpp
index 776c4ce..a82145b 100644
--- a/tests/test_python_types.cpp
+++ b/tests/test_python_types.cpp
@@ -359,9 +359,10 @@
const char *operator()(int) { return "int"; }
const char *operator()(std::string) { return "std::string"; }
const char *operator()(double) { return "double"; }
+ const char *operator()(std::nullptr_t) { return "std::nullptr_t"; }
};
- m.def("load_variant", [](std::variant<int, std::string, double> v) {
+ m.def("load_variant", [](std::variant<int, std::string, double, std::nullptr_t> v) {
return std::visit(visitor(), v);
});
@@ -516,6 +517,9 @@
});
}
);
+
+ m.def("load_nullptr_t", [](std::nullptr_t) {}); // not useful, but it should still compile
+ m.def("cast_nullptr_t", []() { return std::nullptr_t{}; });
});
#if defined(_MSC_VER)
diff --git a/tests/test_python_types.py b/tests/test_python_types.py
index 45cf3e8..3e337d4 100644
--- a/tests/test_python_types.py
+++ b/tests/test_python_types.py
@@ -378,9 +378,10 @@
assert load_variant(1) == "int"
assert load_variant("1") == "std::string"
assert load_variant(1.0) == "double"
+ assert load_variant(None) == "std::nullptr_t"
assert cast_variant() == (5, "Hello")
- assert doc(load_variant) == "load_variant(arg0: Union[int, str, float]) -> str"
+ assert doc(load_variant) == "load_variant(arg0: Union[int, str, float, None]) -> str"
def test_constructors():
@@ -568,3 +569,10 @@
creating capsule
destructing capsule: 1234
"""
+
+
+def test_void_caster():
+ import pybind11_tests as m
+
+ assert m.load_nullptr_t(None) is None
+ assert m.cast_nullptr_t() is None