Skip to content

Commit

Permalink
Add type_caster for std::nullopt
Browse files Browse the repository at this point in the history
  • Loading branch information
Qingran Zheng committed Nov 1, 2023
1 parent fe2fbc6 commit c8c0b31
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 6 deletions.
15 changes: 15 additions & 0 deletions include/nanobind/stl/optional.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,20 @@ struct type_caster<std::optional<T>> {
}
};


template <> struct type_caster<std::nullopt_t> {
bool from_python(handle src, uint8_t, cleanup_list *) noexcept {
if (src.is_none())
return true;
return false;
}

static handle from_cpp(std::nullopt_t, rv_policy, cleanup_list *) noexcept {
return none().release();
}

NB_TYPE_CASTER(std::nullopt_t, const_name("None"));
};

NAMESPACE_END(detail)
NAMESPACE_END(NB_NAMESPACE)
1 change: 1 addition & 0 deletions tests/test_stl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ NB_MODULE(test_stl_ext, m) {
m.def("optional_ret_opt_movable_ptr", []() { return new std::optional<Movable *>(new Movable()); });
m.def("optional_ret_opt_none", []() { return std::optional<Movable>(); });
m.def("optional_unbound_type", [](std::optional<int> &x) { return x; }, nb::arg("x") = nb::none());
m.def("optional_unbound_type_with_nullopt_as_default", [](std::optional<int> &x) { return x; }, nb::arg("x") = std::nullopt);

// ----- test43-test50 ------
m.def("variant_copyable", [](std::variant<Copyable, int> &) {});
Expand Down
14 changes: 8 additions & 6 deletions tests/test_stl.py
Original file line number Diff line number Diff line change
Expand Up @@ -438,12 +438,14 @@ def test41_std_optional_ret_opt_none():


def test42_std_optional_unbound_type():
assert t.optional_unbound_type(3) == 3
assert t.optional_unbound_type(None) is None
assert t.optional_unbound_type() is None
assert t.optional_unbound_type.__doc__ == (
"optional_unbound_type(x: Optional[int] = None) -> Optional[int]"
)
for method_name in ("optional_unbound_type", "optional_unbound_type_with_nullopt_as_default"):
method = getattr(t, method_name)
assert method(3) == 3
assert method(None) is None
assert method() is None
assert method.__doc__ == (
f"{method_name}(x: Optional[int] = None) -> Optional[int]"
)


def test43_std_variant_copyable(clean):
Expand Down

0 comments on commit c8c0b31

Please sign in to comment.