Skip to content

Commit 78f1dcf

Browse files
authored
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.
1 parent 77710ff commit 78f1dcf

File tree

3 files changed

+20
-4
lines changed

3 files changed

+20
-4
lines changed

include/pybind11/cast.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,11 @@ struct type_caster<T, enable_if_t<std::is_arithmetic<T>::value && !is_std_char_t
602602

603603
template<typename T> struct void_caster {
604604
public:
605-
bool load(handle, bool) { return false; }
605+
bool load(handle src, bool) {
606+
if (src && src.is_none())
607+
return true;
608+
return false;
609+
}
606610
static handle cast(T, return_value_policy /* policy */, handle /* parent */) {
607611
return none().inc_ref();
608612
}
@@ -653,7 +657,7 @@ template <> class type_caster<void> : public type_caster<void_type> {
653657
void *value = nullptr;
654658
};
655659

656-
template <> class type_caster<std::nullptr_t> : public type_caster<void_type> { };
660+
template <> class type_caster<std::nullptr_t> : public void_caster<std::nullptr_t> { };
657661

658662
template <> class type_caster<bool> {
659663
public:

tests/test_python_types.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,9 +359,10 @@ test_initializer python_types([](py::module &m) {
359359
const char *operator()(int) { return "int"; }
360360
const char *operator()(std::string) { return "std::string"; }
361361
const char *operator()(double) { return "double"; }
362+
const char *operator()(std::nullptr_t) { return "std::nullptr_t"; }
362363
};
363364

364-
m.def("load_variant", [](std::variant<int, std::string, double> v) {
365+
m.def("load_variant", [](std::variant<int, std::string, double, std::nullptr_t> v) {
365366
return std::visit(visitor(), v);
366367
});
367368

@@ -516,6 +517,9 @@ test_initializer python_types([](py::module &m) {
516517
});
517518
}
518519
);
520+
521+
m.def("load_nullptr_t", [](std::nullptr_t) {}); // not useful, but it should still compile
522+
m.def("cast_nullptr_t", []() { return std::nullptr_t{}; });
519523
});
520524

521525
#if defined(_MSC_VER)

tests/test_python_types.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,9 +378,10 @@ def test_variant(doc):
378378
assert load_variant(1) == "int"
379379
assert load_variant("1") == "std::string"
380380
assert load_variant(1.0) == "double"
381+
assert load_variant(None) == "std::nullptr_t"
381382
assert cast_variant() == (5, "Hello")
382383

383-
assert doc(load_variant) == "load_variant(arg0: Union[int, str, float]) -> str"
384+
assert doc(load_variant) == "load_variant(arg0: Union[int, str, float, None]) -> str"
384385

385386

386387
def test_constructors():
@@ -568,3 +569,10 @@ def test_capsule_with_destructor(capture):
568569
creating capsule
569570
destructing capsule: 1234
570571
"""
572+
573+
574+
def test_void_caster():
575+
import pybind11_tests as m
576+
577+
assert m.load_nullptr_t(None) is None
578+
assert m.cast_nullptr_t() is None

0 commit comments

Comments
 (0)