-
Notifications
You must be signed in to change notification settings - Fork 200
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use NDArray
instead of ArrayLike
when dtype
is given
#442
base: master
Are you sure you want to change the base?
Conversation
I am not sure why the test for pypy3.10 failed, but all the tests passed on my fork. |
Doesn't |
I'm actually not set on |
Sorry, I had assumed that stubgen was annotating ndarray for Numpy. However, I think module.def("ndarray_func1", [](nb::ndarray<std::int32_t> arr) {}); def ndarray_func1(arg: Annotated[ArrayLike, dict(dtype='int32')], /) -> None: >>> ndarray_func1([1,2,3]) # type checking OK, but...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: ndarray_func1(): incompatible function arguments. The following argument types are supported:
1. ndarray_func1(arg: ndarray[dtype=int32], /) -> None
Invoked with types: list On the other hand, as you say, import torch
import test
test.ndarray_func1(torch.tensor([1, 2, 3]))
I am currently trying to use jaxtyping, but I have not successfully checked multiple array types at once with dtype specified. |
Since numpy is the only user module in nanobind that can be imported, what about the following idea about post-processing in stubgen? When
Framework is not specified for input arguments:
Framework is not specified for return values:
|
I think that your answer applies to the output end (A function returning an nd-array in a specific framework). On the input end, the situation is rather more complex. Nanobind will accept anything that implements the buffer protocol or DLPack protocol as input. That could be encoded as follows: # Contents of a hypothetical nanobind.typing module
from collections.abc import Buffer
from typing import Protocol, Any, TypeAlias, Union
from types import CapsuleType
class DLPackBuffer(Protocol):
def __dlpack__(
self,
stream: Any = None,
max_version: tuple[int, int] | None = None,
dl_device: Any | None = None,
copy: bool | None = None,
) -> CapsuleType: ...
NDArray: TypeAlias = Union[Buffer, DLPackBuffer] |
cf0dd0e
to
ba12ce8
Compare
@wjakob Could you review the last commit (force pushed) in this PR? The changes are as follows:
Please see the example stub file in tests: https://github.com/wjakob/nanobind/blob/ba12ce8ce410bdea65bf03f205f3e8d990019150/tests/test_ndarray_ext.pyi.ref |
56d7e93
to
e80edb1
Compare
c30294a
to
af57451
Compare
d7117a4
to
983d6c0
Compare
I'm arriving here from this discussion @wjakob I switched my codebase to build with this fork and am able to get rid of my sed post-processing hack on the pyi file. The generated types when using this branch appear to have essentially the same semantics as what I got by hackily string replacing |
ba12ce8
to
2651557
Compare
2651557
to
579a69e
Compare
f9e5e0b
to
30e96b7
Compare
f3e2796
to
bff96e2
Compare
If it is already clear at compile-time that nanobind will return a concrete import nbmod
arr = nbmod.numpyArray()
arr.sum() # flagged
Also, I think that a concrete import numpy as np
from typing import Literal
type VecF[N: int] = np.ndarray[tuple[N], np.dtype[np.float64]]
type VecF2 = VecF[Literal[2]]
type Mat2xF[N: int] = np.ndarray[tuple[Literal[2], N], np.dtype[np.float64]]
def func(vec: VecF2):
pass |
For
ndarray
typing, I would like to suggest using NDArray instead of ArrayLike when thedtype
is given.The NDArray has data type annotation while ArrayLike appears to treat the data type as Any.