diff --git a/numpy/__init__.pyi b/numpy/__init__.pyi index bf91aafdd3ed..d275ad27a45e 100644 --- a/numpy/__init__.pyi +++ b/numpy/__init__.pyi @@ -862,6 +862,24 @@ class dtype(Generic[_DTypeScalar]): align: bool = ..., copy: bool = ..., ) -> dtype[void]: ... + + @overload + def __getitem__(self: dtype[void], key: List[str]) -> dtype[void]: ... + @overload + def __getitem__(self: dtype[void], key: Union[str, int]) -> dtype[Any]: ... + + # NOTE: In the future 1-based multiplications will also yield `void` dtypes + @overload + def __mul__(self, value: Literal[0]) -> None: ... # type: ignore[misc] + @overload + def __mul__(self, value: Literal[1]) -> dtype[_DTypeScalar]: ... + @overload + def __mul__(self, value: int) -> dtype[void]: ... + + # NOTE: `__rmul__` seems to be broken when used in combination with + # literals as of mypy 0.800. Set the return-type to `Any` for now. + def __rmul__(self, value: int) -> Any: ... + def __eq__(self, other: DTypeLike) -> bool: ... def __ne__(self, other: DTypeLike) -> bool: ... def __gt__(self, other: DTypeLike) -> bool: ... @@ -901,6 +919,8 @@ class dtype(Generic[_DTypeScalar]): @property def name(self) -> str: ... @property + def names(self) -> Optional[Tuple[str, ...]]: ... + @property def num(self) -> int: ... @property def shape(self) -> _Shape: ... diff --git a/numpy/typing/tests/data/pass/dtype.py b/numpy/typing/tests/data/pass/dtype.py index cbae8c078551..90715209eac2 100644 --- a/numpy/typing/tests/data/pass/dtype.py +++ b/numpy/typing/tests/data/pass/dtype.py @@ -1,5 +1,8 @@ import numpy as np +dtype_obj = np.dtype(np.str_) +void_dtype_obj = np.dtype([("f0", np.float64), ("f1", np.float32)]) + np.dtype(dtype=np.int64) np.dtype(int) np.dtype("int") @@ -33,3 +36,16 @@ class Test: np.dtype(Test()) + +dtype_obj.names + +dtype_obj * 0 +dtype_obj * 2 + +0 * dtype_obj +2 * dtype_obj + +void_dtype_obj["f0"] +void_dtype_obj[0] +void_dtype_obj[["f0", "f1"]] +void_dtype_obj[["f0"]] diff --git a/numpy/typing/tests/data/reveal/dtype.py b/numpy/typing/tests/data/reveal/dtype.py index d414f2c4934f..83a7695b9bb5 100644 --- a/numpy/typing/tests/data/reveal/dtype.py +++ b/numpy/typing/tests/data/reveal/dtype.py @@ -1,5 +1,8 @@ import numpy as np +dtype_obj: np.dtype[np.str_] +void_dtype_obj: np.dtype[np.void] + reveal_type(np.dtype(np.float64)) # E: numpy.dtype[numpy.floating[numpy.typing._64Bit]] reveal_type(np.dtype(np.int64)) # E: numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]] @@ -31,3 +34,19 @@ # Void reveal_type(np.dtype(("U", 10))) # E: numpy.dtype[numpy.void] + +reveal_type(dtype_obj.name) # E: str +reveal_type(dtype_obj.names) # E: Union[builtins.tuple[builtins.str], None] + +reveal_type(dtype_obj * 0) # E: None +reveal_type(dtype_obj * 1) # E: numpy.dtype[numpy.str_] +reveal_type(dtype_obj * 2) # E: numpy.dtype[numpy.void] + +reveal_type(0 * dtype_obj) # E: Any +reveal_type(1 * dtype_obj) # E: Any +reveal_type(2 * dtype_obj) # E: Any + +reveal_type(void_dtype_obj["f0"]) # E: numpy.dtype[Any] +reveal_type(void_dtype_obj[0]) # E: numpy.dtype[Any] +reveal_type(void_dtype_obj[["f0", "f1"]]) # E: numpy.dtype[numpy.void] +reveal_type(void_dtype_obj[["f0"]]) # E: numpy.dtype[numpy.void]