diff --git a/include/nanobind/stl/variant.h b/include/nanobind/stl/variant.h index c54e367f..9dc7cb77 100644 --- a/include/nanobind/stl/variant.h +++ b/include/nanobind/stl/variant.h @@ -28,9 +28,7 @@ template <> struct type_caster { NB_TYPE_CASTER(std::monostate, const_name("None")); bool from_python(handle src, uint8_t, cleanup_list *) noexcept { - if (src.is_none()) - return true; - return false; + return src.is_none(); } static handle from_cpp(const std::monostate &, rv_policy, @@ -54,6 +52,11 @@ template struct type_caster> { "type caster was registered to intercept this particular " "type, which is not allowed."); + if constexpr (!std::is_pointer_v && is_base_caster_v) { + if (src.is_none()) + return false; + } + CasterT caster; if (!caster.from_python(src, flags, cleanup)) diff --git a/tests/test_stl.cpp b/tests/test_stl.cpp index 95a84910..4e1efc2d 100644 --- a/tests/test_stl.cpp +++ b/tests/test_stl.cpp @@ -256,7 +256,7 @@ NB_MODULE(test_stl_ext, m) { // ----- test43-test50 ------ m.def("variant_copyable", [](std::variant &) {}); - m.def("variant_copyable_none", [](std::variant &) {}, nb::arg("x").none()); + m.def("variant_copyable_none", [](std::variant &) {}, nb::arg("x").none()); m.def("variant_copyable_ptr", [](std::variant &) {}); m.def("variant_copyable_ptr_none", [](std::variant &) {}, nb::arg("x").none()); m.def("variant_ret_var_copyable", []() { return std::variant(); }); diff --git a/tests/test_stl.py b/tests/test_stl.py index 1dda41b3..933d526f 100644 --- a/tests/test_stl.py +++ b/tests/test_stl.py @@ -464,7 +464,7 @@ def test44_std_variant_copyable_none(clean): t.variant_copyable_none(5) t.variant_copyable_none(None) assert t.variant_copyable_none.__doc__ == ( - "variant_copyable_none(x: Optional[Union[test_stl_ext.Copyable, int]]) -> None" + "variant_copyable_none(x: Optional[Union[int, test_stl_ext.Copyable]]) -> None" ) assert_stats( default_constructed=1,