wjakob / nanobind

nanobind: tiny and efficient C++/Python bindings
BSD 3-Clause "New" or "Revised" License
2.14k stars 161 forks source link

Support arg().none() annotation for ndarray parameter. #526

Closed hpkfft closed 2 months ago

hpkfft commented 2 months ago

It's useful to have an optional ndarray function parameter, e.g., to pass an existing array to a function so as to avoid memory allocation, or None if the function should allocate a new array.

The only thing missing was in from_python in the type caster. The other direction was already supported. The pytest tests the round trip.

wjakob commented 2 months ago

Is there some way to easily find out on the C++ side that the ndarray is invalid? (e.g. a is_valid() check similar to the other wrappers?)

hpkfft commented 2 months ago

Yes, that is already there.

bool is_valid() const

Check whether the array is in a valid state.

hpkfft commented 2 months ago

Note that integral promotion from bool is portable C++ code. The standard requires promotion to 0 or 1 (as appropriate). Also, the compiler generates branch-free code. On x86_64:

        test    rdi, rdi
        setne   al

On AArch64:

        cmp     x0, #0
        cset    x0, ne

I added pytests. As you can see, there's python typing related failures on older versions of python. I'm hoping this is not my fault....

hpkfft commented 2 months ago

It seems somewhat common for a python library function to accept None as an array argument. For example:

wjakob commented 2 months ago

This looks great, thank you!