Skip to content

Commit

Permalink
support None for const char* arg, with minimal overhead
Browse files Browse the repository at this point in the history
Since pybind11 also accepts None for const char* as an exception among
built-in types, remove a paragraph about differences in porting.rst.
  • Loading branch information
wojdyr committed Aug 13, 2024
1 parent 8e5fd14 commit 513ee4c
Show file tree
Hide file tree
Showing 5 changed files with 10 additions and 10 deletions.
8 changes: 5 additions & 3 deletions docs/api_core.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1622,9 +1622,11 @@ parameter of :cpp:func:`module_::def`, :cpp:func:`class_::def`,

Set a flag noting that the function argument accepts ``None``. Can only
be used for python wrapper types (e.g. :cpp:class:`handle`,
:cpp:class:`int_`) and types that have been bound using
:cpp:class:`class_`. You cannot use this to implement functions that
accept null pointers to builtin C++ types like ``int *i = nullptr``.
:cpp:class:`int_`), for types that have been bound using
:cpp:class:`class_`, for :cpp:class:`ndarray`, ``std::optional``,
``std::variant``, and ``const char*``.
You cannot use this to implement functions that
accept null pointers to other builtin C++ types like ``int *i = nullptr``.

.. cpp:function:: arg &noconvert(bool value = true)

Expand Down
6 changes: 0 additions & 6 deletions docs/porting.rst
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,6 @@ It is also possible to set a ``None`` default value, in which case the
m.def("func", &func, "arg"_a = nb::none());
``None``-valued arguments are only supported by two of the three parameter
passing styles described in the section on :ref:`information exchange
<exchange>`. In particular, they are supported by :ref:`bindings <bindings>`
and :ref:`wrappers <wrappers>`, *but not* by :ref:`type casters
<type_casters>`.

Shared pointers and holders
---------------------------

Expand Down
3 changes: 2 additions & 1 deletion include/nanobind/nb_cast.h
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,8 @@ template <> struct type_caster<char> {
value = PyUnicode_AsUTF8AndSize(src.ptr(), &size);
if (!value) {
PyErr_Clear();
return false;
// optimize for src being a string, check for None afterwards
return src.is_none();
}
return true;
}
Expand Down
1 change: 1 addition & 0 deletions tests/test_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ NB_MODULE(test_functions_ext, m) {

// Test string caster
m.def("test_12", [](const char *c) { return nb::str(c); });
m.def("test_12_n", [](const char *c) { return nb::str(c ? c : "n/a"); }, nb::arg().none());
m.def("test_13", []() -> const char * { return "test"; });
m.def("test_14", [](nb::object o) -> const char * { return nb::cast<const char *>(o); });

Expand Down
2 changes: 2 additions & 0 deletions tests/test_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,8 @@ def test21_numpy_overloads():

def test22_string_return():
assert t.test_12("hello") == "hello"
assert t.test_12_n("hello") == "hello"
assert t.test_12_n(None) == "n/a"
assert t.test_13() == "test"
assert t.test_14("abc") == "abc"

Expand Down

0 comments on commit 513ee4c

Please sign in to comment.