Update on October 24, 2022
This is still not possible currently, but according to this comment on a Numpy GitHub issue, it will be possible once mypy supports PEP 646. Please see the relevant issue on mypy's GitHub repo. That issue is open at the time of writing.
Python 3.11 has been released today with support for PEP646. Once mypy supports PEP646, users will be able to type-hint the shapes of Numpy arrays.
Older answer
It seems like it is not possible to type-hint the shape (or data type) of a numpy.ndarray at this point (September 13, 2022). There are, however, some recent pull requests to numpy working towards this goal.
https://github.com/numpy/numpy/pull/17719
makes the
np.ndarrayclass generic w.r.t. its shape and dtype:np.ndarray[~Shape, ~DType]However, an explicit non-goal of that PR is to make runtime-subscriptable aliases for
numpy.ndarray. According to that PR, those changes will come in later PRs.https://github.com/numpy/numpy/issues/16544
Issue discussing typing support for shapes. It is still open at the time of writing.
PEP 646 is related to this and has been accepted into Python 3.11. According to numpy/numpy issue #16544, one will be able to type-hint shape and data type of arrays after type checkers like mypy add support for PEP 646.
This is possible to do with the nptyping package, but that is not part of numpy.
from typing import Any
from nptyping import NDArray
# Nx3 array with Any data type.
NDArray[(Any, 3), Any]
Answer from jkr on Stack OverflowSyntax for typing multi-dimensional arrays
Typing for multi-dimensional arrays
Type hint to show the dimension of a Numpy ndarray
From a cursory google search NPTyping seems like the most straightforward option.
More on reddit.comWhat's the appropriate type-hint for a function that can accept a list of floats OR a numpy array?
» pip install nptyping
For the code
import numpy as np
def binary_cross_entropy(yhat: np.ndarray, y: np.ndarray) -> float:
"""Compute binary cross-entropy loss for a vector of prediction
return -(y * np.log(yhat) + (1 - y) * np.log(1 - yhat)).mean()
I see that yhat and y are declared as Numpy ndarrays. Is there a way to further specify the rank of the array? For example, you may require that the 1st argument be a rank-1 array (vector) and the 2nd argument a rank-2 array (matrix).
This is what I've got so far
import numpy.typing as npt
def myfunc(mylist : list[float] | npt.NDArray):
print(len(mylist))It works, but I wonder if there's another way to do this that doesn't involve the |?
I tried npt.ArrayLike, but it complains when you try to access an element from an ArrayLike object, i.e. the following program results in an error:
import numpy as np import numpy.typing as npt myvar: npt.ArrayLike = np.array([1,2,3]) # this line is fine print(myvar[0]) # this line throws an error with mypy because apparently ArrayLike is not indexable
There is a numpy.typing module with an NDArray generic type.
From the Numpy 2.3 docs:
numpy.typing.NDArray = numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]]A
np.ndarray[tuple[Any, ...], np.dtype[ScalarT]]type alias generic w.r.t. itsdtype.type.Can be used during runtime for typing arrays with a given dtype and unspecified shape.
Examples:
>>> import numpy as np >>> import numpy.typing as npt >>> print(npt.NDArray) numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]] >>> print(npt.NDArray[np.float64]) numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[numpy.float64]] >>> NDArrayInt = npt.NDArray[np.int_] >>> a: NDArrayInt = np.arange(10) >>> def func(a: npt.ArrayLike) -> npt.NDArray[Any]: ... return np.array(a)
As of 2025-07-17, support for shapes is still a work in progress per numpy/numpy#16544.
Update
Check recent numpy versions for a new typing module
https://numpy.org/doc/stable/reference/typing.html#module-numpy.typing
dated answer
It looks like typing module was developed at:
https://github.com/python/typing
The main numpy repository is at
https://github.com/numpy/numpy
Python bugs and commits can be tracked at
http://bugs.python.org/
The usual way of adding a feature is to fork the main repository, develop the feature till it is bomb proof, and then submit a pull request. Obviously at various points in the process you want feedback from other developers. If you can't do the development yourself, then you have to convince someone else that it is a worthwhile project.
cython has a form of annotations, which it uses to generate efficient C code.
You referenced the array-like paragraph in numpy documentation. Note its typing information:
A simple way to find out if the object can be converted to a numpy array using array() is simply to try it interactively and see if it works! (The Python Way).
In other words the numpy developers refuse to be pinned down. They don't, or can't, describe in words what kinds of objects can or cannot be converted to np.ndarray.
In [586]: np.array({'test':1}) # a dictionary
Out[586]: array({'test': 1}, dtype=object)
In [587]: np.array(['one','two']) # a list
Out[587]:
array(['one', 'two'],
dtype='<U3')
In [589]: np.array({'one','two'}) # a set
Out[589]: array({'one', 'two'}, dtype=object)
For your own functions, an annotation like
def foo(x: np.ndarray) -> np.ndarray:
works. Of course if your function ends up calling some numpy function that passes its argument through asanyarray (as many do), such an annotation would be incomplete, since your input could be a list, or np.matrix, etc.
When evaluating this question and answer, pay attention to the date. 484 was a relatively new PEP back then, and code to make use of it for standard Python still in development. But it looks like the links provided are still valid.