summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--numpy/__init__.pyi59
-rw-r--r--numpy/core/function_base.pyi13
-rw-r--r--numpy/lib/function_base.pyi308
-rw-r--r--numpy/typing/tests/data/fail/lib_function_base.pyi19
-rw-r--r--numpy/typing/tests/data/fail/ndarray_misc.pyi4
-rw-r--r--numpy/typing/tests/data/reveal/lib_function_base.pyi99
-rw-r--r--numpy/typing/tests/data/reveal/ndarray_misc.pyi11
7 files changed, 474 insertions, 39 deletions
diff --git a/numpy/__init__.pyi b/numpy/__init__.pyi
index c78d48cc6..69f18fac4 100644
--- a/numpy/__init__.pyi
+++ b/numpy/__init__.pyi
@@ -197,6 +197,7 @@ from typing import (
Final,
final,
ClassVar,
+ Set,
)
# Ensures that the stubs are picked up
@@ -828,24 +829,6 @@ class poly1d:
def integ(self, m=..., k=...): ...
def deriv(self, m=...): ...
-class vectorize:
- pyfunc: Any
- cache: Any
- signature: Any
- otypes: Any
- excluded: Any
- __doc__: Any
- def __init__(
- self,
- pyfunc,
- otypes: Any = ...,
- doc: Any = ...,
- excluded: Any = ...,
- cache: Any = ...,
- signature: Any = ...,
- ) -> None: ...
- def __call__(self, *args: Any, **kwargs: Any) -> Any: ...
-
# Some of these are aliases; others are wrappers with an identical signature
round = around
round_ = around
@@ -1181,8 +1164,6 @@ class _ArrayOrScalarCommon:
# generics and 0d arrays return builtin scalars
def tolist(self) -> Any: ...
- # TODO: Add proper signatures
- def __getitem__(self, key) -> Any: ...
@property
def __array_interface__(self): ...
@property
@@ -1679,6 +1660,26 @@ class ndarray(_ArrayOrScalarCommon, Generic[_ShapeType, _DType_co]):
/,
) -> ndarray[_ShapeType2, _DType]: ...
+ @overload
+ def __getitem__(self, key: Union[
+ SupportsIndex,
+ _ArrayLikeInt_co,
+ Tuple[SupportsIndex | _ArrayLikeInt_co, ...],
+ ]) -> Any: ...
+ @overload
+ def __getitem__(self, key: Union[
+ None,
+ slice,
+ ellipsis,
+ SupportsIndex,
+ _ArrayLikeInt_co,
+ Tuple[None | slice | ellipsis | _ArrayLikeInt_co | SupportsIndex, ...],
+ ]) -> ndarray[Any, _DType_co]: ...
+ @overload
+ def __getitem__(self: NDArray[void], key: str) -> NDArray[Any]: ...
+ @overload
+ def __getitem__(self: NDArray[void], key: list[str]) -> ndarray[_ShapeType, dtype[void]]: ...
+
@property
def ctypes(self) -> _ctypes[int]: ...
@property
@@ -3879,3 +3880,21 @@ class memmap(ndarray[_ShapeType, _DType_co]):
) -> Any: ...
def __getitem__(self, index): ... # TODO
def flush(self) -> None: ...
+
+class vectorize:
+ pyfunc: Callable[..., Any]
+ cache: bool
+ signature: None | str
+ otypes: None | str
+ excluded: Set[int | str]
+ __doc__: None | str
+ def __init__(
+ self,
+ pyfunc: Callable[..., Any],
+ otypes: None | str | Iterable[DTypeLike] = ...,
+ doc: None | str = ...,
+ excluded: None | Iterable[int | str] = ...,
+ cache: bool = ...,
+ signature: None | str = ...,
+ ) -> None: ...
+ def __call__(self, *args: Any, **kwargs: Any) -> NDArray[Any]: ...
diff --git a/numpy/core/function_base.pyi b/numpy/core/function_base.pyi
index c35629aa7..68d3b3a98 100644
--- a/numpy/core/function_base.pyi
+++ b/numpy/core/function_base.pyi
@@ -1,4 +1,4 @@
-from typing import overload, Tuple, Union, Sequence, Any, SupportsIndex, Literal
+from typing import overload, Tuple, Union, Sequence, Any, SupportsIndex, Literal, List
from numpy import ndarray
from numpy.typing import ArrayLike, DTypeLike, _SupportsArray, _NumberLike_co
@@ -8,6 +8,9 @@ _ArrayLikeNested = Sequence[Sequence[Any]]
_ArrayLikeNumber = Union[
_NumberLike_co, Sequence[_NumberLike_co], ndarray, _SupportsArray, _ArrayLikeNested
]
+
+__all__: List[str]
+
@overload
def linspace(
start: _ArrayLikeNumber,
@@ -47,3 +50,11 @@ def geomspace(
dtype: DTypeLike = ...,
axis: SupportsIndex = ...,
) -> ndarray: ...
+
+# Re-exported to `np.lib.function_base`
+def add_newdoc(
+ place: str,
+ obj: str,
+ doc: str | Tuple[str, str] | List[Tuple[str, str]],
+ warn_on_python: bool = ...,
+) -> None: ...
diff --git a/numpy/lib/function_base.pyi b/numpy/lib/function_base.pyi
index 69c615c9c..cbbc87e65 100644
--- a/numpy/lib/function_base.pyi
+++ b/numpy/lib/function_base.pyi
@@ -1,7 +1,48 @@
-from typing import List
+import sys
+from typing import (
+ Literal as L,
+ List,
+ Type,
+ Sequence,
+ Tuple,
+ Union,
+ Any,
+ TypeVar,
+ Iterator,
+ overload,
+ Callable,
+ Protocol,
+ SupportsIndex,
+ Iterable,
+)
+
+if sys.version_info >= (3, 10):
+ from typing import TypeGuard
+else:
+ from typing_extensions import TypeGuard
from numpy import (
vectorize as vectorize,
+ dtype,
+ generic,
+ floating,
+ complexfloating,
+ object_,
+ _OrderKACF,
+)
+
+from numpy.typing import (
+ NDArray,
+ ArrayLike,
+ DTypeLike,
+ _ShapeLike,
+ _ScalarLike_co,
+ _SupportsDType,
+ _FiniteNestedSequence,
+ _SupportsArray,
+ _ArrayLikeComplex_co,
+ _ArrayLikeFloat_co,
+ _ArrayLikeObject_co,
)
from numpy.core.function_base import (
@@ -12,30 +53,261 @@ from numpy.core.multiarray import (
add_docstring as add_docstring,
bincount as bincount,
)
+
from numpy.core.umath import _add_newdoc_ufunc
+_T = TypeVar("_T")
+_T_co = TypeVar("_T_co", covariant=True)
+_SCT = TypeVar("_SCT", bound=generic)
+_ArrayType = TypeVar("_ArrayType", bound=NDArray[Any])
+
+_2Tuple = Tuple[_T, _T]
+_ArrayLike = _FiniteNestedSequence[_SupportsArray[dtype[_SCT]]]
+_DTypeLike = Union[
+ dtype[_SCT],
+ Type[_SCT],
+ _SupportsDType[dtype[_SCT]],
+]
+
+class _TrimZerosSequence(Protocol[_T_co]):
+ def __len__(self) -> int: ...
+ def __getitem__(self, key: slice, /) -> _T_co: ...
+ def __iter__(self) -> Iterator[Any]: ...
+
+class _SupportsWriteFlush(Protocol):
+ def write(self, s: str, /) -> object: ...
+ def flush(self) -> object: ...
+
__all__: List[str]
add_newdoc_ufunc = _add_newdoc_ufunc
-def rot90(m, k=..., axes = ...): ...
-def flip(m, axis=...): ...
-def iterable(y): ...
-def average(a, axis=..., weights=..., returned=...): ...
-def asarray_chkfinite(a, dtype=..., order=...): ...
-def piecewise(x, condlist, funclist, *args, **kw): ...
-def select(condlist, choicelist, default=...): ...
-def copy(a, order=..., subok=...): ...
-def gradient(f, *varargs, axis=..., edge_order=...): ...
-def diff(a, n=..., axis=..., prepend = ..., append = ...): ...
+@overload
+def rot90(
+ m: _ArrayLike[_SCT],
+ k: int = ...,
+ axes: Tuple[int, int] = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def rot90(
+ m: ArrayLike,
+ k: int = ...,
+ axes: Tuple[int, int] = ...,
+) -> NDArray[Any]: ...
+
+@overload
+def flip(m: _SCT, axis: None = ...) -> _SCT: ...
+@overload
+def flip(m: _ScalarLike_co, axis: None = ...) -> Any: ...
+@overload
+def flip(m: _ArrayLike[_SCT], axis: None | _ShapeLike = ...) -> NDArray[_SCT]: ...
+@overload
+def flip(m: ArrayLike, axis: None | _ShapeLike = ...) -> NDArray[Any]: ...
+
+def iterable(y: object) -> TypeGuard[Iterable[Any]]: ...
+
+@overload
+def average(
+ a: _ArrayLikeFloat_co,
+ axis: None = ...,
+ weights: None | _ArrayLikeFloat_co= ...,
+ returned: L[False] = ...,
+) -> floating[Any]: ...
+@overload
+def average(
+ a: _ArrayLikeComplex_co,
+ axis: None = ...,
+ weights: None | _ArrayLikeComplex_co = ...,
+ returned: L[False] = ...,
+) -> complexfloating[Any, Any]: ...
+@overload
+def average(
+ a: _ArrayLikeObject_co,
+ axis: None = ...,
+ weights: None | Any = ...,
+ returned: L[False] = ...,
+) -> Any: ...
+@overload
+def average(
+ a: _ArrayLikeFloat_co,
+ axis: None = ...,
+ weights: None | _ArrayLikeFloat_co= ...,
+ returned: L[True] = ...,
+) -> _2Tuple[floating[Any]]: ...
+@overload
+def average(
+ a: _ArrayLikeComplex_co,
+ axis: None = ...,
+ weights: None | _ArrayLikeComplex_co = ...,
+ returned: L[True] = ...,
+) -> _2Tuple[complexfloating[Any, Any]]: ...
+@overload
+def average(
+ a: _ArrayLikeObject_co,
+ axis: None = ...,
+ weights: None | Any = ...,
+ returned: L[True] = ...,
+) -> _2Tuple[Any]: ...
+@overload
+def average(
+ a: _ArrayLikeComplex_co | _ArrayLikeObject_co,
+ axis: None | _ShapeLike = ...,
+ weights: None | Any = ...,
+ returned: L[False] = ...,
+) -> Any: ...
+@overload
+def average(
+ a: _ArrayLikeComplex_co | _ArrayLikeObject_co,
+ axis: None | _ShapeLike = ...,
+ weights: None | Any = ...,
+ returned: L[True] = ...,
+) -> _2Tuple[Any]: ...
+
+@overload
+def asarray_chkfinite(
+ a: _ArrayLike[_SCT],
+ dtype: None = ...,
+ order: _OrderKACF = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def asarray_chkfinite(
+ a: object,
+ dtype: None = ...,
+ order: _OrderKACF = ...,
+) -> NDArray[Any]: ...
+@overload
+def asarray_chkfinite(
+ a: Any,
+ dtype: _DTypeLike[_SCT],
+ order: _OrderKACF = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def asarray_chkfinite(
+ a: Any,
+ dtype: DTypeLike,
+ order: _OrderKACF = ...,
+) -> NDArray[Any]: ...
+
+@overload
+def piecewise(
+ x: _ArrayLike[_SCT],
+ condlist: ArrayLike,
+ funclist: Sequence[Any | Callable[..., Any]],
+ *args: Any,
+ **kw: Any,
+) -> NDArray[_SCT]: ...
+@overload
+def piecewise(
+ x: ArrayLike,
+ condlist: ArrayLike,
+ funclist: Sequence[Any | Callable[..., Any]],
+ *args: Any,
+ **kw: Any,
+) -> NDArray[Any]: ...
+
+def select(
+ condlist: Sequence[ArrayLike],
+ choicelist: Sequence[ArrayLike],
+ default: ArrayLike = ...,
+) -> NDArray[Any]: ...
+
+@overload
+def copy(
+ a: _ArrayType,
+ order: _OrderKACF,
+ subok: L[True],
+) -> _ArrayType: ...
+@overload
+def copy(
+ a: _ArrayType,
+ order: _OrderKACF = ...,
+ *,
+ subok: L[True],
+) -> _ArrayType: ...
+@overload
+def copy(
+ a: _ArrayLike[_SCT],
+ order: _OrderKACF = ...,
+ subok: L[False] = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def copy(
+ a: ArrayLike,
+ order: _OrderKACF = ...,
+ subok: L[False] = ...,
+) -> NDArray[Any]: ...
+
+def gradient(
+ f: ArrayLike,
+ *varargs: ArrayLike,
+ axis: None | _ShapeLike = ...,
+ edge_order: L[1, 2] = ...,
+) -> Any: ...
+
+@overload
+def diff(
+ a: _T,
+ n: L[0],
+ axis: SupportsIndex = ...,
+ prepend: ArrayLike = ...,
+ append: ArrayLike = ...,
+) -> _T: ...
+@overload
+def diff(
+ a: ArrayLike,
+ n: int = ...,
+ axis: SupportsIndex = ...,
+ prepend: ArrayLike = ...,
+ append: ArrayLike = ...,
+) -> NDArray[Any]: ...
+
+# TODO
def interp(x, xp, fp, left=..., right=..., period=...): ...
-def angle(z, deg=...): ...
-def unwrap(p, discont = ..., axis=..., *, period=...): ...
-def sort_complex(a): ...
-def trim_zeros(filt, trim=...): ...
-def extract(condition, arr): ...
-def place(arr, mask, vals): ...
-def disp(mesg, device=..., linefeed=...): ...
+
+@overload
+def angle(z: _ArrayLikeFloat_co, deg: bool = ...) -> floating[Any]: ...
+@overload
+def angle(z: _ArrayLikeComplex_co, deg: bool = ...) -> complexfloating[Any, Any]: ...
+@overload
+def angle(z: _ArrayLikeObject_co, deg: bool = ...) -> Any: ...
+
+@overload
+def unwrap(
+ p: _ArrayLikeFloat_co,
+ discont: None | float = ...,
+ axis: int = ...,
+ *,
+ period: float = ...,
+) -> NDArray[floating[Any]]: ...
+@overload
+def unwrap(
+ p: _ArrayLikeObject_co,
+ discont: None | float = ...,
+ axis: int = ...,
+ *,
+ period: float = ...,
+) -> NDArray[object_]: ...
+
+def sort_complex(a: ArrayLike) -> NDArray[complexfloating[Any, Any]]: ...
+
+def trim_zeros(
+ filt: _TrimZerosSequence[_T],
+ trim: L["f", "b", "fb", "bf"] = ...,
+) -> _T: ...
+
+@overload
+def extract(condition: ArrayLike, arr: _ArrayLike[_SCT]) -> NDArray[_SCT]: ...
+@overload
+def extract(condition: ArrayLike, arr: ArrayLike) -> NDArray[Any]: ...
+
+def place(arr: NDArray[Any], mask: ArrayLike, vals: Any) -> None: ...
+
+def disp(
+ mesg: object,
+ device: None | _SupportsWriteFlush = ...,
+ linefeed: bool = ...,
+) -> None: ...
+
def cov(m, y=..., rowvar=..., bias=..., ddof=..., fweights=..., aweights=..., *, dtype=...): ...
def corrcoef(x, y=..., rowvar=..., bias = ..., ddof = ..., *, dtype=...): ...
def blackman(M): ...
diff --git a/numpy/typing/tests/data/fail/lib_function_base.pyi b/numpy/typing/tests/data/fail/lib_function_base.pyi
new file mode 100644
index 000000000..019bd7f01
--- /dev/null
+++ b/numpy/typing/tests/data/fail/lib_function_base.pyi
@@ -0,0 +1,19 @@
+from typing import Any
+
+import numpy as np
+import numpy.typing as npt
+
+AR_m: npt.NDArray[np.timedelta64]
+AR_f8: npt.NDArray[np.float64]
+AR_c16: npt.NDArray[np.complex128]
+
+np.average(AR_m) # E: incompatible type
+np.select(1, [AR_f8]) # E: incompatible type
+np.angle(AR_m) # E: incompatible type
+np.unwrap(AR_m) # E: incompatible type
+np.unwrap(AR_c16) # E: incompatible type
+np.trim_zeros(1) # E: incompatible type
+np.place(1, [True], 1.5) # E: incompatible type
+np.vectorize(1) # E: incompatible type
+np.add_newdoc("__main__", 1.5, "docstring") # E: incompatible type
+np.place(AR_f8, slice(None), 5) # E: incompatible type
diff --git a/numpy/typing/tests/data/fail/ndarray_misc.pyi b/numpy/typing/tests/data/fail/ndarray_misc.pyi
index cf3fedc45..8320a44f3 100644
--- a/numpy/typing/tests/data/fail/ndarray_misc.pyi
+++ b/numpy/typing/tests/data/fail/ndarray_misc.pyi
@@ -35,3 +35,7 @@ AR_M.__int__() # E: Invalid self argument
AR_M.__float__() # E: Invalid self argument
AR_M.__complex__() # E: Invalid self argument
AR_b.__index__() # E: Invalid self argument
+
+AR_f8[1.5] # E: No overload variant
+AR_f8["field_a"] # E: No overload variant
+AR_f8[["field_a", "field_b"]] # E: Invalid index type
diff --git a/numpy/typing/tests/data/reveal/lib_function_base.pyi b/numpy/typing/tests/data/reveal/lib_function_base.pyi
new file mode 100644
index 000000000..76d54c49f
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/lib_function_base.pyi
@@ -0,0 +1,99 @@
+from typing import Any
+
+import numpy as np
+import numpy.typing as npt
+
+vectorized_func: np.vectorize
+
+f8: np.float64
+AR_LIKE_f8: list[float]
+
+AR_i8: npt.NDArray[np.int64]
+AR_f8: npt.NDArray[np.float64]
+AR_c16: npt.NDArray[np.complex128]
+AR_O: npt.NDArray[np.object_]
+AR_b: npt.NDArray[np.bool_]
+AR_U: npt.NDArray[np.str_]
+CHAR_AR_U: np.chararray[Any, np.dtype[np.str_]]
+
+def func(*args: Any, **kwargs: Any) -> Any: ...
+
+reveal_type(vectorized_func.pyfunc) # E: def (*Any, **Any) -> Any
+reveal_type(vectorized_func.cache) # E: bool
+reveal_type(vectorized_func.signature) # E: Union[None, builtins.str]
+reveal_type(vectorized_func.otypes) # E: Union[None, builtins.str]
+reveal_type(vectorized_func.excluded) # E: set[Union[builtins.int, builtins.str]]
+reveal_type(vectorized_func.__doc__) # E: Union[None, builtins.str]
+reveal_type(vectorized_func([1])) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(np.vectorize(int)) # E: numpy.vectorize
+reveal_type(np.vectorize( # E: numpy.vectorize
+ int, otypes="i", doc="doc", excluded=(), cache=True, signature=None
+))
+
+reveal_type(np.add_newdoc("__main__", "blabla", doc="test doc")) # E: None
+reveal_type(np.add_newdoc("__main__", "blabla", doc=("meth", "test doc"))) # E: None
+reveal_type(np.add_newdoc("__main__", "blabla", doc=[("meth", "test doc")])) # E: None
+
+reveal_type(np.rot90(AR_f8, k=2)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.rot90(AR_LIKE_f8, axes=(0, 1))) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.flip(f8)) # E: {float64}
+reveal_type(np.flip(1.0)) # E: Any
+reveal_type(np.flip(AR_f8, axis=(0, 1))) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.flip(AR_LIKE_f8, axis=0)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.iterable(1)) # E: bool
+reveal_type(np.iterable([1])) # E: bool
+
+reveal_type(np.average(AR_f8)) # E: numpy.floating[Any]
+reveal_type(np.average(AR_f8, weights=AR_c16)) # E: numpy.complexfloating[Any, Any]
+reveal_type(np.average(AR_O)) # E: Any
+reveal_type(np.average(AR_f8, returned=True)) # E: Tuple[numpy.floating[Any], numpy.floating[Any]]
+reveal_type(np.average(AR_f8, weights=AR_c16, returned=True)) # E: Tuple[numpy.complexfloating[Any, Any], numpy.complexfloating[Any, Any]]
+reveal_type(np.average(AR_O, returned=True)) # E: Tuple[Any, Any]
+reveal_type(np.average(AR_f8, axis=0)) # E: Any
+reveal_type(np.average(AR_f8, axis=0, returned=True)) # E: Tuple[Any, Any]
+
+reveal_type(np.asarray_chkfinite(AR_f8)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.asarray_chkfinite(AR_LIKE_f8)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(np.asarray_chkfinite(AR_f8, dtype=np.float64)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.asarray_chkfinite(AR_f8, dtype=float)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.piecewise(AR_f8, AR_b, [func])) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.piecewise(AR_LIKE_f8, AR_b, [func])) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.select([AR_f8], [AR_f8])) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.copy(AR_LIKE_f8)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(np.copy(AR_U)) # E: numpy.ndarray[Any, numpy.dtype[numpy.str_]]
+reveal_type(np.copy(CHAR_AR_U)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.copy(CHAR_AR_U, "K", subok=True)) # E: numpy.chararray[Any, numpy.dtype[numpy.str_]]
+reveal_type(np.copy(CHAR_AR_U, subok=True)) # E: numpy.chararray[Any, numpy.dtype[numpy.str_]]
+
+reveal_type(np.gradient(AR_f8, axis=None)) # E: Any
+reveal_type(np.gradient(AR_LIKE_f8, edge_order=2)) # E: Any
+
+reveal_type(np.diff("bob", n=0)) # E: str
+reveal_type(np.diff(AR_f8, axis=0)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(np.diff(AR_LIKE_f8, prepend=1.5)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.angle(AR_f8)) # E: numpy.floating[Any]
+reveal_type(np.angle(AR_c16, deg=True)) # E: numpy.complexfloating[Any, Any]
+reveal_type(np.angle(AR_O)) # E: Any
+
+reveal_type(np.unwrap(AR_f8)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(np.unwrap(AR_O)) # E: numpy.ndarray[Any, numpy.dtype[numpy.object_]]
+
+reveal_type(np.sort_complex(AR_f8)) # E: numpy.ndarray[Any, numpy.dtype[numpy.complexfloating[Any, Any]]]
+
+reveal_type(np.trim_zeros(AR_f8)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.trim_zeros(AR_LIKE_f8)) # E: list[builtins.float]
+
+reveal_type(np.extract(AR_i8, AR_f8)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.extract(AR_i8, AR_LIKE_f8)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.place(AR_f8, mask=AR_i8, vals=5.0)) # E: None
+
+reveal_type(np.disp(1, linefeed=True)) # E: None
+with open("test", "w") as f:
+ reveal_type(np.disp("message", device=f)) # E: None
diff --git a/numpy/typing/tests/data/reveal/ndarray_misc.pyi b/numpy/typing/tests/data/reveal/ndarray_misc.pyi
index 050b82cdc..e384b5388 100644
--- a/numpy/typing/tests/data/reveal/ndarray_misc.pyi
+++ b/numpy/typing/tests/data/reveal/ndarray_misc.pyi
@@ -20,6 +20,7 @@ B: SubClass
AR_f8: NDArray[np.float64]
AR_i8: NDArray[np.int64]
AR_U: NDArray[np.str_]
+AR_V: NDArray[np.void]
ctypes_obj = AR_f8.ctypes
@@ -193,3 +194,13 @@ reveal_type(operator.index(AR_i8)) # E: int
reveal_type(AR_f8.__array_prepare__(B)) # E: numpy.ndarray[Any, numpy.dtype[numpy.object_]]
reveal_type(AR_f8.__array_wrap__(B)) # E: numpy.ndarray[Any, numpy.dtype[numpy.object_]]
+
+reveal_type(AR_V[0]) # E: Any
+reveal_type(AR_V[0, 0]) # E: Any
+reveal_type(AR_V[AR_i8]) # E: Any
+reveal_type(AR_V[AR_i8, AR_i8]) # E: Any
+reveal_type(AR_V[AR_i8, None]) # E: numpy.ndarray[Any, numpy.dtype[numpy.void]]
+reveal_type(AR_V[0, ...]) # E: numpy.ndarray[Any, numpy.dtype[numpy.void]]
+reveal_type(AR_V[:]) # E: numpy.ndarray[Any, numpy.dtype[numpy.void]]
+reveal_type(AR_V["a"]) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(AR_V[["a", "b"]]) # E: numpy.ndarray[Any, numpy.dtype[numpy.void]]