Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 513ee4c

Browse files
committedAug 13, 2024·
support None for const char* arg, with minimal overhead
Since pybind11 also accepts None for const char* as an exception among built-in types, remove a paragraph about differences in porting.rst.
1 parent 8e5fd14 commit 513ee4c

File tree

5 files changed

+10
-10
lines changed

5 files changed

+10
-10
lines changed
 

‎docs/api_core.rst

+5-3
Original file line numberDiff line numberDiff line change
@@ -1622,9 +1622,11 @@ parameter of :cpp:func:`module_::def`, :cpp:func:`class_::def`,
16221622

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

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

‎docs/porting.rst

-6
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,6 @@ It is also possible to set a ``None`` default value, in which case the
8686
8787
m.def("func", &func, "arg"_a = nb::none());
8888
89-
``None``-valued arguments are only supported by two of the three parameter
90-
passing styles described in the section on :ref:`information exchange
91-
<exchange>`. In particular, they are supported by :ref:`bindings <bindings>`
92-
and :ref:`wrappers <wrappers>`, *but not* by :ref:`type casters
93-
<type_casters>`.
94-
9589
Shared pointers and holders
9690
---------------------------
9791

‎include/nanobind/nb_cast.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,8 @@ template <> struct type_caster<char> {
286286
value = PyUnicode_AsUTF8AndSize(src.ptr(), &size);
287287
if (!value) {
288288
PyErr_Clear();
289-
return false;
289+
// optimize for src being a string, check for None afterwards
290+
return src.is_none();
290291
}
291292
return true;
292293
}

‎tests/test_functions.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ NB_MODULE(test_functions_ext, m) {
161161

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

‎tests/test_functions.py

+2
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,8 @@ def test21_numpy_overloads():
236236

237237
def test22_string_return():
238238
assert t.test_12("hello") == "hello"
239+
assert t.test_12_n("hello") == "hello"
240+
assert t.test_12_n(None) == "n/a"
239241
assert t.test_13() == "test"
240242
assert t.test_14("abc") == "abc"
241243

0 commit comments

Comments
 (0)