summaryrefslogtreecommitdiff
path: root/numpy/typing
diff options
context:
space:
mode:
authorCharles Harris <charlesr.harris@gmail.com>2020-12-13 14:14:49 -0700
committerGitHub <noreply@github.com>2020-12-13 14:14:49 -0700
commit3fe2d9d2627fc0f84aeed293ff8afa7c1f08d899 (patch)
tree2ea27fe06a19c39e8d7a5fe2f87cb7e05363247d /numpy/typing
parent7d7e446fcbeeff70d905bde2eb0264a797488280 (diff)
parenteff302e5e8678fa17fb3d8156d49eb585b0876d9 (diff)
downloadnumpy-3fe2d9d2627fc0f84aeed293ff8afa7c1f08d899.tar.gz
Merge branch 'master' into fix-issue-10244
Diffstat (limited to 'numpy/typing')
-rw-r--r--numpy/typing/__init__.py181
-rw-r--r--numpy/typing/_add_docstring.py96
-rw-r--r--numpy/typing/_array_like.py29
-rw-r--r--numpy/typing/_callable.py345
-rw-r--r--numpy/typing/_dtype_like.py93
-rw-r--r--numpy/typing/_scalars.py30
-rw-r--r--numpy/typing/setup.py11
-rw-r--r--numpy/typing/tests/__init__.py0
-rw-r--r--numpy/typing/tests/data/fail/arithmetic.py16
-rw-r--r--numpy/typing/tests/data/fail/array_constructors.py31
-rw-r--r--numpy/typing/tests/data/fail/array_like.py16
-rw-r--r--numpy/typing/tests/data/fail/bitwise_ops.py20
-rw-r--r--numpy/typing/tests/data/fail/constants.py6
-rw-r--r--numpy/typing/tests/data/fail/dtype.py16
-rw-r--r--numpy/typing/tests/data/fail/flatiter.py25
-rw-r--r--numpy/typing/tests/data/fail/fromnumeric.py154
-rw-r--r--numpy/typing/tests/data/fail/modules.py10
-rw-r--r--numpy/typing/tests/data/fail/ndarray.py11
-rw-r--r--numpy/typing/tests/data/fail/ndarray_misc.py21
-rw-r--r--numpy/typing/tests/data/fail/numerictypes.py13
-rw-r--r--numpy/typing/tests/data/fail/scalars.py76
-rw-r--r--numpy/typing/tests/data/fail/ufunc_config.py21
-rw-r--r--numpy/typing/tests/data/fail/ufuncs.py7
-rw-r--r--numpy/typing/tests/data/fail/warnings_and_errors.py7
-rw-r--r--numpy/typing/tests/data/mypy.ini8
-rw-r--r--numpy/typing/tests/data/pass/arithmetic.py293
-rw-r--r--numpy/typing/tests/data/pass/array_constructors.py128
-rw-r--r--numpy/typing/tests/data/pass/array_like.py39
-rw-r--r--numpy/typing/tests/data/pass/bitwise_ops.py131
-rw-r--r--numpy/typing/tests/data/pass/comparisons.py247
-rw-r--r--numpy/typing/tests/data/pass/dtype.py43
-rw-r--r--numpy/typing/tests/data/pass/flatiter.py16
-rw-r--r--numpy/typing/tests/data/pass/fromnumeric.py260
-rw-r--r--numpy/typing/tests/data/pass/literal.py45
-rw-r--r--numpy/typing/tests/data/pass/mod.py149
-rw-r--r--numpy/typing/tests/data/pass/ndarray_conversion.py94
-rw-r--r--numpy/typing/tests/data/pass/ndarray_misc.py159
-rw-r--r--numpy/typing/tests/data/pass/ndarray_shape_manipulation.py47
-rw-r--r--numpy/typing/tests/data/pass/numeric.py89
-rw-r--r--numpy/typing/tests/data/pass/numerictypes.py29
-rw-r--r--numpy/typing/tests/data/pass/scalars.py165
-rw-r--r--numpy/typing/tests/data/pass/simple.py165
-rw-r--r--numpy/typing/tests/data/pass/simple_py3.py6
-rw-r--r--numpy/typing/tests/data/pass/ufunc_config.py50
-rw-r--r--numpy/typing/tests/data/pass/ufuncs.py16
-rw-r--r--numpy/typing/tests/data/pass/warnings_and_errors.py7
-rw-r--r--numpy/typing/tests/data/reveal/arithmetic.py291
-rw-r--r--numpy/typing/tests/data/reveal/array_constructors.py102
-rw-r--r--numpy/typing/tests/data/reveal/bitwise_ops.py131
-rw-r--r--numpy/typing/tests/data/reveal/comparisons.py247
-rw-r--r--numpy/typing/tests/data/reveal/constants.py52
-rw-r--r--numpy/typing/tests/data/reveal/dtype.py41
-rw-r--r--numpy/typing/tests/data/reveal/flatiter.py17
-rw-r--r--numpy/typing/tests/data/reveal/fromnumeric.py278
-rw-r--r--numpy/typing/tests/data/reveal/mod.py149
-rw-r--r--numpy/typing/tests/data/reveal/modules.py20
-rw-r--r--numpy/typing/tests/data/reveal/nbit_base_example.py18
-rw-r--r--numpy/typing/tests/data/reveal/ndarray_conversion.py54
-rw-r--r--numpy/typing/tests/data/reveal/ndarray_misc.py150
-rw-r--r--numpy/typing/tests/data/reveal/ndarray_shape_manipulation.py35
-rw-r--r--numpy/typing/tests/data/reveal/numeric.py89
-rw-r--r--numpy/typing/tests/data/reveal/numerictypes.py18
-rw-r--r--numpy/typing/tests/data/reveal/scalars.py28
-rw-r--r--numpy/typing/tests/data/reveal/ufunc_config.py25
-rw-r--r--numpy/typing/tests/data/reveal/warnings_and_errors.py10
-rw-r--r--numpy/typing/tests/test_isfile.py33
-rw-r--r--numpy/typing/tests/test_typing.py182
67 files changed, 5339 insertions, 52 deletions
diff --git a/numpy/typing/__init__.py b/numpy/typing/__init__.py
index f2000823f..d9d9557bf 100644
--- a/numpy/typing/__init__.py
+++ b/numpy/typing/__init__.py
@@ -11,14 +11,11 @@ Typing (:mod:`numpy.typing`)
typing-extensions_ package.
Large parts of the NumPy API have PEP-484-style type annotations. In
-addition, the following type aliases are available for users.
+addition a number of type aliases are available to users, most prominently
+the two below:
-- ``typing.ArrayLike``: objects that can be converted to arrays
-- ``typing.DtypeLike``: objects that can be converted to dtypes
-
-Roughly speaking, ``typing.ArrayLike`` is "objects that can be used as
-inputs to ``np.array``" and ``typing.DtypeLike`` is "objects that can
-be used as inputs to ``np.dtype``".
+- `ArrayLike`: objects that can be converted to arrays
+- `DTypeLike`: objects that can be converted to dtypes
.. _typing-extensions: https://pypi.org/project/typing-extensions/
@@ -34,13 +31,13 @@ differences.
ArrayLike
~~~~~~~~~
-The ``ArrayLike`` type tries to avoid creating object arrays. For
+The `ArrayLike` type tries to avoid creating object arrays. For
example,
.. code-block:: python
>>> np.array(x**2 for x in range(10))
- array(<generator object <genexpr> at 0x10c004cd0>, dtype=object)
+ array(<generator object <genexpr> at ...>, dtype=object)
is valid NumPy code which will create a 0-dimensional object
array. Type checkers will complain about the above example when using
@@ -51,14 +48,14 @@ you can either use a ``# type: ignore`` comment:
>>> np.array(x**2 for x in range(10)) # type: ignore
-or explicitly type the array like object as ``Any``:
+or explicitly type the array like object as `~typing.Any`:
.. code-block:: python
>>> from typing import Any
>>> array_like: Any = (x**2 for x in range(10))
>>> np.array(array_like)
- array(<generator object <genexpr> at 0x1192741d0>, dtype=object)
+ array(<generator object <genexpr> at ...>, dtype=object)
ndarray
~~~~~~~
@@ -68,14 +65,170 @@ the following code is valid:
.. code-block:: python
- x = np.array([1, 2])
- x.dtype = np.bool_
+ >>> x = np.array([1, 2])
+ >>> x.dtype = np.bool_
This sort of mutation is not allowed by the types. Users who want to
write statically typed code should insted use the `numpy.ndarray.view`
method to create a view of the array with a different dtype.
+DTypeLike
+~~~~~~~~~
+
+The `DTypeLike` type tries to avoid creation of dtype objects using
+dictionary of fields like below:
+
+.. code-block:: python
+
+ >>> x = np.dtype({"field1": (float, 1), "field2": (int, 3)})
+
+Although this is valid Numpy code, the type checker will complain about it,
+since its usage is discouraged.
+Please see : :ref:`Data type objects <arrays.dtypes>`
+
+Number Precision
+~~~~~~~~~~~~~~~~
+
+The precision of `numpy.number` subclasses is treated as a covariant generic
+parameter (see :class:`~NBitBase`), simplifying the annoting of proccesses
+involving precision-based casting.
+
+.. code-block:: python
+
+ >>> from typing import TypeVar
+ >>> import numpy as np
+ >>> import numpy.typing as npt
+
+ >>> T = TypeVar("T", bound=npt.NBitBase)
+ >>> def func(a: "np.floating[T]", b: "np.floating[T]") -> "np.floating[T]":
+ ... ...
+
+Consequently, the likes of `~numpy.float16`, `~numpy.float32` and
+`~numpy.float64` are still sub-types of `~numpy.floating`, but, contrary to
+runtime, they're not necessarily considered as sub-classes.
+
+Timedelta64
+~~~~~~~~~~~
+
+The `~numpy.timedelta64` class is not considered a subclass of `~numpy.signedinteger`,
+the former only inheriting from `~numpy.generic` while static type checking.
+
+API
+---
+
"""
+# NOTE: The API section will be appended with additional entries
+# further down in this file
+
+from typing import TYPE_CHECKING, List
+
+if TYPE_CHECKING:
+ import sys
+ if sys.version_info >= (3, 8):
+ from typing import final
+ else:
+ from typing_extensions import final
+else:
+ def final(f): return f
+
+if not TYPE_CHECKING:
+ __all__ = ["ArrayLike", "DTypeLike", "NBitBase"]
+else:
+ # Ensure that all objects within this module are accessible while
+ # static type checking. This includes private ones, as we need them
+ # for internal use.
+ #
+ # Declare to mypy that `__all__` is a list of strings without assigning
+ # an explicit value
+ __all__: List[str]
+
+
+@final # Dissallow the creation of arbitrary `NBitBase` subclasses
+class NBitBase:
+ """
+ An object representing `numpy.number` precision during static type checking.
+
+ Used exclusively for the purpose static type checking, `NBitBase`
+ represents the base of a hierachieral set of subclasses.
+ Each subsequent subclass is herein used for representing a lower level
+ of precision, *e.g.* ``64Bit > 32Bit > 16Bit``.
+
+ Examples
+ --------
+ Below is a typical usage example: `NBitBase` is herein used for annotating a
+ function that takes a float and integer of arbitrary precision as arguments
+ and returns a new float of whichever precision is largest
+ (*e.g.* ``np.float16 + np.int64 -> np.float64``).
+
+ .. code-block:: python
+
+ >>> from typing import TypeVar, TYPE_CHECKING
+ >>> import numpy as np
+ >>> import numpy.typing as npt
+
+ >>> T = TypeVar("T", bound=npt.NBitBase)
+
+ >>> def add(a: "np.floating[T]", b: "np.integer[T]") -> "np.floating[T]":
+ ... return a + b
+
+ >>> a = np.float16()
+ >>> b = np.int64()
+ >>> out = add(a, b)
+
+ >>> if TYPE_CHECKING:
+ ... reveal_locals()
+ ... # note: Revealed local types are:
+ ... # note: a: numpy.floating[numpy.typing._16Bit*]
+ ... # note: b: numpy.signedinteger[numpy.typing._64Bit*]
+ ... # note: out: numpy.floating[numpy.typing._64Bit*]
+
+ """
+
+ def __init_subclass__(cls) -> None:
+ allowed_names = {
+ "NBitBase", "_256Bit", "_128Bit", "_96Bit", "_80Bit",
+ "_64Bit", "_32Bit", "_16Bit", "_8Bit",
+ }
+ if cls.__name__ not in allowed_names:
+ raise TypeError('cannot inherit from final class "NBitBase"')
+ super().__init_subclass__()
+
+
+# Silence errors about subclassing a `@final`-decorated class
+class _256Bit(NBitBase): ... # type: ignore[misc]
+class _128Bit(_256Bit): ... # type: ignore[misc]
+class _96Bit(_128Bit): ... # type: ignore[misc]
+class _80Bit(_96Bit): ... # type: ignore[misc]
+class _64Bit(_80Bit): ... # type: ignore[misc]
+class _32Bit(_64Bit): ... # type: ignore[misc]
+class _16Bit(_32Bit): ... # type: ignore[misc]
+class _8Bit(_16Bit): ... # type: ignore[misc]
+
+# Clean up the namespace
+del TYPE_CHECKING, final, List
+
+from ._scalars import (
+ _CharLike,
+ _BoolLike,
+ _UIntLike,
+ _IntLike,
+ _FloatLike,
+ _ComplexLike,
+ _TD64Like,
+ _NumberLike,
+ _ScalarLike,
+ _VoidLike,
+)
from ._array_like import _SupportsArray, ArrayLike
from ._shape import _Shape, _ShapeLike
-from ._dtype_like import DtypeLike
+from ._dtype_like import _SupportsDType, _VoidDTypeLike, DTypeLike
+
+if __doc__ is not None:
+ from ._add_docstring import _docstrings
+ __doc__ += _docstrings
+ __doc__ += '\n.. autoclass:: numpy.typing.NBitBase\n'
+ del _docstrings
+
+from numpy._pytesttester import PytestTester
+test = PytestTester(__name__)
+del PytestTester
diff --git a/numpy/typing/_add_docstring.py b/numpy/typing/_add_docstring.py
new file mode 100644
index 000000000..8e39fe2c6
--- /dev/null
+++ b/numpy/typing/_add_docstring.py
@@ -0,0 +1,96 @@
+"""A module for creating docstrings for sphinx ``data`` domains."""
+
+import re
+import textwrap
+
+_docstrings_list = []
+
+
+def add_newdoc(name, value, doc):
+ _docstrings_list.append((name, value, doc))
+
+
+def _parse_docstrings():
+ type_list_ret = []
+ for name, value, doc in _docstrings_list:
+ s = textwrap.dedent(doc).replace("\n", "\n ")
+
+ # Replace sections by rubrics
+ lines = s.split("\n")
+ new_lines = []
+ indent = ""
+ for line in lines:
+ m = re.match(r'^(\s+)[-=]+\s*$', line)
+ if m and new_lines:
+ prev = textwrap.dedent(new_lines.pop())
+ if prev == "Examples":
+ indent = ""
+ new_lines.append(f'{m.group(1)}.. rubric:: {prev}')
+ else:
+ indent = 4 * " "
+ new_lines.append(f'{m.group(1)}.. admonition:: {prev}')
+ new_lines.append("")
+ else:
+ new_lines.append(f"{indent}{line}")
+ s = "\n".join(new_lines)
+
+ # Done.
+ type_list_ret.append(f""".. data:: {name}\n :value: {value}\n {s}""")
+ return "\n".join(type_list_ret)
+
+
+add_newdoc('ArrayLike', 'typing.Union[...]',
+ """
+ A `~typing.Union` representing objects that can be coerced into an `~numpy.ndarray`.
+
+ Among others this includes the likes of:
+
+ * Scalars.
+ * (Nested) sequences.
+ * Objects implementing the `~class.__array__` protocol.
+
+ See Also
+ --------
+ :term:`array_like`:
+ Any scalar or sequence that can be interpreted as an ndarray.
+
+ Examples
+ --------
+ .. code-block:: python
+
+ >>> import numpy as np
+ >>> import numpy.typing as npt
+
+ >>> def as_array(a: npt.ArrayLike) -> np.ndarray:
+ ... return np.array(a)
+
+ """)
+
+add_newdoc('DTypeLike', 'typing.Union[...]',
+ """
+ A `~typing.Union` representing objects that can be coerced into a `~numpy.dtype`.
+
+ Among others this includes the likes of:
+
+ * :class:`type` objects.
+ * Character codes or the names of :class:`type` objects.
+ * Objects with the ``.dtype`` attribute.
+
+ See Also
+ --------
+ :ref:`Specifying and constructing data types <arrays.dtypes.constructing>`
+ A comprehensive overview of all objects that can be coerced into data types.
+
+ Examples
+ --------
+ .. code-block:: python
+
+ >>> import numpy as np
+ >>> import numpy.typing as npt
+
+ >>> def as_dtype(d: npt.DTypeLike) -> np.dtype:
+ ... return np.dtype(d)
+
+ """)
+
+_docstrings = _parse_docstrings()
diff --git a/numpy/typing/_array_like.py b/numpy/typing/_array_like.py
index 76c0c839c..63b67b33a 100644
--- a/numpy/typing/_array_like.py
+++ b/numpy/typing/_array_like.py
@@ -1,8 +1,11 @@
+from __future__ import annotations
+
import sys
-from typing import Any, overload, Sequence, TYPE_CHECKING, Union
+from typing import Any, overload, Sequence, TYPE_CHECKING, Union, TypeVar
-from numpy import ndarray
-from ._dtype_like import DtypeLike
+from numpy import ndarray, dtype
+from ._scalars import _ScalarLike
+from ._dtype_like import DTypeLike
if sys.version_info >= (3, 8):
from typing import Protocol
@@ -15,12 +18,15 @@ else:
else:
HAVE_PROTOCOL = True
+_DType = TypeVar("_DType", bound="dtype[Any]")
+
if TYPE_CHECKING or HAVE_PROTOCOL:
- class _SupportsArray(Protocol):
- @overload
- def __array__(self, __dtype: DtypeLike = ...) -> ndarray: ...
- @overload
- def __array__(self, dtype: DtypeLike = ...) -> ndarray: ...
+ # The `_SupportsArray` protocol only cares about the default dtype
+ # (i.e. `dtype=None`) of the to-be returned array.
+ # Concrete implementations of the protocol are responsible for adding
+ # any and all remaining overloads
+ class _SupportsArray(Protocol[_DType]):
+ def __array__(self, dtype: None = ...) -> ndarray[Any, _DType]: ...
else:
_SupportsArray = Any
@@ -31,4 +37,9 @@ else:
# is resolved. See also the mypy issue:
#
# https://github.com/python/typing/issues/593
-ArrayLike = Union[bool, int, float, complex, _SupportsArray, Sequence]
+ArrayLike = Union[
+ _ScalarLike,
+ Sequence[_ScalarLike],
+ Sequence[Sequence[Any]], # TODO: Wait for support for recursive types
+ "_SupportsArray[Any]",
+]
diff --git a/numpy/typing/_callable.py b/numpy/typing/_callable.py
new file mode 100644
index 000000000..831921fd7
--- /dev/null
+++ b/numpy/typing/_callable.py
@@ -0,0 +1,345 @@
+"""
+A module with various ``typing.Protocol`` subclasses that implement
+the ``__call__`` magic method.
+
+See the `Mypy documentation`_ on protocols for more details.
+
+.. _`Mypy documentation`: https://mypy.readthedocs.io/en/stable/protocols.html#callback-protocols
+
+"""
+
+import sys
+from typing import (
+ Union,
+ TypeVar,
+ overload,
+ Any,
+ Tuple,
+ NoReturn,
+ TYPE_CHECKING,
+)
+
+from numpy import (
+ ndarray,
+ generic,
+ bool_,
+ timedelta64,
+ number,
+ integer,
+ unsignedinteger,
+ signedinteger,
+ int8,
+ floating,
+ float64,
+ complexfloating,
+ complex128,
+)
+from ._scalars import (
+ _BoolLike,
+ _IntLike,
+ _FloatLike,
+ _ComplexLike,
+ _NumberLike,
+)
+from . import NBitBase
+from ._array_like import ArrayLike
+
+if sys.version_info >= (3, 8):
+ from typing import Protocol
+ HAVE_PROTOCOL = True
+else:
+ try:
+ from typing_extensions import Protocol
+ except ImportError:
+ HAVE_PROTOCOL = False
+ else:
+ HAVE_PROTOCOL = True
+
+if TYPE_CHECKING or HAVE_PROTOCOL:
+ _T = TypeVar("_T")
+ _2Tuple = Tuple[_T, _T]
+
+ _NBit_co = TypeVar("_NBit_co", covariant=True, bound=NBitBase)
+ _NBit = TypeVar("_NBit", bound=NBitBase)
+
+ _IntType = TypeVar("_IntType", bound=integer)
+ _FloatType = TypeVar("_FloatType", bound=floating)
+ _NumberType = TypeVar("_NumberType", bound=number)
+ _NumberType_co = TypeVar("_NumberType_co", covariant=True, bound=number)
+ _GenericType_co = TypeVar("_GenericType_co", covariant=True, bound=generic)
+
+ class _BoolOp(Protocol[_GenericType_co]):
+ @overload
+ def __call__(self, __other: _BoolLike) -> _GenericType_co: ...
+ @overload # platform dependent
+ def __call__(self, __other: int) -> signedinteger[Any]: ...
+ @overload
+ def __call__(self, __other: float) -> float64: ...
+ @overload
+ def __call__(self, __other: complex) -> complex128: ...
+ @overload
+ def __call__(self, __other: _NumberType) -> _NumberType: ...
+
+ class _BoolBitOp(Protocol[_GenericType_co]):
+ @overload
+ def __call__(self, __other: _BoolLike) -> _GenericType_co: ...
+ @overload # platform dependent
+ def __call__(self, __other: int) -> signedinteger[Any]: ...
+ @overload
+ def __call__(self, __other: _IntType) -> _IntType: ...
+
+ class _BoolSub(Protocol):
+ # Note that `__other: bool_` is absent here
+ @overload
+ def __call__(self, __other: bool) -> NoReturn: ...
+ @overload # platform dependent
+ def __call__(self, __other: int) -> signedinteger[Any]: ...
+ @overload
+ def __call__(self, __other: float) -> float64: ...
+ @overload
+ def __call__(self, __other: complex) -> complex128: ...
+ @overload
+ def __call__(self, __other: _NumberType) -> _NumberType: ...
+
+ class _BoolTrueDiv(Protocol):
+ @overload
+ def __call__(self, __other: Union[float, _IntLike]) -> float64: ...
+ @overload
+ def __call__(self, __other: complex) -> complex128: ...
+ @overload
+ def __call__(self, __other: _NumberType) -> _NumberType: ...
+
+ class _BoolMod(Protocol):
+ @overload
+ def __call__(self, __other: _BoolLike) -> int8: ...
+ @overload # platform dependent
+ def __call__(self, __other: int) -> signedinteger[Any]: ...
+ @overload
+ def __call__(self, __other: float) -> float64: ...
+ @overload
+ def __call__(self, __other: _IntType) -> _IntType: ...
+ @overload
+ def __call__(self, __other: _FloatType) -> _FloatType: ...
+
+ class _BoolDivMod(Protocol):
+ @overload
+ def __call__(self, __other: _BoolLike) -> _2Tuple[int8]: ...
+ @overload # platform dependent
+ def __call__(self, __other: int) -> _2Tuple[signedinteger[Any]]: ...
+ @overload
+ def __call__(self, __other: float) -> _2Tuple[float64]: ...
+ @overload
+ def __call__(self, __other: _IntType) -> _2Tuple[_IntType]: ...
+ @overload
+ def __call__(self, __other: _FloatType) -> _2Tuple[_FloatType]: ...
+
+ class _TD64Div(Protocol[_NumberType_co]):
+ @overload
+ def __call__(self, __other: timedelta64) -> _NumberType_co: ...
+ @overload
+ def __call__(self, __other: _FloatLike) -> timedelta64: ...
+
+ class _IntTrueDiv(Protocol[_NBit_co]):
+ @overload
+ def __call__(self, __other: bool) -> floating[_NBit_co]: ...
+ @overload
+ def __call__(self, __other: int) -> floating[Any]: ...
+ @overload
+ def __call__(self, __other: float) -> float64: ...
+ @overload
+ def __call__(self, __other: complex) -> complex128: ...
+ @overload
+ def __call__(self, __other: integer[_NBit]) -> floating[Union[_NBit_co, _NBit]]: ...
+
+ class _UnsignedIntOp(Protocol[_NBit_co]):
+ # NOTE: `uint64 + signedinteger -> float64`
+ @overload
+ def __call__(self, __other: bool) -> unsignedinteger[_NBit_co]: ...
+ @overload
+ def __call__(
+ self, __other: Union[int, signedinteger[Any]]
+ ) -> Union[signedinteger[Any], float64]: ...
+ @overload
+ def __call__(self, __other: float) -> float64: ...
+ @overload
+ def __call__(self, __other: complex) -> complex128: ...
+ @overload
+ def __call__(
+ self, __other: unsignedinteger[_NBit]
+ ) -> unsignedinteger[Union[_NBit_co, _NBit]]: ...
+
+ class _UnsignedIntBitOp(Protocol[_NBit_co]):
+ @overload
+ def __call__(self, __other: bool) -> unsignedinteger[_NBit_co]: ...
+ @overload
+ def __call__(self, __other: int) -> signedinteger[Any]: ...
+ @overload
+ def __call__(self, __other: signedinteger[Any]) -> signedinteger[Any]: ...
+ @overload
+ def __call__(
+ self, __other: unsignedinteger[_NBit]
+ ) -> unsignedinteger[Union[_NBit_co, _NBit]]: ...
+
+ class _UnsignedIntMod(Protocol[_NBit_co]):
+ @overload
+ def __call__(self, __other: bool) -> unsignedinteger[_NBit_co]: ...
+ @overload
+ def __call__(
+ self, __other: Union[int, signedinteger[Any]]
+ ) -> Union[signedinteger[Any], float64]: ...
+ @overload
+ def __call__(self, __other: float) -> float64: ...
+ @overload
+ def __call__(
+ self, __other: unsignedinteger[_NBit]
+ ) -> unsignedinteger[Union[_NBit_co, _NBit]]: ...
+
+ class _UnsignedIntDivMod(Protocol[_NBit_co]):
+ @overload
+ def __call__(self, __other: bool) -> _2Tuple[signedinteger[_NBit_co]]: ...
+ @overload
+ def __call__(
+ self, __other: Union[int, signedinteger[Any]]
+ ) -> Union[_2Tuple[signedinteger[Any]], _2Tuple[float64]]: ...
+ @overload
+ def __call__(self, __other: float) -> _2Tuple[float64]: ...
+ @overload
+ def __call__(
+ self, __other: unsignedinteger[_NBit]
+ ) -> _2Tuple[unsignedinteger[Union[_NBit_co, _NBit]]]: ...
+
+ class _SignedIntOp(Protocol[_NBit_co]):
+ @overload
+ def __call__(self, __other: bool) -> signedinteger[_NBit_co]: ...
+ @overload
+ def __call__(self, __other: int) -> signedinteger[Any]: ...
+ @overload
+ def __call__(self, __other: float) -> float64: ...
+ @overload
+ def __call__(self, __other: complex) -> complex128: ...
+ @overload
+ def __call__(
+ self, __other: signedinteger[_NBit]
+ ) -> signedinteger[Union[_NBit_co, _NBit]]: ...
+
+ class _SignedIntBitOp(Protocol[_NBit_co]):
+ @overload
+ def __call__(self, __other: bool) -> signedinteger[_NBit_co]: ...
+ @overload
+ def __call__(self, __other: int) -> signedinteger[Any]: ...
+ @overload
+ def __call__(
+ self, __other: signedinteger[_NBit]
+ ) -> signedinteger[Union[_NBit_co, _NBit]]: ...
+
+ class _SignedIntMod(Protocol[_NBit_co]):
+ @overload
+ def __call__(self, __other: bool) -> signedinteger[_NBit_co]: ...
+ @overload
+ def __call__(self, __other: int) -> signedinteger[Any]: ...
+ @overload
+ def __call__(self, __other: float) -> float64: ...
+ @overload
+ def __call__(
+ self, __other: signedinteger[_NBit]
+ ) -> signedinteger[Union[_NBit_co, _NBit]]: ...
+
+ class _SignedIntDivMod(Protocol[_NBit_co]):
+ @overload
+ def __call__(self, __other: bool) -> _2Tuple[signedinteger[_NBit_co]]: ...
+ @overload
+ def __call__(self, __other: int) -> _2Tuple[signedinteger[Any]]: ...
+ @overload
+ def __call__(self, __other: float) -> _2Tuple[float64]: ...
+ @overload
+ def __call__(
+ self, __other: signedinteger[_NBit]
+ ) -> _2Tuple[signedinteger[Union[_NBit_co, _NBit]]]: ...
+
+ class _FloatOp(Protocol[_NBit_co]):
+ @overload
+ def __call__(self, __other: bool) -> floating[_NBit_co]: ...
+ @overload
+ def __call__(self, __other: int) -> floating[Any]: ...
+ @overload
+ def __call__(self, __other: float) -> float64: ...
+ @overload
+ def __call__(self, __other: complex) -> complex128: ...
+ @overload
+ def __call__(
+ self, __other: Union[integer[_NBit], floating[_NBit]]
+ ) -> floating[Union[_NBit_co, _NBit]]: ...
+
+ class _FloatMod(Protocol[_NBit_co]):
+ @overload
+ def __call__(self, __other: bool) -> floating[_NBit_co]: ...
+ @overload
+ def __call__(self, __other: int) -> floating[Any]: ...
+ @overload
+ def __call__(self, __other: float) -> float64: ...
+ @overload
+ def __call__(
+ self, __other: Union[integer[_NBit], floating[_NBit]]
+ ) -> floating[Union[_NBit_co, _NBit]]: ...
+
+ class _FloatDivMod(Protocol[_NBit_co]):
+ @overload
+ def __call__(self, __other: bool) -> _2Tuple[floating[_NBit_co]]: ...
+ @overload
+ def __call__(self, __other: int) -> _2Tuple[floating[Any]]: ...
+ @overload
+ def __call__(self, __other: float) -> _2Tuple[float64]: ...
+ @overload
+ def __call__(
+ self, __other: Union[integer[_NBit], floating[_NBit]]
+ ) -> _2Tuple[floating[Union[_NBit_co, _NBit]]]: ...
+
+ class _ComplexOp(Protocol[_NBit_co]):
+ @overload
+ def __call__(self, __other: bool) -> complexfloating[_NBit_co, _NBit_co]: ...
+ @overload
+ def __call__(self, __other: int) -> complexfloating[Any, Any]: ...
+ @overload
+ def __call__(self, __other: Union[float, complex]) -> complex128: ...
+ @overload
+ def __call__(
+ self,
+ __other: Union[
+ integer[_NBit],
+ floating[_NBit],
+ complexfloating[_NBit, _NBit],
+ ]
+ ) -> complexfloating[Union[_NBit_co, _NBit], Union[_NBit_co, _NBit]]: ...
+
+ class _NumberOp(Protocol):
+ def __call__(self, __other: _NumberLike) -> number: ...
+
+ class _ComparisonOp(Protocol[_T]):
+ @overload
+ def __call__(self, __other: _T) -> bool_: ...
+ @overload
+ def __call__(self, __other: ArrayLike) -> Union[ndarray, bool_]: ...
+
+else:
+ _BoolOp = Any
+ _BoolBitOp = Any
+ _BoolSub = Any
+ _BoolTrueDiv = Any
+ _BoolMod = Any
+ _BoolDivMod = Any
+ _TD64Div = Any
+ _IntTrueDiv = Any
+ _UnsignedIntOp = Any
+ _UnsignedIntBitOp = Any
+ _UnsignedIntMod = Any
+ _UnsignedIntDivMod = Any
+ _SignedIntOp = Any
+ _SignedIntBitOp = Any
+ _SignedIntMod = Any
+ _SignedIntDivMod = Any
+ _FloatOp = Any
+ _FloatMod = Any
+ _FloatDivMod = Any
+ _ComplexOp = Any
+ _NumberOp = Any
+ _ComparisonOp = Any
diff --git a/numpy/typing/_dtype_like.py b/numpy/typing/_dtype_like.py
index b9df0af04..1953bd5fc 100644
--- a/numpy/typing/_dtype_like.py
+++ b/numpy/typing/_dtype_like.py
@@ -1,25 +1,50 @@
-from typing import Any, Dict, List, Sequence, Tuple, Union
+import sys
+from typing import Any, List, Sequence, Tuple, Union, TYPE_CHECKING
from numpy import dtype
from ._shape import _ShapeLike
-_DtypeLikeNested = Any # TODO: wait for support for recursive types
+if sys.version_info >= (3, 8):
+ from typing import Protocol, TypedDict
+ HAVE_PROTOCOL = True
+else:
+ try:
+ from typing_extensions import Protocol, TypedDict
+ except ImportError:
+ HAVE_PROTOCOL = False
+ else:
+ HAVE_PROTOCOL = True
-# Anything that can be coerced into numpy.dtype.
-# Reference: https://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html
-DtypeLike = Union[
- dtype,
- # default data type (float64)
- None,
- # array-scalar types and generic types
- type, # TODO: enumerate these when we add type hints for numpy scalars
- # TODO: add a protocol for anything with a dtype attribute
- # character codes, type strings or comma-separated fields, e.g., 'float64'
- str,
+_DTypeLikeNested = Any # TODO: wait for support for recursive types
+
+if TYPE_CHECKING or HAVE_PROTOCOL:
+ # Mandatory keys
+ class _DTypeDictBase(TypedDict):
+ names: Sequence[str]
+ formats: Sequence[_DTypeLikeNested]
+
+ # Mandatory + optional keys
+ class _DTypeDict(_DTypeDictBase, total=False):
+ offsets: Sequence[int]
+ titles: Sequence[Any] # Only `str` elements are usable as indexing aliases, but all objects are legal
+ itemsize: int
+ aligned: bool
+
+ # A protocol for anything with the dtype attribute
+ class _SupportsDType(Protocol):
+ dtype: _DTypeLikeNested
+
+else:
+ _DTypeDict = Any
+ _SupportsDType = Any
+
+
+# Would create a dtype[np.void]
+_VoidDTypeLike = Union[
# (flexible_dtype, itemsize)
- Tuple[_DtypeLikeNested, int],
+ Tuple[_DTypeLikeNested, int],
# (fixed_dtype, shape)
- Tuple[_DtypeLikeNested, _ShapeLike],
+ Tuple[_DTypeLikeNested, _ShapeLike],
# [(field_name, field_dtype, field_shape), ...]
#
# The type here is quite broad because NumPy accepts quite a wide
@@ -28,19 +53,29 @@ DtypeLike = Union[
List[Any],
# {'names': ..., 'formats': ..., 'offsets': ..., 'titles': ...,
# 'itemsize': ...}
- # TODO: use TypedDict when/if it's officially supported
- Dict[
- str,
- Union[
- Sequence[str], # names
- Sequence[_DtypeLikeNested], # formats
- Sequence[int], # offsets
- Sequence[Union[bytes, str, None]], # titles
- int, # itemsize
- ],
- ],
- # {'field1': ..., 'field2': ..., ...}
- Dict[str, Tuple[_DtypeLikeNested, int]],
+ _DTypeDict,
# (base_dtype, new_dtype)
- Tuple[_DtypeLikeNested, _DtypeLikeNested],
+ Tuple[_DTypeLikeNested, _DTypeLikeNested],
]
+
+# Anything that can be coerced into numpy.dtype.
+# Reference: https://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html
+DTypeLike = Union[
+ dtype,
+ # default data type (float64)
+ None,
+ # array-scalar types and generic types
+ type, # TODO: enumerate these when we add type hints for numpy scalars
+ # anything with a dtype attribute
+ _SupportsDType,
+ # character codes, type strings or comma-separated fields, e.g., 'float64'
+ str,
+ _VoidDTypeLike,
+]
+
+# NOTE: while it is possible to provide the dtype as a dict of
+# dtype-like objects (e.g. `{'field1': ..., 'field2': ..., ...}`),
+# this syntax is officially discourged and
+# therefore not included in the Union defining `DTypeLike`.
+#
+# See https://github.com/numpy/numpy/issues/16891 for more details.
diff --git a/numpy/typing/_scalars.py b/numpy/typing/_scalars.py
new file mode 100644
index 000000000..90b2eff7b
--- /dev/null
+++ b/numpy/typing/_scalars.py
@@ -0,0 +1,30 @@
+from typing import Union, Tuple, Any
+
+import numpy as np
+
+# NOTE: `_StrLike` and `_BytesLike` are pointless, as `np.str_` and `np.bytes_`
+# are already subclasses of their builtin counterpart
+
+_CharLike = Union[str, bytes]
+
+# The 6 `<X>Like` type-aliases below represent all scalars that can be
+# coerced into `<X>` (with the casting rule `same_kind`)
+_BoolLike = Union[bool, np.bool_]
+_UIntLike = Union[_BoolLike, np.unsignedinteger]
+_IntLike = Union[_BoolLike, int, np.integer]
+_FloatLike = Union[_IntLike, float, np.floating]
+_ComplexLike = Union[_FloatLike, complex, np.complexfloating]
+_TD64Like = Union[_IntLike, np.timedelta64]
+
+_NumberLike = Union[int, float, complex, np.number, np.bool_]
+_ScalarLike = Union[
+ int,
+ float,
+ complex,
+ str,
+ bytes,
+ np.generic,
+]
+
+# `_VoidLike` is technically not a scalar, but it's close enough
+_VoidLike = Union[Tuple[Any, ...], np.void]
diff --git a/numpy/typing/setup.py b/numpy/typing/setup.py
new file mode 100644
index 000000000..c444e769f
--- /dev/null
+++ b/numpy/typing/setup.py
@@ -0,0 +1,11 @@
+def configuration(parent_package='', top_path=None):
+ from numpy.distutils.misc_util import Configuration
+ config = Configuration('typing', parent_package, top_path)
+ config.add_subpackage('tests')
+ config.add_data_dir('tests/data')
+ return config
+
+
+if __name__ == '__main__':
+ from numpy.distutils.core import setup
+ setup(configuration=configuration)
diff --git a/numpy/typing/tests/__init__.py b/numpy/typing/tests/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/numpy/typing/tests/__init__.py
diff --git a/numpy/typing/tests/data/fail/arithmetic.py b/numpy/typing/tests/data/fail/arithmetic.py
new file mode 100644
index 000000000..f32eddc4b
--- /dev/null
+++ b/numpy/typing/tests/data/fail/arithmetic.py
@@ -0,0 +1,16 @@
+import numpy as np
+
+b_ = np.bool_()
+dt = np.datetime64(0, "D")
+td = np.timedelta64(0, "D")
+
+b_ - b_ # E: No overload variant
+
+dt + dt # E: Unsupported operand types
+td - dt # E: Unsupported operand types
+td % 1 # E: Unsupported operand types
+td / dt # E: No overload
+td % dt # E: Unsupported operand types
+
+-b_ # E: Unsupported operand type
++b_ # E: Unsupported operand type
diff --git a/numpy/typing/tests/data/fail/array_constructors.py b/numpy/typing/tests/data/fail/array_constructors.py
new file mode 100644
index 000000000..9cb59fe5f
--- /dev/null
+++ b/numpy/typing/tests/data/fail/array_constructors.py
@@ -0,0 +1,31 @@
+import numpy as np
+
+a: np.ndarray
+generator = (i for i in range(10))
+
+np.require(a, requirements=1) # E: No overload variant
+np.require(a, requirements="TEST") # E: incompatible type
+
+np.zeros("test") # E: incompatible type
+np.zeros() # E: Too few arguments
+
+np.ones("test") # E: incompatible type
+np.ones() # E: Too few arguments
+
+np.array(0, float, True) # E: Too many positional
+
+np.linspace(None, 'bob') # E: No overload variant
+np.linspace(0, 2, num=10.0) # E: No overload variant
+np.linspace(0, 2, endpoint='True') # E: No overload variant
+np.linspace(0, 2, retstep=b'False') # E: No overload variant
+np.linspace(0, 2, dtype=0) # E: No overload variant
+np.linspace(0, 2, axis=None) # E: No overload variant
+
+np.logspace(None, 'bob') # E: Argument 1
+np.logspace(0, 2, base=None) # E: Argument "base"
+
+np.geomspace(None, 'bob') # E: Argument 1
+
+np.stack(generator) # E: No overload variant
+np.hstack({1, 2}) # E: incompatible type
+np.vstack(1) # E: incompatible type
diff --git a/numpy/typing/tests/data/fail/array_like.py b/numpy/typing/tests/data/fail/array_like.py
new file mode 100644
index 000000000..3bbd29061
--- /dev/null
+++ b/numpy/typing/tests/data/fail/array_like.py
@@ -0,0 +1,16 @@
+import numpy as np
+from numpy.typing import ArrayLike
+
+
+class A:
+ pass
+
+
+x1: ArrayLike = (i for i in range(10)) # E: Incompatible types in assignment
+x2: ArrayLike = A() # E: Incompatible types in assignment
+x3: ArrayLike = {1: "foo", 2: "bar"} # E: Incompatible types in assignment
+
+scalar = np.int64(1)
+scalar.__array__(dtype=np.float64) # E: No overload variant
+array = np.array([1])
+array.__array__(dtype=np.float64) # E: No overload variant
diff --git a/numpy/typing/tests/data/fail/bitwise_ops.py b/numpy/typing/tests/data/fail/bitwise_ops.py
new file mode 100644
index 000000000..8a8f89755
--- /dev/null
+++ b/numpy/typing/tests/data/fail/bitwise_ops.py
@@ -0,0 +1,20 @@
+import numpy as np
+
+i8 = np.int64()
+i4 = np.int32()
+u8 = np.uint64()
+b_ = np.bool_()
+i = int()
+
+f8 = np.float64()
+
+b_ >> f8 # E: No overload variant
+i8 << f8 # E: No overload variant
+i | f8 # E: Unsupported operand types
+i8 ^ f8 # E: No overload variant
+u8 & f8 # E: No overload variant
+~f8 # E: Unsupported operand type
+
+# mypys' error message for `NoReturn` is unfortunately pretty bad
+# TODO: Reenable this once we add support for numerical precision for `number`s
+# a = u8 | 0 # E: Need type annotation
diff --git a/numpy/typing/tests/data/fail/constants.py b/numpy/typing/tests/data/fail/constants.py
new file mode 100644
index 000000000..67ee0e0bc
--- /dev/null
+++ b/numpy/typing/tests/data/fail/constants.py
@@ -0,0 +1,6 @@
+import numpy as np
+
+np.Inf = np.Inf # E: Cannot assign to final
+np.ALLOW_THREADS = np.ALLOW_THREADS # E: Cannot assign to final
+np.little_endian = np.little_endian # E: Cannot assign to final
+np.UFUNC_PYVALS_NAME = np.UFUNC_PYVALS_NAME # E: Cannot assign to final
diff --git a/numpy/typing/tests/data/fail/dtype.py b/numpy/typing/tests/data/fail/dtype.py
new file mode 100644
index 000000000..7d4783d8f
--- /dev/null
+++ b/numpy/typing/tests/data/fail/dtype.py
@@ -0,0 +1,16 @@
+import numpy as np
+
+class Test:
+ not_dtype = float
+
+
+np.dtype(Test()) # E: No overload variant of "dtype" matches
+
+np.dtype( # E: No overload variant of "dtype" matches
+ {
+ "field1": (float, 1),
+ "field2": (int, 3),
+ }
+)
+
+np.dtype[np.float64](np.int64) # E: Argument 1 to "dtype" has incompatible type
diff --git a/numpy/typing/tests/data/fail/flatiter.py b/numpy/typing/tests/data/fail/flatiter.py
new file mode 100644
index 000000000..544ffbe4a
--- /dev/null
+++ b/numpy/typing/tests/data/fail/flatiter.py
@@ -0,0 +1,25 @@
+from typing import Any
+
+import numpy as np
+from numpy.typing import _SupportsArray
+
+
+class Index:
+ def __index__(self) -> int:
+ ...
+
+
+a: "np.flatiter[np.ndarray]"
+supports_array: _SupportsArray
+
+a.base = Any # E: Property "base" defined in "flatiter" is read-only
+a.coords = Any # E: Property "coords" defined in "flatiter" is read-only
+a.index = Any # E: Property "index" defined in "flatiter" is read-only
+a.copy(order='C') # E: Unexpected keyword argument
+
+# NOTE: Contrary to `ndarray.__getitem__` its counterpart in `flatiter`
+# does not accept objects with the `__array__` or `__index__` protocols;
+# boolean indexing is just plain broken (gh-17175)
+a[np.bool_()] # E: No overload variant of "__getitem__"
+a[Index()] # E: No overload variant of "__getitem__"
+a[supports_array] # E: No overload variant of "__getitem__"
diff --git a/numpy/typing/tests/data/fail/fromnumeric.py b/numpy/typing/tests/data/fail/fromnumeric.py
new file mode 100644
index 000000000..c9156895d
--- /dev/null
+++ b/numpy/typing/tests/data/fail/fromnumeric.py
@@ -0,0 +1,154 @@
+"""Tests for :mod:`numpy.core.fromnumeric`."""
+
+import numpy as np
+
+A = np.array(True, ndmin=2, dtype=bool)
+A.setflags(write=False)
+
+a = np.bool_(True)
+
+np.take(a, None) # E: No overload variant of "take" matches argument type
+np.take(a, axis=1.0) # E: No overload variant of "take" matches argument type
+np.take(A, out=1) # E: No overload variant of "take" matches argument type
+np.take(A, mode="bob") # E: No overload variant of "take" matches argument type
+
+np.reshape(a, None) # E: Argument 2 to "reshape" has incompatible type
+np.reshape(A, 1, order="bob") # E: Argument "order" to "reshape" has incompatible type
+
+np.choose(a, None) # E: No overload variant of "choose" matches argument type
+np.choose(a, out=1.0) # E: No overload variant of "choose" matches argument type
+np.choose(A, mode="bob") # E: No overload variant of "choose" matches argument type
+
+np.repeat(a, None) # E: Argument 2 to "repeat" has incompatible type
+np.repeat(A, 1, axis=1.0) # E: Argument "axis" to "repeat" has incompatible type
+
+np.swapaxes(A, None, 1) # E: Argument 2 to "swapaxes" has incompatible type
+np.swapaxes(A, 1, [0]) # E: Argument 3 to "swapaxes" has incompatible type
+
+np.transpose(A, axes=1.0) # E: Argument "axes" to "transpose" has incompatible type
+
+np.partition(a, None) # E: Argument 2 to "partition" has incompatible type
+np.partition(
+ a, 0, axis="bob" # E: Argument "axis" to "partition" has incompatible type
+)
+np.partition(
+ A, 0, kind="bob" # E: Argument "kind" to "partition" has incompatible type
+)
+np.partition(
+ A, 0, order=range(5) # E: Argument "order" to "partition" has incompatible type
+)
+
+np.argpartition( # E: No overload variant of "argpartition" matches argument type
+ a, None
+)
+np.argpartition( # E: No overload variant of "argpartition" matches argument type
+ a, 0, axis="bob"
+)
+np.argpartition( # E: No overload variant of "argpartition" matches argument type
+ A, 0, kind="bob"
+)
+np.argpartition(
+ A, 0, order=range(5) # E: Argument "order" to "argpartition" has incompatible type
+)
+
+np.sort(A, axis="bob") # E: Argument "axis" to "sort" has incompatible type
+np.sort(A, kind="bob") # E: Argument "kind" to "sort" has incompatible type
+np.sort(A, order=range(5)) # E: Argument "order" to "sort" has incompatible type
+
+np.argsort(A, axis="bob") # E: Argument "axis" to "argsort" has incompatible type
+np.argsort(A, kind="bob") # E: Argument "kind" to "argsort" has incompatible type
+np.argsort(A, order=range(5)) # E: Argument "order" to "argsort" has incompatible type
+
+np.argmax(A, axis="bob") # E: No overload variant of "argmax" matches argument type
+np.argmax(A, kind="bob") # E: No overload variant of "argmax" matches argument type
+
+np.argmin(A, axis="bob") # E: No overload variant of "argmin" matches argument type
+np.argmin(A, kind="bob") # E: No overload variant of "argmin" matches argument type
+
+np.searchsorted( # E: No overload variant of "searchsorted" matches argument type
+ A[0], 0, side="bob"
+)
+np.searchsorted( # E: No overload variant of "searchsorted" matches argument type
+ A[0], 0, sorter=1.0
+)
+
+np.resize(A, 1.0) # E: Argument 2 to "resize" has incompatible type
+
+np.squeeze(A, 1.0) # E: No overload variant of "squeeze" matches argument type
+
+np.diagonal(A, offset=None) # E: Argument "offset" to "diagonal" has incompatible type
+np.diagonal(A, axis1="bob") # E: Argument "axis1" to "diagonal" has incompatible type
+np.diagonal(A, axis2=[]) # E: Argument "axis2" to "diagonal" has incompatible type
+
+np.trace(A, offset=None) # E: Argument "offset" to "trace" has incompatible type
+np.trace(A, axis1="bob") # E: Argument "axis1" to "trace" has incompatible type
+np.trace(A, axis2=[]) # E: Argument "axis2" to "trace" has incompatible type
+
+np.ravel(a, order="bob") # E: Argument "order" to "ravel" has incompatible type
+
+np.compress(
+ [True], A, axis=1.0 # E: Argument "axis" to "compress" has incompatible type
+)
+
+np.clip(a, 1, 2, out=1) # E: No overload variant of "clip" matches argument type
+np.clip(1, None, None) # E: No overload variant of "clip" matches argument type
+
+np.sum(a, axis=1.0) # E: No overload variant of "sum" matches argument type
+np.sum(a, keepdims=1.0) # E: No overload variant of "sum" matches argument type
+np.sum(a, initial=[1]) # E: No overload variant of "sum" matches argument type
+
+np.all(a, axis=1.0) # E: No overload variant of "all" matches argument type
+np.all(a, keepdims=1.0) # E: No overload variant of "all" matches argument type
+np.all(a, out=1.0) # E: No overload variant of "all" matches argument type
+
+np.any(a, axis=1.0) # E: No overload variant of "any" matches argument type
+np.any(a, keepdims=1.0) # E: No overload variant of "any" matches argument type
+np.any(a, out=1.0) # E: No overload variant of "any" matches argument type
+
+np.cumsum(a, axis=1.0) # E: Argument "axis" to "cumsum" has incompatible type
+np.cumsum(a, dtype=1.0) # E: Argument "dtype" to "cumsum" has incompatible type
+np.cumsum(a, out=1.0) # E: Argument "out" to "cumsum" has incompatible type
+
+np.ptp(a, axis=1.0) # E: No overload variant of "ptp" matches argument type
+np.ptp(a, keepdims=1.0) # E: No overload variant of "ptp" matches argument type
+np.ptp(a, out=1.0) # E: No overload variant of "ptp" matches argument type
+
+np.amax(a, axis=1.0) # E: No overload variant of "amax" matches argument type
+np.amax(a, keepdims=1.0) # E: No overload variant of "amax" matches argument type
+np.amax(a, out=1.0) # E: No overload variant of "amax" matches argument type
+np.amax(a, initial=[1.0]) # E: No overload variant of "amax" matches argument type
+np.amax(a, where=[1.0]) # E: List item 0 has incompatible type
+
+np.amin(a, axis=1.0) # E: No overload variant of "amin" matches argument type
+np.amin(a, keepdims=1.0) # E: No overload variant of "amin" matches argument type
+np.amin(a, out=1.0) # E: No overload variant of "amin" matches argument type
+np.amin(a, initial=[1.0]) # E: No overload variant of "amin" matches argument type
+np.amin(a, where=[1.0]) # E: List item 0 has incompatible type
+
+np.prod(a, axis=1.0) # E: No overload variant of "prod" matches argument type
+np.prod(a, out=False) # E: No overload variant of "prod" matches argument type
+np.prod(a, keepdims=1.0) # E: No overload variant of "prod" matches argument type
+np.prod(a, initial=int) # E: No overload variant of "prod" matches argument type
+np.prod(a, where=1.0) # E: No overload variant of "prod" matches argument type
+
+np.cumprod(a, axis=1.0) # E: Argument "axis" to "cumprod" has incompatible type
+np.cumprod(a, out=False) # E: Argument "out" to "cumprod" has incompatible type
+
+np.size(a, axis=1.0) # E: Argument "axis" to "size" has incompatible type
+
+np.around(a, decimals=1.0) # E: No overload variant of "around" matches argument type
+np.around(a, out=type) # E: No overload variant of "around" matches argument type
+
+np.mean(a, axis=1.0) # E: No overload variant of "mean" matches argument type
+np.mean(a, out=False) # E: No overload variant of "mean" matches argument type
+np.mean(a, keepdims=1.0) # E: No overload variant of "mean" matches argument type
+
+np.std(a, axis=1.0) # E: No overload variant of "std" matches argument type
+np.std(a, out=False) # E: No overload variant of "std" matches argument type
+np.std(a, ddof='test') # E: No overload variant of "std" matches argument type
+np.std(a, keepdims=1.0) # E: No overload variant of "std" matches argument type
+
+np.var(a, axis=1.0) # E: No overload variant of "var" matches argument type
+np.var(a, out=False) # E: No overload variant of "var" matches argument type
+np.var(a, ddof='test') # E: No overload variant of "var" matches argument type
+np.var(a, keepdims=1.0) # E: No overload variant of "var" matches argument type
diff --git a/numpy/typing/tests/data/fail/modules.py b/numpy/typing/tests/data/fail/modules.py
new file mode 100644
index 000000000..5e2d820ab
--- /dev/null
+++ b/numpy/typing/tests/data/fail/modules.py
@@ -0,0 +1,10 @@
+import numpy as np
+
+np.testing.bob # E: Module has no attribute
+np.bob # E: Module has no attribute
+
+# Stdlib modules in the namespace by accident
+np.warnings # E: Module has no attribute
+np.sys # E: Module has no attribute
+np.os # E: Module has no attribute
+np.math # E: Module has no attribute
diff --git a/numpy/typing/tests/data/fail/ndarray.py b/numpy/typing/tests/data/fail/ndarray.py
new file mode 100644
index 000000000..5a5130d40
--- /dev/null
+++ b/numpy/typing/tests/data/fail/ndarray.py
@@ -0,0 +1,11 @@
+import numpy as np
+
+# Ban setting dtype since mutating the type of the array in place
+# makes having ndarray be generic over dtype impossible. Generally
+# users should use `ndarray.view` in this situation anyway. See
+#
+# https://github.com/numpy/numpy-stubs/issues/7
+#
+# for more context.
+float_array = np.array([1.0])
+float_array.dtype = np.bool_ # E: Property "dtype" defined in "ndarray" is read-only
diff --git a/numpy/typing/tests/data/fail/ndarray_misc.py b/numpy/typing/tests/data/fail/ndarray_misc.py
new file mode 100644
index 000000000..1e1496bfe
--- /dev/null
+++ b/numpy/typing/tests/data/fail/ndarray_misc.py
@@ -0,0 +1,21 @@
+"""
+Tests for miscellaneous (non-magic) ``np.ndarray``/``np.generic`` methods.
+
+More extensive tests are performed for the methods'
+function-based counterpart in `../from_numeric.py`.
+
+"""
+
+import numpy as np
+
+f8: np.float64
+
+f8.argpartition(0) # E: has no attribute
+f8.diagonal() # E: has no attribute
+f8.dot(1) # E: has no attribute
+f8.nonzero() # E: has no attribute
+f8.partition(0) # E: has no attribute
+f8.put(0, 2) # E: has no attribute
+f8.setfield(2, np.float64) # E: has no attribute
+f8.sort() # E: has no attribute
+f8.trace() # E: has no attribute
diff --git a/numpy/typing/tests/data/fail/numerictypes.py b/numpy/typing/tests/data/fail/numerictypes.py
new file mode 100644
index 000000000..94537a23b
--- /dev/null
+++ b/numpy/typing/tests/data/fail/numerictypes.py
@@ -0,0 +1,13 @@
+import numpy as np
+
+# Techincally this works, but probably shouldn't. See
+#
+# https://github.com/numpy/numpy/issues/16366
+#
+np.maximum_sctype(1) # E: incompatible type "int"
+
+np.issubsctype(1, np.int64) # E: incompatible type "int"
+
+np.issubdtype(1, np.int64) # E: incompatible type "int"
+
+np.find_common_type(np.int64, np.int64) # E: incompatible type "Type[signedinteger[Any]]"
diff --git a/numpy/typing/tests/data/fail/scalars.py b/numpy/typing/tests/data/fail/scalars.py
new file mode 100644
index 000000000..f09740875
--- /dev/null
+++ b/numpy/typing/tests/data/fail/scalars.py
@@ -0,0 +1,76 @@
+import numpy as np
+
+f8: np.float64
+
+# Construction
+
+np.float32(3j) # E: incompatible type
+
+# Technically the following examples are valid NumPy code. But they
+# are not considered a best practice, and people who wish to use the
+# stubs should instead do
+#
+# np.array([1.0, 0.0, 0.0], dtype=np.float32)
+# np.array([], dtype=np.complex64)
+#
+# See e.g. the discussion on the mailing list
+#
+# https://mail.python.org/pipermail/numpy-discussion/2020-April/080566.html
+#
+# and the issue
+#
+# https://github.com/numpy/numpy-stubs/issues/41
+#
+# for more context.
+np.float32([1.0, 0.0, 0.0]) # E: incompatible type
+np.complex64([]) # E: incompatible type
+
+np.complex64(1, 2) # E: Too many arguments
+# TODO: protocols (can't check for non-existent protocols w/ __getattr__)
+
+np.datetime64(0) # E: non-matching overload
+
+class A:
+ def __float__(self):
+ return 1.0
+
+
+np.int8(A()) # E: incompatible type
+np.int16(A()) # E: incompatible type
+np.int32(A()) # E: incompatible type
+np.int64(A()) # E: incompatible type
+np.uint8(A()) # E: incompatible type
+np.uint16(A()) # E: incompatible type
+np.uint32(A()) # E: incompatible type
+np.uint64(A()) # E: incompatible type
+
+np.void("test") # E: incompatible type
+
+np.generic(1) # E: Cannot instantiate abstract class
+np.number(1) # E: Cannot instantiate abstract class
+np.integer(1) # E: Cannot instantiate abstract class
+np.inexact(1) # E: Cannot instantiate abstract class
+np.character("test") # E: Cannot instantiate abstract class
+np.flexible(b"test") # E: Cannot instantiate abstract class
+
+np.float64(value=0.0) # E: Unexpected keyword argument
+np.int64(value=0) # E: Unexpected keyword argument
+np.uint64(value=0) # E: Unexpected keyword argument
+np.complex128(value=0.0j) # E: Unexpected keyword argument
+np.str_(value='bob') # E: No overload variant
+np.bytes_(value=b'test') # E: No overload variant
+np.void(value=b'test') # E: Unexpected keyword argument
+np.bool_(value=True) # E: Unexpected keyword argument
+np.datetime64(value="2019") # E: No overload variant
+np.timedelta64(value=0) # E: Unexpected keyword argument
+
+np.bytes_(b"hello", encoding='utf-8') # E: No overload variant
+np.str_("hello", encoding='utf-8') # E: No overload variant
+
+complex(np.bytes_("1")) # E: No overload variant
+
+f8.item(1) # E: incompatible type
+f8.item((0, 1)) # E: incompatible type
+f8.squeeze(axis=1) # E: incompatible type
+f8.squeeze(axis=(0, 1)) # E: incompatible type
+f8.transpose(1) # E: incompatible type
diff --git a/numpy/typing/tests/data/fail/ufunc_config.py b/numpy/typing/tests/data/fail/ufunc_config.py
new file mode 100644
index 000000000..f547fbb46
--- /dev/null
+++ b/numpy/typing/tests/data/fail/ufunc_config.py
@@ -0,0 +1,21 @@
+"""Typing tests for `numpy.core._ufunc_config`."""
+
+import numpy as np
+
+def func1(a: str, b: int, c: float) -> None: ...
+def func2(a: str, *, b: int) -> None: ...
+
+class Write1:
+ def write1(self, a: str) -> None: ...
+
+class Write2:
+ def write(self, a: str, b: str) -> None: ...
+
+class Write3:
+ def write(self, *, a: str) -> None: ...
+
+np.seterrcall(func1) # E: Argument 1 to "seterrcall" has incompatible type
+np.seterrcall(func2) # E: Argument 1 to "seterrcall" has incompatible type
+np.seterrcall(Write1()) # E: Argument 1 to "seterrcall" has incompatible type
+np.seterrcall(Write2()) # E: Argument 1 to "seterrcall" has incompatible type
+np.seterrcall(Write3()) # E: Argument 1 to "seterrcall" has incompatible type
diff --git a/numpy/typing/tests/data/fail/ufuncs.py b/numpy/typing/tests/data/fail/ufuncs.py
new file mode 100644
index 000000000..4da9d08ba
--- /dev/null
+++ b/numpy/typing/tests/data/fail/ufuncs.py
@@ -0,0 +1,7 @@
+import numpy as np
+
+np.sin.nin + "foo" # E: Unsupported operand types
+np.sin(1, foo="bar") # E: Unexpected keyword argument
+np.sin(1, extobj=["foo", "foo", "foo"]) # E: incompatible type
+
+np.abs(None) # E: incompatible type
diff --git a/numpy/typing/tests/data/fail/warnings_and_errors.py b/numpy/typing/tests/data/fail/warnings_and_errors.py
new file mode 100644
index 000000000..7390cc45f
--- /dev/null
+++ b/numpy/typing/tests/data/fail/warnings_and_errors.py
@@ -0,0 +1,7 @@
+import numpy as np
+
+np.AxisError(1.0) # E: Argument 1 to "AxisError" has incompatible type
+np.AxisError(1, ndim=2.0) # E: Argument "ndim" to "AxisError" has incompatible type
+np.AxisError(
+ 2, msg_prefix=404 # E: Argument "msg_prefix" to "AxisError" has incompatible type
+)
diff --git a/numpy/typing/tests/data/mypy.ini b/numpy/typing/tests/data/mypy.ini
new file mode 100644
index 000000000..91d93588a
--- /dev/null
+++ b/numpy/typing/tests/data/mypy.ini
@@ -0,0 +1,8 @@
+[mypy]
+mypy_path = ../../..
+
+[mypy-numpy]
+ignore_errors = True
+
+[mypy-numpy.*]
+ignore_errors = True
diff --git a/numpy/typing/tests/data/pass/arithmetic.py b/numpy/typing/tests/data/pass/arithmetic.py
new file mode 100644
index 000000000..ffbaf2975
--- /dev/null
+++ b/numpy/typing/tests/data/pass/arithmetic.py
@@ -0,0 +1,293 @@
+import numpy as np
+
+c16 = np.complex128(1)
+f8 = np.float64(1)
+i8 = np.int64(1)
+u8 = np.uint64(1)
+
+c8 = np.complex64(1)
+f4 = np.float32(1)
+i4 = np.int32(1)
+u4 = np.uint32(1)
+
+dt = np.datetime64(1, "D")
+td = np.timedelta64(1, "D")
+
+b_ = np.bool_(1)
+
+b = bool(1)
+c = complex(1)
+f = float(1)
+i = int(1)
+
+AR = np.ones(1, dtype=np.float64)
+AR.setflags(write=False)
+
+# unary ops
+
+-c16
+-c8
+-f8
+-f4
+-i8
+-i4
+-u8
+-u4
+-td
+-AR
+
++c16
++c8
++f8
++f4
++i8
++i4
++u8
++u4
++td
++AR
+
+abs(c16)
+abs(c8)
+abs(f8)
+abs(f4)
+abs(i8)
+abs(i4)
+abs(u8)
+abs(u4)
+abs(td)
+abs(b_)
+abs(AR)
+
+# Time structures
+
+dt + td
+dt + i
+dt + i4
+dt + i8
+dt - dt
+dt - i
+dt - i4
+dt - i8
+
+td + td
+td + i
+td + i4
+td + i8
+td - td
+td - i
+td - i4
+td - i8
+td / f
+td / f4
+td / f8
+td / td
+td // td
+td % td
+
+
+# boolean
+
+b_ / b
+b_ / b_
+b_ / i
+b_ / i8
+b_ / i4
+b_ / u8
+b_ / u4
+b_ / f
+b_ / f8
+b_ / f4
+b_ / c
+b_ / c16
+b_ / c8
+
+b / b_
+b_ / b_
+i / b_
+i8 / b_
+i4 / b_
+u8 / b_
+u4 / b_
+f / b_
+f8 / b_
+f4 / b_
+c / b_
+c16 / b_
+c8 / b_
+
+# Complex
+
+c16 + c16
+c16 + f8
+c16 + i8
+c16 + c8
+c16 + f4
+c16 + i4
+c16 + b_
+c16 + b
+c16 + c
+c16 + f
+c16 + i
+c16 + AR
+
+c16 + c16
+f8 + c16
+i8 + c16
+c8 + c16
+f4 + c16
+i4 + c16
+b_ + c16
+b + c16
+c + c16
+f + c16
+i + c16
+AR + c16
+
+c8 + c16
+c8 + f8
+c8 + i8
+c8 + c8
+c8 + f4
+c8 + i4
+c8 + b_
+c8 + b
+c8 + c
+c8 + f
+c8 + i
+c8 + AR
+
+c16 + c8
+f8 + c8
+i8 + c8
+c8 + c8
+f4 + c8
+i4 + c8
+b_ + c8
+b + c8
+c + c8
+f + c8
+i + c8
+AR + c8
+
+# Float
+
+f8 + f8
+f8 + i8
+f8 + f4
+f8 + i4
+f8 + b_
+f8 + b
+f8 + c
+f8 + f
+f8 + i
+f8 + AR
+
+f8 + f8
+i8 + f8
+f4 + f8
+i4 + f8
+b_ + f8
+b + f8
+c + f8
+f + f8
+i + f8
+AR + f8
+
+f4 + f8
+f4 + i8
+f4 + f4
+f4 + i4
+f4 + b_
+f4 + b
+f4 + c
+f4 + f
+f4 + i
+f4 + AR
+
+f8 + f4
+i8 + f4
+f4 + f4
+i4 + f4
+b_ + f4
+b + f4
+c + f4
+f + f4
+i + f4
+AR + f4
+
+# Int
+
+i8 + i8
+i8 + u8
+i8 + i4
+i8 + u4
+i8 + b_
+i8 + b
+i8 + c
+i8 + f
+i8 + i
+i8 + AR
+
+u8 + u8
+u8 + i4
+u8 + u4
+u8 + b_
+u8 + b
+u8 + c
+u8 + f
+u8 + i
+u8 + AR
+
+i8 + i8
+u8 + i8
+i4 + i8
+u4 + i8
+b_ + i8
+b + i8
+c + i8
+f + i8
+i + i8
+AR + i8
+
+u8 + u8
+i4 + u8
+u4 + u8
+b_ + u8
+b + u8
+c + u8
+f + u8
+i + u8
+AR + u8
+
+i4 + i8
+i4 + i4
+i4 + i
+i4 + b_
+i4 + b
+i4 + AR
+
+u4 + i8
+u4 + i4
+u4 + u8
+u4 + u4
+u4 + i
+u4 + b_
+u4 + b
+u4 + AR
+
+i8 + i4
+i4 + i4
+i + i4
+b_ + i4
+b + i4
+AR + i4
+
+i8 + u4
+i4 + u4
+u8 + u4
+u4 + u4
+b_ + u4
+b + u4
+i + u4
+AR + u4
diff --git a/numpy/typing/tests/data/pass/array_constructors.py b/numpy/typing/tests/data/pass/array_constructors.py
new file mode 100644
index 000000000..63208f139
--- /dev/null
+++ b/numpy/typing/tests/data/pass/array_constructors.py
@@ -0,0 +1,128 @@
+from typing import List, Any
+import numpy as np
+
+class Index:
+ def __index__(self) -> int:
+ return 0
+
+class SubClass(np.ndarray): ...
+
+i8 = np.int64(1)
+
+A = np.array([1])
+B = A.view(SubClass).copy()
+B_stack = np.array([[1], [1]]).view(SubClass)
+C = [1]
+
+def func(i: int, j: int, **kwargs: Any) -> SubClass:
+ return B
+
+np.array(1, dtype=float)
+np.array(1, copy=False)
+np.array(1, order='F')
+np.array(1, order=None)
+np.array(1, subok=True)
+np.array(1, ndmin=3)
+np.array(1, str, copy=True, order='C', subok=False, ndmin=2)
+
+np.asarray(A)
+np.asarray(B)
+np.asarray(C)
+
+np.asanyarray(A)
+np.asanyarray(B)
+np.asanyarray(B, dtype=int)
+np.asanyarray(C)
+
+np.ascontiguousarray(A)
+np.ascontiguousarray(B)
+np.ascontiguousarray(C)
+
+np.asfortranarray(A)
+np.asfortranarray(B)
+np.asfortranarray(C)
+
+np.require(A)
+np.require(B)
+np.require(B, dtype=int)
+np.require(B, requirements=None)
+np.require(B, requirements="E")
+np.require(B, requirements=["ENSUREARRAY"])
+np.require(B, requirements={"F", "E"})
+np.require(B, requirements=["C", "OWNDATA"])
+np.require(B, requirements="W")
+np.require(B, requirements="A")
+np.require(C)
+
+np.linspace(0, 2)
+np.linspace(0.5, [0, 1, 2])
+np.linspace([0, 1, 2], 3)
+np.linspace(0j, 2)
+np.linspace(0, 2, num=10)
+np.linspace(0, 2, endpoint=True)
+np.linspace(0, 2, retstep=True)
+np.linspace(0j, 2j, retstep=True)
+np.linspace(0, 2, dtype=bool)
+np.linspace([0, 1], [2, 3], axis=Index())
+
+np.logspace(0, 2, base=2)
+np.logspace(0, 2, base=2)
+np.logspace(0, 2, base=[1j, 2j], num=2)
+
+np.geomspace(1, 2)
+
+np.zeros_like(A)
+np.zeros_like(C)
+np.zeros_like(B)
+np.zeros_like(B, dtype=np.int64)
+
+np.ones_like(A)
+np.ones_like(C)
+np.ones_like(B)
+np.ones_like(B, dtype=np.int64)
+
+np.empty_like(A)
+np.empty_like(C)
+np.empty_like(B)
+np.empty_like(B, dtype=np.int64)
+
+np.full_like(A, i8)
+np.full_like(C, i8)
+np.full_like(B, i8)
+np.full_like(B, i8, dtype=np.int64)
+
+np.ones(1)
+np.ones([1, 1, 1])
+
+np.full(1, i8)
+np.full([1, 1, 1], i8)
+
+np.indices([1, 2, 3])
+np.indices([1, 2, 3], sparse=True)
+
+np.fromfunction(func, (3, 5))
+
+np.identity(10)
+
+np.atleast_1d(C)
+np.atleast_1d(A)
+np.atleast_1d(C, C)
+np.atleast_1d(C, A)
+np.atleast_1d(A, A)
+
+np.atleast_2d(C)
+
+np.atleast_3d(C)
+
+np.vstack([C, C])
+np.vstack([C, A])
+np.vstack([A, A])
+
+np.hstack([C, C])
+
+np.stack([C, C])
+np.stack([C, C], axis=0)
+np.stack([C, C], out=B_stack)
+
+np.block([[C, C], [C, C]])
+np.block(A)
diff --git a/numpy/typing/tests/data/pass/array_like.py b/numpy/typing/tests/data/pass/array_like.py
new file mode 100644
index 000000000..563fc08c7
--- /dev/null
+++ b/numpy/typing/tests/data/pass/array_like.py
@@ -0,0 +1,39 @@
+from typing import Any, List, Optional
+
+import numpy as np
+from numpy.typing import ArrayLike, DTypeLike, _SupportsArray
+
+x1: ArrayLike = True
+x2: ArrayLike = 5
+x3: ArrayLike = 1.0
+x4: ArrayLike = 1 + 1j
+x5: ArrayLike = np.int8(1)
+x6: ArrayLike = np.float64(1)
+x7: ArrayLike = np.complex128(1)
+x8: ArrayLike = np.array([1, 2, 3])
+x9: ArrayLike = [1, 2, 3]
+x10: ArrayLike = (1, 2, 3)
+x11: ArrayLike = "foo"
+x12: ArrayLike = memoryview(b'foo')
+
+
+class A:
+ def __array__(self, dtype: DTypeLike = None) -> np.ndarray:
+ return np.array([1, 2, 3])
+
+
+x13: ArrayLike = A()
+
+scalar: _SupportsArray = np.int64(1)
+scalar.__array__(None)
+array: _SupportsArray = np.array(1)
+array.__array__(None)
+
+a: _SupportsArray = A()
+a.__array__(None)
+a.__array__(dtype=None)
+
+# Escape hatch for when you mean to make something like an object
+# array.
+object_array_scalar: Any = (i for i in range(10))
+np.array(object_array_scalar)
diff --git a/numpy/typing/tests/data/pass/bitwise_ops.py b/numpy/typing/tests/data/pass/bitwise_ops.py
new file mode 100644
index 000000000..67449e2c2
--- /dev/null
+++ b/numpy/typing/tests/data/pass/bitwise_ops.py
@@ -0,0 +1,131 @@
+import numpy as np
+
+i8 = np.int64(1)
+u8 = np.uint64(1)
+
+i4 = np.int32(1)
+u4 = np.uint32(1)
+
+b_ = np.bool_(1)
+
+b = bool(1)
+i = int(1)
+
+AR = np.array([0, 1, 2], dtype=np.int32)
+AR.setflags(write=False)
+
+
+i8 << i8
+i8 >> i8
+i8 | i8
+i8 ^ i8
+i8 & i8
+
+i8 << AR
+i8 >> AR
+i8 | AR
+i8 ^ AR
+i8 & AR
+
+i4 << i4
+i4 >> i4
+i4 | i4
+i4 ^ i4
+i4 & i4
+
+i8 << i4
+i8 >> i4
+i8 | i4
+i8 ^ i4
+i8 & i4
+
+i8 << i
+i8 >> i
+i8 | i
+i8 ^ i
+i8 & i
+
+i8 << b_
+i8 >> b_
+i8 | b_
+i8 ^ b_
+i8 & b_
+
+i8 << b
+i8 >> b
+i8 | b
+i8 ^ b
+i8 & b
+
+u8 << u8
+u8 >> u8
+u8 | u8
+u8 ^ u8
+u8 & u8
+
+u8 << AR
+u8 >> AR
+u8 | AR
+u8 ^ AR
+u8 & AR
+
+u4 << u4
+u4 >> u4
+u4 | u4
+u4 ^ u4
+u4 & u4
+
+u4 << i4
+u4 >> i4
+u4 | i4
+u4 ^ i4
+u4 & i4
+
+u4 << i
+u4 >> i
+u4 | i
+u4 ^ i
+u4 & i
+
+u8 << b_
+u8 >> b_
+u8 | b_
+u8 ^ b_
+u8 & b_
+
+u8 << b
+u8 >> b
+u8 | b
+u8 ^ b
+u8 & b
+
+b_ << b_
+b_ >> b_
+b_ | b_
+b_ ^ b_
+b_ & b_
+
+b_ << AR
+b_ >> AR
+b_ | AR
+b_ ^ AR
+b_ & AR
+
+b_ << b
+b_ >> b
+b_ | b
+b_ ^ b
+b_ & b
+
+b_ << i
+b_ >> i
+b_ | i
+b_ ^ i
+b_ & i
+
+~i8
+~i4
+~u8
+~u4
+~b_
+~AR
diff --git a/numpy/typing/tests/data/pass/comparisons.py b/numpy/typing/tests/data/pass/comparisons.py
new file mode 100644
index 000000000..b298117a6
--- /dev/null
+++ b/numpy/typing/tests/data/pass/comparisons.py
@@ -0,0 +1,247 @@
+import numpy as np
+
+c16 = np.complex128()
+f8 = np.float64()
+i8 = np.int64()
+u8 = np.uint64()
+
+c8 = np.complex64()
+f4 = np.float32()
+i4 = np.int32()
+u4 = np.uint32()
+
+dt = np.datetime64(0, "D")
+td = np.timedelta64(0, "D")
+
+b_ = np.bool_()
+
+b = bool()
+c = complex()
+f = float()
+i = int()
+
+AR = np.array([0], dtype=np.int64)
+AR.setflags(write=False)
+
+SEQ = (0, 1, 2, 3, 4)
+
+# Time structures
+
+dt > dt
+
+td > td
+td > i
+td > i4
+td > i8
+td > AR
+td > SEQ
+
+# boolean
+
+b_ > b
+b_ > b_
+b_ > i
+b_ > i8
+b_ > i4
+b_ > u8
+b_ > u4
+b_ > f
+b_ > f8
+b_ > f4
+b_ > c
+b_ > c16
+b_ > c8
+b_ > AR
+b_ > SEQ
+
+# Complex
+
+c16 > c16
+c16 > f8
+c16 > i8
+c16 > c8
+c16 > f4
+c16 > i4
+c16 > b_
+c16 > b
+c16 > c
+c16 > f
+c16 > i
+c16 > AR
+c16 > SEQ
+
+c16 > c16
+f8 > c16
+i8 > c16
+c8 > c16
+f4 > c16
+i4 > c16
+b_ > c16
+b > c16
+c > c16
+f > c16
+i > c16
+AR > c16
+SEQ > c16
+
+c8 > c16
+c8 > f8
+c8 > i8
+c8 > c8
+c8 > f4
+c8 > i4
+c8 > b_
+c8 > b
+c8 > c
+c8 > f
+c8 > i
+c8 > AR
+c8 > SEQ
+
+c16 > c8
+f8 > c8
+i8 > c8
+c8 > c8
+f4 > c8
+i4 > c8
+b_ > c8
+b > c8
+c > c8
+f > c8
+i > c8
+AR > c8
+SEQ > c8
+
+# Float
+
+f8 > f8
+f8 > i8
+f8 > f4
+f8 > i4
+f8 > b_
+f8 > b
+f8 > c
+f8 > f
+f8 > i
+f8 > AR
+f8 > SEQ
+
+f8 > f8
+i8 > f8
+f4 > f8
+i4 > f8
+b_ > f8
+b > f8
+c > f8
+f > f8
+i > f8
+AR > f8
+SEQ > f8
+
+f4 > f8
+f4 > i8
+f4 > f4
+f4 > i4
+f4 > b_
+f4 > b
+f4 > c
+f4 > f
+f4 > i
+f4 > AR
+f4 > SEQ
+
+f8 > f4
+i8 > f4
+f4 > f4
+i4 > f4
+b_ > f4
+b > f4
+c > f4
+f > f4
+i > f4
+AR > f4
+SEQ > f4
+
+# Int
+
+i8 > i8
+i8 > u8
+i8 > i4
+i8 > u4
+i8 > b_
+i8 > b
+i8 > c
+i8 > f
+i8 > i
+i8 > AR
+i8 > SEQ
+
+u8 > u8
+u8 > i4
+u8 > u4
+u8 > b_
+u8 > b
+u8 > c
+u8 > f
+u8 > i
+u8 > AR
+u8 > SEQ
+
+i8 > i8
+u8 > i8
+i4 > i8
+u4 > i8
+b_ > i8
+b > i8
+c > i8
+f > i8
+i > i8
+AR > i8
+SEQ > i8
+
+u8 > u8
+i4 > u8
+u4 > u8
+b_ > u8
+b > u8
+c > u8
+f > u8
+i > u8
+AR > u8
+SEQ > u8
+
+i4 > i8
+i4 > i4
+i4 > i
+i4 > b_
+i4 > b
+i4 > AR
+i4 > SEQ
+
+u4 > i8
+u4 > i4
+u4 > u8
+u4 > u4
+u4 > i
+u4 > b_
+u4 > b
+u4 > AR
+u4 > SEQ
+
+i8 > i4
+i4 > i4
+i > i4
+b_ > i4
+b > i4
+AR > i4
+SEQ > i4
+
+i8 > u4
+i4 > u4
+u8 > u4
+u4 > u4
+b_ > u4
+b > u4
+i > u4
+AR > u4
+SEQ > u4
diff --git a/numpy/typing/tests/data/pass/dtype.py b/numpy/typing/tests/data/pass/dtype.py
new file mode 100644
index 000000000..a97edc302
--- /dev/null
+++ b/numpy/typing/tests/data/pass/dtype.py
@@ -0,0 +1,43 @@
+import numpy as np
+
+dtype_obj = np.dtype(np.str_)
+
+np.dtype(dtype=np.int64)
+np.dtype(int)
+np.dtype("int")
+np.dtype(None)
+
+np.dtype((int, 2))
+np.dtype((int, (1,)))
+
+np.dtype({"names": ["a", "b"], "formats": [int, float]})
+np.dtype({"names": ["a"], "formats": [int], "titles": [object]})
+np.dtype({"names": ["a"], "formats": [int], "titles": [object()]})
+
+np.dtype([("name", np.unicode_, 16), ("grades", np.float64, (2,)), ("age", "int32")])
+
+np.dtype(
+ {
+ "names": ["a", "b"],
+ "formats": [int, float],
+ "itemsize": 9,
+ "aligned": False,
+ "titles": ["x", "y"],
+ "offsets": [0, 1],
+ }
+)
+
+np.dtype((np.float_, float))
+
+
+class Test:
+ dtype = float
+
+
+np.dtype(Test())
+
+# Methods and attributes
+dtype_obj.base
+dtype_obj.subdtype
+dtype_obj.newbyteorder()
+dtype_obj.type
diff --git a/numpy/typing/tests/data/pass/flatiter.py b/numpy/typing/tests/data/pass/flatiter.py
new file mode 100644
index 000000000..4fdf25299
--- /dev/null
+++ b/numpy/typing/tests/data/pass/flatiter.py
@@ -0,0 +1,16 @@
+import numpy as np
+
+a = np.empty((2, 2)).flat
+
+a.base
+a.copy()
+a.coords
+a.index
+iter(a)
+next(a)
+a[0]
+a[[0, 1, 2]]
+a[...]
+a[:]
+a.__array__()
+a.__array__(np.float64)
diff --git a/numpy/typing/tests/data/pass/fromnumeric.py b/numpy/typing/tests/data/pass/fromnumeric.py
new file mode 100644
index 000000000..9e936e684
--- /dev/null
+++ b/numpy/typing/tests/data/pass/fromnumeric.py
@@ -0,0 +1,260 @@
+"""Tests for :mod:`numpy.core.fromnumeric`."""
+
+import numpy as np
+
+A = np.array(True, ndmin=2, dtype=bool)
+B = np.array(1.0, ndmin=2, dtype=np.float32)
+A.setflags(write=False)
+B.setflags(write=False)
+
+a = np.bool_(True)
+b = np.float32(1.0)
+c = 1.0
+d = np.array(1.0, dtype=np.float32) # writeable
+
+np.take(a, 0)
+np.take(b, 0)
+np.take(c, 0)
+np.take(A, 0)
+np.take(B, 0)
+np.take(A, [0])
+np.take(B, [0])
+
+np.reshape(a, 1)
+np.reshape(b, 1)
+np.reshape(c, 1)
+np.reshape(A, 1)
+np.reshape(B, 1)
+
+np.choose(a, [True, True])
+np.choose(A, [1.0, 1.0])
+
+np.repeat(a, 1)
+np.repeat(b, 1)
+np.repeat(c, 1)
+np.repeat(A, 1)
+np.repeat(B, 1)
+
+np.swapaxes(A, 0, 0)
+np.swapaxes(B, 0, 0)
+
+np.transpose(a)
+np.transpose(b)
+np.transpose(c)
+np.transpose(A)
+np.transpose(B)
+
+np.partition(a, 0, axis=None)
+np.partition(b, 0, axis=None)
+np.partition(c, 0, axis=None)
+np.partition(A, 0)
+np.partition(B, 0)
+
+np.argpartition(a, 0)
+np.argpartition(b, 0)
+np.argpartition(c, 0)
+np.argpartition(A, 0)
+np.argpartition(B, 0)
+
+np.sort(A, 0)
+np.sort(B, 0)
+
+np.argsort(A, 0)
+np.argsort(B, 0)
+
+np.argmax(A)
+np.argmax(B)
+np.argmax(A, axis=0)
+np.argmax(B, axis=0)
+
+np.argmin(A)
+np.argmin(B)
+np.argmin(A, axis=0)
+np.argmin(B, axis=0)
+
+np.searchsorted(A[0], 0)
+np.searchsorted(B[0], 0)
+np.searchsorted(A[0], [0])
+np.searchsorted(B[0], [0])
+
+np.resize(a, (5, 5))
+np.resize(b, (5, 5))
+np.resize(c, (5, 5))
+np.resize(A, (5, 5))
+np.resize(B, (5, 5))
+
+np.squeeze(a)
+np.squeeze(b)
+np.squeeze(c)
+np.squeeze(A)
+np.squeeze(B)
+
+np.diagonal(A)
+np.diagonal(B)
+
+np.trace(A)
+np.trace(B)
+
+np.ravel(a)
+np.ravel(b)
+np.ravel(c)
+np.ravel(A)
+np.ravel(B)
+
+np.nonzero(A)
+np.nonzero(B)
+
+np.shape(a)
+np.shape(b)
+np.shape(c)
+np.shape(A)
+np.shape(B)
+
+np.compress([True], a)
+np.compress([True], b)
+np.compress([True], c)
+np.compress([True], A)
+np.compress([True], B)
+
+np.clip(a, 0, 1.0)
+np.clip(b, -1, 1)
+np.clip(a, 0, None)
+np.clip(b, None, 1)
+np.clip(c, 0, 1)
+np.clip(A, 0, 1)
+np.clip(B, 0, 1)
+np.clip(B, [0, 1], [1, 2])
+
+np.sum(a)
+np.sum(b)
+np.sum(c)
+np.sum(A)
+np.sum(B)
+np.sum(A, axis=0)
+np.sum(B, axis=0)
+
+np.all(a)
+np.all(b)
+np.all(c)
+np.all(A)
+np.all(B)
+np.all(A, axis=0)
+np.all(B, axis=0)
+np.all(A, keepdims=True)
+np.all(B, keepdims=True)
+
+np.any(a)
+np.any(b)
+np.any(c)
+np.any(A)
+np.any(B)
+np.any(A, axis=0)
+np.any(B, axis=0)
+np.any(A, keepdims=True)
+np.any(B, keepdims=True)
+
+np.cumsum(a)
+np.cumsum(b)
+np.cumsum(c)
+np.cumsum(A)
+np.cumsum(B)
+
+np.ptp(b)
+np.ptp(c)
+np.ptp(B)
+np.ptp(B, axis=0)
+np.ptp(B, keepdims=True)
+
+np.amax(a)
+np.amax(b)
+np.amax(c)
+np.amax(A)
+np.amax(B)
+np.amax(A, axis=0)
+np.amax(B, axis=0)
+np.amax(A, keepdims=True)
+np.amax(B, keepdims=True)
+
+np.amin(a)
+np.amin(b)
+np.amin(c)
+np.amin(A)
+np.amin(B)
+np.amin(A, axis=0)
+np.amin(B, axis=0)
+np.amin(A, keepdims=True)
+np.amin(B, keepdims=True)
+
+np.prod(a)
+np.prod(b)
+np.prod(c)
+np.prod(A)
+np.prod(B)
+np.prod(a, dtype=None)
+np.prod(A, dtype=None)
+np.prod(A, axis=0)
+np.prod(B, axis=0)
+np.prod(A, keepdims=True)
+np.prod(B, keepdims=True)
+np.prod(b, out=d)
+np.prod(B, out=d)
+
+np.cumprod(a)
+np.cumprod(b)
+np.cumprod(c)
+np.cumprod(A)
+np.cumprod(B)
+
+np.ndim(a)
+np.ndim(b)
+np.ndim(c)
+np.ndim(A)
+np.ndim(B)
+
+np.size(a)
+np.size(b)
+np.size(c)
+np.size(A)
+np.size(B)
+
+np.around(a)
+np.around(b)
+np.around(c)
+np.around(A)
+np.around(B)
+
+np.mean(a)
+np.mean(b)
+np.mean(c)
+np.mean(A)
+np.mean(B)
+np.mean(A, axis=0)
+np.mean(B, axis=0)
+np.mean(A, keepdims=True)
+np.mean(B, keepdims=True)
+np.mean(b, out=d)
+np.mean(B, out=d)
+
+np.std(a)
+np.std(b)
+np.std(c)
+np.std(A)
+np.std(B)
+np.std(A, axis=0)
+np.std(B, axis=0)
+np.std(A, keepdims=True)
+np.std(B, keepdims=True)
+np.std(b, out=d)
+np.std(B, out=d)
+
+np.var(a)
+np.var(b)
+np.var(c)
+np.var(A)
+np.var(B)
+np.var(A, axis=0)
+np.var(B, axis=0)
+np.var(A, keepdims=True)
+np.var(B, keepdims=True)
+np.var(b, out=d)
+np.var(B, out=d)
diff --git a/numpy/typing/tests/data/pass/literal.py b/numpy/typing/tests/data/pass/literal.py
new file mode 100644
index 000000000..8eaeb6afb
--- /dev/null
+++ b/numpy/typing/tests/data/pass/literal.py
@@ -0,0 +1,45 @@
+from functools import partial
+from typing import Callable, List, Tuple
+
+import pytest # type: ignore
+import numpy as np
+
+AR = np.array(0)
+AR.setflags(write=False)
+
+KACF = frozenset({None, "K", "A", "C", "F"})
+ACF = frozenset({None, "A", "C", "F"})
+CF = frozenset({None, "C", "F"})
+
+order_list: List[Tuple[frozenset, Callable]] = [
+ (KACF, partial(np.ndarray, 1)),
+ (KACF, AR.tobytes),
+ (KACF, partial(AR.astype, int)),
+ (KACF, AR.copy),
+ (ACF, partial(AR.reshape, 1)),
+ (KACF, AR.flatten),
+ (KACF, AR.ravel),
+ (KACF, partial(np.array, 1)),
+ (CF, partial(np.zeros, 1)),
+ (CF, partial(np.ones, 1)),
+ (CF, partial(np.empty, 1)),
+ (CF, partial(np.full, 1, 1)),
+ (KACF, partial(np.zeros_like, AR)),
+ (KACF, partial(np.ones_like, AR)),
+ (KACF, partial(np.empty_like, AR)),
+ (KACF, partial(np.full_like, AR, 1)),
+ (KACF, partial(np.add, 1, 1)), # i.e. np.ufunc.__call__
+ (ACF, partial(np.reshape, AR, 1)),
+ (KACF, partial(np.ravel, AR)),
+ (KACF, partial(np.asarray, 1)),
+ (KACF, partial(np.asanyarray, 1)),
+]
+
+for order_set, func in order_list:
+ for order in order_set:
+ func(order=order)
+
+ invalid_orders = KACF - order_set
+ for order in invalid_orders:
+ with pytest.raises(ValueError):
+ func(order=order)
diff --git a/numpy/typing/tests/data/pass/mod.py b/numpy/typing/tests/data/pass/mod.py
new file mode 100644
index 000000000..b5b9afb2a
--- /dev/null
+++ b/numpy/typing/tests/data/pass/mod.py
@@ -0,0 +1,149 @@
+import numpy as np
+
+f8 = np.float64(1)
+i8 = np.int64(1)
+u8 = np.uint64(1)
+
+f4 = np.float32(1)
+i4 = np.int32(1)
+u4 = np.uint32(1)
+
+td = np.timedelta64(1, "D")
+b_ = np.bool_(1)
+
+b = bool(1)
+f = float(1)
+i = int(1)
+
+AR = np.array([1], dtype=np.bool_)
+AR.setflags(write=False)
+
+AR2 = np.array([1], dtype=np.timedelta64)
+AR2.setflags(write=False)
+
+# Time structures
+
+td % td
+td % AR2
+AR2 % td
+
+divmod(td, td)
+divmod(td, AR2)
+divmod(AR2, td)
+
+# Bool
+
+b_ % b
+b_ % i
+b_ % f
+b_ % b_
+b_ % i8
+b_ % u8
+b_ % f8
+b_ % AR
+
+divmod(b_, b)
+divmod(b_, i)
+divmod(b_, f)
+divmod(b_, b_)
+divmod(b_, i8)
+divmod(b_, u8)
+divmod(b_, f8)
+divmod(b_, AR)
+
+b % b_
+i % b_
+f % b_
+b_ % b_
+i8 % b_
+u8 % b_
+f8 % b_
+AR % b_
+
+divmod(b, b_)
+divmod(i, b_)
+divmod(f, b_)
+divmod(b_, b_)
+divmod(i8, b_)
+divmod(u8, b_)
+divmod(f8, b_)
+divmod(AR, b_)
+
+# int
+
+i8 % b
+i8 % i
+i8 % f
+i8 % i8
+i8 % f8
+i4 % i8
+i4 % f8
+i4 % i4
+i4 % f4
+i8 % AR
+
+divmod(i8, b)
+divmod(i8, i)
+divmod(i8, f)
+divmod(i8, i8)
+divmod(i8, f8)
+divmod(i8, i4)
+divmod(i8, f4)
+divmod(i4, i4)
+divmod(i4, f4)
+divmod(i8, AR)
+
+b % i8
+i % i8
+f % i8
+i8 % i8
+f8 % i8
+i8 % i4
+f8 % i4
+i4 % i4
+f4 % i4
+AR % i8
+
+divmod(b, i8)
+divmod(i, i8)
+divmod(f, i8)
+divmod(i8, i8)
+divmod(f8, i8)
+divmod(i4, i8)
+divmod(f4, i8)
+divmod(i4, i4)
+divmod(f4, i4)
+divmod(AR, i8)
+
+# float
+
+f8 % b
+f8 % i
+f8 % f
+i8 % f4
+f4 % f4
+f8 % AR
+
+divmod(f8, b)
+divmod(f8, i)
+divmod(f8, f)
+divmod(f8, f8)
+divmod(f8, f4)
+divmod(f4, f4)
+divmod(f8, AR)
+
+b % f8
+i % f8
+f % f8
+f8 % f8
+f8 % f8
+f4 % f4
+AR % f8
+
+divmod(b, f8)
+divmod(i, f8)
+divmod(f, f8)
+divmod(f8, f8)
+divmod(f4, f8)
+divmod(f4, f4)
+divmod(AR, f8)
diff --git a/numpy/typing/tests/data/pass/ndarray_conversion.py b/numpy/typing/tests/data/pass/ndarray_conversion.py
new file mode 100644
index 000000000..303cf53e4
--- /dev/null
+++ b/numpy/typing/tests/data/pass/ndarray_conversion.py
@@ -0,0 +1,94 @@
+import os
+import tempfile
+
+import numpy as np
+
+nd = np.array([[1, 2], [3, 4]])
+scalar_array = np.array(1)
+
+# item
+scalar_array.item()
+nd.item(1)
+nd.item(0, 1)
+nd.item((0, 1))
+
+# tolist is pretty simple
+
+# itemset
+scalar_array.itemset(3)
+nd.itemset(3, 0)
+nd.itemset((0, 0), 3)
+
+# tobytes
+nd.tobytes()
+nd.tobytes("C")
+nd.tobytes(None)
+
+# tofile
+if os.name != "nt":
+ with tempfile.NamedTemporaryFile(suffix=".txt") as tmp:
+ nd.tofile(tmp.name)
+ nd.tofile(tmp.name, "")
+ nd.tofile(tmp.name, sep="")
+
+ nd.tofile(tmp.name, "", "%s")
+ nd.tofile(tmp.name, format="%s")
+
+ nd.tofile(tmp)
+
+# dump is pretty simple
+# dumps is pretty simple
+
+# astype
+nd.astype("float")
+nd.astype(float)
+
+nd.astype(float, "K")
+nd.astype(float, order="K")
+
+nd.astype(float, "K", "unsafe")
+nd.astype(float, casting="unsafe")
+
+nd.astype(float, "K", "unsafe", True)
+nd.astype(float, subok=True)
+
+nd.astype(float, "K", "unsafe", True, True)
+nd.astype(float, copy=True)
+
+# byteswap
+nd.byteswap()
+nd.byteswap(True)
+
+# copy
+nd.copy()
+nd.copy("C")
+
+# view
+nd.view()
+nd.view(np.int64)
+nd.view(dtype=np.int64)
+nd.view(np.int64, np.matrix)
+nd.view(type=np.matrix)
+
+# getfield
+complex_array = np.array([[1 + 1j, 0], [0, 1 - 1j]], dtype=np.complex128)
+
+complex_array.getfield("float")
+complex_array.getfield(float)
+
+complex_array.getfield("float", 8)
+complex_array.getfield(float, offset=8)
+
+# setflags
+nd.setflags()
+
+nd.setflags(True)
+nd.setflags(write=True)
+
+nd.setflags(True, True)
+nd.setflags(write=True, align=True)
+
+nd.setflags(True, True, False)
+nd.setflags(write=True, align=True, uic=False)
+
+# fill is pretty simple
diff --git a/numpy/typing/tests/data/pass/ndarray_misc.py b/numpy/typing/tests/data/pass/ndarray_misc.py
new file mode 100644
index 000000000..6c6f5d50b
--- /dev/null
+++ b/numpy/typing/tests/data/pass/ndarray_misc.py
@@ -0,0 +1,159 @@
+"""
+Tests for miscellaneous (non-magic) ``np.ndarray``/``np.generic`` methods.
+
+More extensive tests are performed for the methods'
+function-based counterpart in `../from_numeric.py`.
+
+"""
+
+from typing import cast
+import numpy as np
+
+class SubClass(np.ndarray): ...
+
+i4 = np.int32(1)
+A = np.array([[1]], dtype=np.int32)
+B0 = np.empty((), dtype=np.int32).view(SubClass)
+B1 = np.empty((1,), dtype=np.int32).view(SubClass)
+B2 = np.empty((1, 1), dtype=np.int32).view(SubClass)
+C = np.array([0, 1, 2], dtype=np.int32)
+D = np.empty(3).view(SubClass)
+
+i4.all()
+A.all()
+A.all(axis=0)
+A.all(keepdims=True)
+A.all(out=B0)
+
+i4.any()
+A.any()
+A.any(axis=0)
+A.any(keepdims=True)
+A.any(out=B0)
+
+i4.argmax()
+A.argmax()
+A.argmax(axis=0)
+A.argmax(out=B0)
+
+i4.argmin()
+A.argmin()
+A.argmin(axis=0)
+A.argmin(out=B0)
+
+i4.argsort()
+A.argsort()
+
+i4.choose([()])
+_choices = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.int32)
+C.choose(_choices)
+C.choose(_choices, out=D)
+
+i4.clip(1)
+A.clip(1)
+A.clip(None, 1)
+A.clip(1, out=B2)
+A.clip(None, 1, out=B2)
+
+i4.compress([1])
+A.compress([1])
+A.compress([1], out=B1)
+
+i4.conj()
+A.conj()
+B0.conj()
+
+i4.conjugate()
+A.conjugate()
+B0.conjugate()
+
+i4.cumprod()
+A.cumprod()
+A.cumprod(out=B1)
+
+i4.cumsum()
+A.cumsum()
+A.cumsum(out=B1)
+
+i4.max()
+A.max()
+A.max(axis=0)
+A.max(keepdims=True)
+A.max(out=B0)
+
+i4.mean()
+A.mean()
+A.mean(axis=0)
+A.mean(keepdims=True)
+A.mean(out=B0)
+
+i4.min()
+A.min()
+A.min(axis=0)
+A.min(keepdims=True)
+A.min(out=B0)
+
+i4.newbyteorder()
+A.newbyteorder()
+B0.newbyteorder('|')
+
+i4.prod()
+A.prod()
+A.prod(axis=0)
+A.prod(keepdims=True)
+A.prod(out=B0)
+
+i4.ptp()
+A.ptp()
+A.ptp(axis=0)
+A.ptp(keepdims=True)
+A.astype(int).ptp(out=B0)
+
+i4.round()
+A.round()
+A.round(out=B2)
+
+i4.repeat(1)
+A.repeat(1)
+B0.repeat(1)
+
+i4.std()
+A.std()
+A.std(axis=0)
+A.std(keepdims=True)
+A.std(out=B0.astype(np.float64))
+
+i4.sum()
+A.sum()
+A.sum(axis=0)
+A.sum(keepdims=True)
+A.sum(out=B0)
+
+i4.take(0)
+A.take(0)
+A.take([0])
+A.take(0, out=B0)
+A.take([0], out=B1)
+
+i4.var()
+A.var()
+A.var(axis=0)
+A.var(keepdims=True)
+A.var(out=B0)
+
+A.argpartition([0])
+
+A.diagonal()
+
+A.dot(1)
+A.dot(1, out=B0)
+
+A.nonzero()
+
+C.searchsorted(1)
+
+A.trace()
+A.trace(out=B0)
+
+void = cast(np.void, np.array(1, dtype=[("f", np.float64)]).take(0))
+void.setfield(10, np.float64)
diff --git a/numpy/typing/tests/data/pass/ndarray_shape_manipulation.py b/numpy/typing/tests/data/pass/ndarray_shape_manipulation.py
new file mode 100644
index 000000000..0ca3dff39
--- /dev/null
+++ b/numpy/typing/tests/data/pass/ndarray_shape_manipulation.py
@@ -0,0 +1,47 @@
+import numpy as np
+
+nd1 = np.array([[1, 2], [3, 4]])
+
+# reshape
+nd1.reshape(4)
+nd1.reshape(2, 2)
+nd1.reshape((2, 2))
+
+nd1.reshape((2, 2), order="C")
+nd1.reshape(4, order="C")
+
+# resize
+nd1.resize()
+nd1.resize(4)
+nd1.resize(2, 2)
+nd1.resize((2, 2))
+
+nd1.resize((2, 2), refcheck=True)
+nd1.resize(4, refcheck=True)
+
+nd2 = np.array([[1, 2], [3, 4]])
+
+# transpose
+nd2.transpose()
+nd2.transpose(1, 0)
+nd2.transpose((1, 0))
+
+# swapaxes
+nd2.swapaxes(0, 1)
+
+# flatten
+nd2.flatten()
+nd2.flatten("C")
+
+# ravel
+nd2.ravel()
+nd2.ravel("C")
+
+# squeeze
+nd2.squeeze()
+
+nd3 = np.array([[1, 2]])
+nd3.squeeze(0)
+
+nd4 = np.array([[[1, 2]]])
+nd4.squeeze((0, 1))
diff --git a/numpy/typing/tests/data/pass/numeric.py b/numpy/typing/tests/data/pass/numeric.py
new file mode 100644
index 000000000..34fef7270
--- /dev/null
+++ b/numpy/typing/tests/data/pass/numeric.py
@@ -0,0 +1,89 @@
+"""
+Tests for :mod:`numpy.core.numeric`.
+
+Does not include tests which fall under ``array_constructors``.
+
+"""
+
+from typing import List
+import numpy as np
+
+class SubClass(np.ndarray):
+ ...
+
+i8 = np.int64(1)
+
+A = np.arange(27).reshape(3, 3, 3)
+B: List[List[List[int]]] = A.tolist()
+C = np.empty((27, 27)).view(SubClass)
+
+np.count_nonzero(i8)
+np.count_nonzero(A)
+np.count_nonzero(B)
+np.count_nonzero(A, keepdims=True)
+np.count_nonzero(A, axis=0)
+
+np.isfortran(i8)
+np.isfortran(A)
+
+np.argwhere(i8)
+np.argwhere(A)
+
+np.flatnonzero(i8)
+np.flatnonzero(A)
+
+np.correlate(B[0][0], A.ravel(), mode="valid")
+np.correlate(A.ravel(), A.ravel(), mode="same")
+
+np.convolve(B[0][0], A.ravel(), mode="valid")
+np.convolve(A.ravel(), A.ravel(), mode="same")
+
+np.outer(i8, A)
+np.outer(B, A)
+np.outer(A, A)
+np.outer(A, A, out=C)
+
+np.tensordot(B, A)
+np.tensordot(A, A)
+np.tensordot(A, A, axes=0)
+np.tensordot(A, A, axes=(0, 1))
+
+np.isscalar(i8)
+np.isscalar(A)
+np.isscalar(B)
+
+np.roll(A, 1)
+np.roll(A, (1, 2))
+np.roll(B, 1)
+
+np.rollaxis(A, 0, 1)
+
+np.moveaxis(A, 0, 1)
+np.moveaxis(A, (0, 1), (1, 2))
+
+np.cross(B, A)
+np.cross(A, A)
+
+np.indices([0, 1, 2])
+np.indices([0, 1, 2], sparse=False)
+np.indices([0, 1, 2], sparse=True)
+
+np.binary_repr(1)
+
+np.base_repr(1)
+
+np.allclose(i8, A)
+np.allclose(B, A)
+np.allclose(A, A)
+
+np.isclose(i8, A)
+np.isclose(B, A)
+np.isclose(A, A)
+
+np.array_equal(i8, A)
+np.array_equal(B, A)
+np.array_equal(A, A)
+
+np.array_equiv(i8, A)
+np.array_equiv(B, A)
+np.array_equiv(A, A)
diff --git a/numpy/typing/tests/data/pass/numerictypes.py b/numpy/typing/tests/data/pass/numerictypes.py
new file mode 100644
index 000000000..4f205cabc
--- /dev/null
+++ b/numpy/typing/tests/data/pass/numerictypes.py
@@ -0,0 +1,29 @@
+import numpy as np
+
+np.maximum_sctype("S8")
+np.maximum_sctype(object)
+
+np.issctype(object)
+np.issctype("S8")
+
+np.obj2sctype(list)
+np.obj2sctype(list, default=None)
+np.obj2sctype(list, default=np.string_)
+
+np.issubclass_(np.int32, int)
+np.issubclass_(np.float64, float)
+np.issubclass_(np.float64, (int, float))
+
+np.issubsctype("int64", int)
+np.issubsctype(np.array([1]), np.array([1]))
+
+np.issubdtype("S1", np.string_)
+np.issubdtype(np.float64, np.float32)
+
+np.sctype2char("S1")
+np.sctype2char(list)
+
+np.find_common_type([], [np.int64, np.float32, complex])
+np.find_common_type((), (np.int64, np.float32, complex))
+np.find_common_type([np.int64, np.float32], [])
+np.find_common_type([np.float32], [np.int64, np.float64])
diff --git a/numpy/typing/tests/data/pass/scalars.py b/numpy/typing/tests/data/pass/scalars.py
new file mode 100644
index 000000000..b7f7880e4
--- /dev/null
+++ b/numpy/typing/tests/data/pass/scalars.py
@@ -0,0 +1,165 @@
+import sys
+import datetime as dt
+
+import pytest
+import numpy as np
+
+
+# Construction
+class D:
+ def __index__(self) -> int:
+ return 0
+
+
+class C:
+ def __complex__(self) -> complex:
+ return 3j
+
+
+class B:
+ def __int__(self) -> int:
+ return 4
+
+
+class A:
+ def __float__(self) -> float:
+ return 4.0
+
+
+np.complex64(3j)
+np.complex64(A())
+np.complex64(C())
+np.complex128(3j)
+np.complex128(C())
+np.complex128(None)
+np.complex64("1.2")
+np.complex128(b"2j")
+
+np.int8(4)
+np.int16(3.4)
+np.int32(4)
+np.int64(-1)
+np.uint8(B())
+np.uint32()
+np.int32("1")
+np.int64(b"2")
+
+np.float16(A())
+np.float32(16)
+np.float64(3.0)
+np.float64(None)
+np.float32("1")
+np.float16(b"2.5")
+
+if sys.version_info >= (3, 8):
+ np.uint64(D())
+ np.float32(D())
+ np.complex64(D())
+
+np.bytes_(b"hello")
+np.bytes_("hello", 'utf-8')
+np.bytes_("hello", encoding='utf-8')
+np.str_("hello")
+np.str_(b"hello", 'utf-8')
+np.str_(b"hello", encoding='utf-8')
+
+# Array-ish semantics
+np.int8().real
+np.int16().imag
+np.int32().data
+np.int64().flags
+
+np.uint8().itemsize * 2
+np.uint16().ndim + 1
+np.uint32().strides
+np.uint64().shape
+
+# Time structures
+np.datetime64()
+np.datetime64(0, "D")
+np.datetime64(0, b"D")
+np.datetime64(0, ('ms', 3))
+np.datetime64("2019")
+np.datetime64(b"2019")
+np.datetime64("2019", "D")
+np.datetime64(np.datetime64())
+np.datetime64(dt.datetime(2000, 5, 3))
+np.datetime64(None)
+np.datetime64(None, "D")
+
+np.timedelta64()
+np.timedelta64(0)
+np.timedelta64(0, "D")
+np.timedelta64(0, ('ms', 3))
+np.timedelta64(0, b"D")
+np.timedelta64("3")
+np.timedelta64(b"5")
+np.timedelta64(np.timedelta64(2))
+np.timedelta64(dt.timedelta(2))
+np.timedelta64(None)
+np.timedelta64(None, "D")
+
+np.void(1)
+np.void(np.int64(1))
+np.void(True)
+np.void(np.bool_(True))
+np.void(b"test")
+np.void(np.bytes_("test"))
+
+# Protocols
+i8 = np.int64()
+u8 = np.uint64()
+f8 = np.float64()
+c16 = np.complex128()
+b_ = np.bool_()
+td = np.timedelta64()
+U = np.str_("1")
+S = np.bytes_("1")
+AR = np.array(1, dtype=np.float64)
+
+int(i8)
+int(u8)
+int(f8)
+int(b_)
+int(td)
+int(U)
+int(S)
+int(AR)
+with pytest.warns(np.ComplexWarning):
+ int(c16)
+
+float(i8)
+float(u8)
+float(f8)
+float(b_)
+float(td)
+float(U)
+float(S)
+float(AR)
+with pytest.warns(np.ComplexWarning):
+ float(c16)
+
+complex(i8)
+complex(u8)
+complex(f8)
+complex(c16)
+complex(b_)
+complex(td)
+complex(U)
+complex(AR)
+
+
+# Misc
+c16.dtype
+c16.real
+c16.imag
+c16.real.real
+c16.real.imag
+c16.ndim
+c16.size
+c16.itemsize
+c16.shape
+c16.strides
+c16.squeeze()
+c16.byteswap()
+c16.transpose()
diff --git a/numpy/typing/tests/data/pass/simple.py b/numpy/typing/tests/data/pass/simple.py
new file mode 100644
index 000000000..243caf229
--- /dev/null
+++ b/numpy/typing/tests/data/pass/simple.py
@@ -0,0 +1,165 @@
+"""Simple expression that should pass with mypy."""
+import operator
+
+import numpy as np
+from typing import Iterable # noqa: F401
+
+# Basic checks
+array = np.array([1, 2])
+
+
+def ndarray_func(x):
+ # type: (np.ndarray) -> np.ndarray
+ return x
+
+
+ndarray_func(np.array([1, 2]))
+array == 1
+array.dtype == float
+
+# Dtype construction
+np.dtype(float)
+np.dtype(np.float64)
+np.dtype(None)
+np.dtype("float64")
+np.dtype(np.dtype(float))
+np.dtype(("U", 10))
+np.dtype((np.int32, (2, 2)))
+# Define the arguments on the previous line to prevent bidirectional
+# type inference in mypy from broadening the types.
+two_tuples_dtype = [("R", "u1"), ("G", "u1"), ("B", "u1")]
+np.dtype(two_tuples_dtype)
+
+three_tuples_dtype = [("R", "u1", 2)]
+np.dtype(three_tuples_dtype)
+
+mixed_tuples_dtype = [("R", "u1"), ("G", np.unicode_, 1)]
+np.dtype(mixed_tuples_dtype)
+
+shape_tuple_dtype = [("R", "u1", (2, 2))]
+np.dtype(shape_tuple_dtype)
+
+shape_like_dtype = [("R", "u1", (2, 2)), ("G", np.unicode_, 1)]
+np.dtype(shape_like_dtype)
+
+object_dtype = [("field1", object)]
+np.dtype(object_dtype)
+
+np.dtype((np.int32, (np.int8, 4)))
+
+# Dtype comparision
+np.dtype(float) == float
+np.dtype(float) != np.float64
+np.dtype(float) < None
+np.dtype(float) <= "float64"
+np.dtype(float) > np.dtype(float)
+np.dtype(float) >= np.dtype(("U", 10))
+
+# Iteration and indexing
+def iterable_func(x):
+ # type: (Iterable) -> Iterable
+ return x
+
+
+iterable_func(array)
+[element for element in array]
+iter(array)
+zip(array, array)
+array[1]
+array[:]
+array[...]
+array[:] = 0
+
+array_2d = np.ones((3, 3))
+array_2d[:2, :2]
+array_2d[..., 0]
+array_2d[:2, :2] = 0
+
+# Other special methods
+len(array)
+str(array)
+array_scalar = np.array(1)
+int(array_scalar)
+float(array_scalar)
+# currently does not work due to https://github.com/python/typeshed/issues/1904
+# complex(array_scalar)
+bytes(array_scalar)
+operator.index(array_scalar)
+bool(array_scalar)
+
+# comparisons
+array < 1
+array <= 1
+array == 1
+array != 1
+array > 1
+array >= 1
+1 < array
+1 <= array
+1 == array
+1 != array
+1 > array
+1 >= array
+
+# binary arithmetic
+array + 1
+1 + array
+array += 1
+
+array - 1
+1 - array
+array -= 1
+
+array * 1
+1 * array
+array *= 1
+
+nonzero_array = np.array([1, 2])
+array / 1
+1 / nonzero_array
+float_array = np.array([1.0, 2.0])
+float_array /= 1
+
+array // 1
+1 // nonzero_array
+array //= 1
+
+array % 1
+1 % nonzero_array
+array %= 1
+
+divmod(array, 1)
+divmod(1, nonzero_array)
+
+array ** 1
+1 ** array
+array **= 1
+
+array << 1
+1 << array
+array <<= 1
+
+array >> 1
+1 >> array
+array >>= 1
+
+array & 1
+1 & array
+array &= 1
+
+array ^ 1
+1 ^ array
+array ^= 1
+
+array | 1
+1 | array
+array |= 1
+
+# unary arithmetic
+-array
++array
+abs(array)
+~array
+
+# Other methods
+np.array([1, 2]).transpose()
diff --git a/numpy/typing/tests/data/pass/simple_py3.py b/numpy/typing/tests/data/pass/simple_py3.py
new file mode 100644
index 000000000..c05a1ce61
--- /dev/null
+++ b/numpy/typing/tests/data/pass/simple_py3.py
@@ -0,0 +1,6 @@
+import numpy as np
+
+array = np.array([1, 2])
+
+# The @ operator is not in python 2
+array @ array
diff --git a/numpy/typing/tests/data/pass/ufunc_config.py b/numpy/typing/tests/data/pass/ufunc_config.py
new file mode 100644
index 000000000..2d1314245
--- /dev/null
+++ b/numpy/typing/tests/data/pass/ufunc_config.py
@@ -0,0 +1,50 @@
+"""Typing tests for `numpy.core._ufunc_config`."""
+
+import numpy as np
+
+def func1(a: str, b: int) -> None: ...
+def func2(a: str, b: int, c: float = ...) -> None: ...
+def func3(a: str, b: int) -> int: ...
+
+class Write1:
+ def write(self, a: str) -> None: ...
+
+class Write2:
+ def write(self, a: str, b: int = ...) -> None: ...
+
+class Write3:
+ def write(self, a: str) -> int: ...
+
+
+_err_default = np.geterr()
+_bufsize_default = np.getbufsize()
+_errcall_default = np.geterrcall()
+
+try:
+ np.seterr(all=None)
+ np.seterr(divide="ignore")
+ np.seterr(over="warn")
+ np.seterr(under="call")
+ np.seterr(invalid="raise")
+ np.geterr()
+
+ np.setbufsize(4096)
+ np.getbufsize()
+
+ np.seterrcall(func1)
+ np.seterrcall(func2)
+ np.seterrcall(func3)
+ np.seterrcall(Write1())
+ np.seterrcall(Write2())
+ np.seterrcall(Write3())
+ np.geterrcall()
+
+ with np.errstate(call=func1, all="call"):
+ pass
+ with np.errstate(call=Write1(), divide="log", over="log"):
+ pass
+
+finally:
+ np.seterr(**_err_default)
+ np.setbufsize(_bufsize_default)
+ np.seterrcall(_errcall_default)
diff --git a/numpy/typing/tests/data/pass/ufuncs.py b/numpy/typing/tests/data/pass/ufuncs.py
new file mode 100644
index 000000000..ad4d483d4
--- /dev/null
+++ b/numpy/typing/tests/data/pass/ufuncs.py
@@ -0,0 +1,16 @@
+import numpy as np
+
+np.sin(1)
+np.sin([1, 2, 3])
+np.sin(1, out=np.empty(1))
+np.matmul(np.ones((2, 2, 2)), np.ones((2, 2, 2)), axes=[(0, 1), (0, 1), (0, 1)])
+np.sin(1, signature="D")
+np.sin(1, extobj=[16, 1, lambda: None])
+# NOTE: `np.generic` subclasses are not guaranteed to support addition;
+# re-enable this we can infer the exact return type of `np.sin(...)`.
+#
+# np.sin(1) + np.sin(1)
+np.sin.types[0]
+np.sin.__name__
+
+np.abs(np.array([1]))
diff --git a/numpy/typing/tests/data/pass/warnings_and_errors.py b/numpy/typing/tests/data/pass/warnings_and_errors.py
new file mode 100644
index 000000000..5b6ec2626
--- /dev/null
+++ b/numpy/typing/tests/data/pass/warnings_and_errors.py
@@ -0,0 +1,7 @@
+import numpy as np
+
+np.AxisError(1)
+np.AxisError(1, ndim=2)
+np.AxisError(1, ndim=None)
+np.AxisError(1, ndim=2, msg_prefix="error")
+np.AxisError(1, ndim=2, msg_prefix=None)
diff --git a/numpy/typing/tests/data/reveal/arithmetic.py b/numpy/typing/tests/data/reveal/arithmetic.py
new file mode 100644
index 000000000..20310e691
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/arithmetic.py
@@ -0,0 +1,291 @@
+import numpy as np
+
+c16 = np.complex128()
+f8 = np.float64()
+i8 = np.int64()
+u8 = np.uint64()
+
+c8 = np.complex64()
+f4 = np.float32()
+i4 = np.int32()
+u4 = np.uint32()
+
+dt = np.datetime64(0, "D")
+td = np.timedelta64(0, "D")
+
+b_ = np.bool_()
+
+b = bool()
+c = complex()
+f = float()
+i = int()
+
+AR = np.array([0], dtype=np.float64)
+AR.setflags(write=False)
+
+# unary ops
+
+reveal_type(-c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(-c8) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
+reveal_type(-f8) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(-f4) # E: numpy.floating[numpy.typing._32Bit]
+reveal_type(-i8) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(-i4) # E: numpy.signedinteger[numpy.typing._32Bit]
+reveal_type(-u8) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+reveal_type(-u4) # E: numpy.unsignedinteger[numpy.typing._32Bit]
+reveal_type(-td) # E: numpy.timedelta64
+reveal_type(-AR) # E: Any
+
+reveal_type(+c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(+c8) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
+reveal_type(+f8) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(+f4) # E: numpy.floating[numpy.typing._32Bit]
+reveal_type(+i8) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(+i4) # E: numpy.signedinteger[numpy.typing._32Bit]
+reveal_type(+u8) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+reveal_type(+u4) # E: numpy.unsignedinteger[numpy.typing._32Bit]
+reveal_type(+td) # E: numpy.timedelta64
+reveal_type(+AR) # E: Any
+
+reveal_type(abs(c16)) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(abs(c8)) # E: numpy.floating[numpy.typing._32Bit]
+reveal_type(abs(f8)) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(abs(f4)) # E: numpy.floating[numpy.typing._32Bit]
+reveal_type(abs(i8)) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(abs(i4)) # E: numpy.signedinteger[numpy.typing._32Bit]
+reveal_type(abs(u8)) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+reveal_type(abs(u4)) # E: numpy.unsignedinteger[numpy.typing._32Bit]
+reveal_type(abs(td)) # E: numpy.timedelta64
+reveal_type(abs(b_)) # E: numpy.bool_
+reveal_type(abs(AR)) # E: Any
+
+# Time structures
+
+reveal_type(dt + td) # E: numpy.datetime64
+reveal_type(dt + i) # E: numpy.datetime64
+reveal_type(dt + i4) # E: numpy.datetime64
+reveal_type(dt + i8) # E: numpy.datetime64
+reveal_type(dt - dt) # E: numpy.timedelta64
+reveal_type(dt - i) # E: numpy.datetime64
+reveal_type(dt - i4) # E: numpy.datetime64
+reveal_type(dt - i8) # E: numpy.datetime64
+
+reveal_type(td + td) # E: numpy.timedelta64
+reveal_type(td + i) # E: numpy.timedelta64
+reveal_type(td + i4) # E: numpy.timedelta64
+reveal_type(td + i8) # E: numpy.timedelta64
+reveal_type(td - td) # E: numpy.timedelta64
+reveal_type(td - i) # E: numpy.timedelta64
+reveal_type(td - i4) # E: numpy.timedelta64
+reveal_type(td - i8) # E: numpy.timedelta64
+reveal_type(td / f) # E: numpy.timedelta64
+reveal_type(td / f4) # E: numpy.timedelta64
+reveal_type(td / f8) # E: numpy.timedelta64
+reveal_type(td / td) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(td // td) # E: numpy.signedinteger[numpy.typing._64Bit]
+
+# boolean
+
+reveal_type(b_ / b) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(b_ / b_) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(b_ / i) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(b_ / i8) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(b_ / i4) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(b_ / u8) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(b_ / u4) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(b_ / f) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(b_ / f8) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(b_ / f4) # E: numpy.floating[numpy.typing._32Bit]
+reveal_type(b_ / c) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(b_ / c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(b_ / c8) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
+
+reveal_type(b / b_) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(b_ / b_) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(i / b_) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(i8 / b_) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(i4 / b_) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(u8 / b_) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(u4 / b_) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(f / b_) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(f8 / b_) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(f4 / b_) # E: numpy.floating[numpy.typing._32Bit]
+reveal_type(c / b_) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(c16 / b_) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(c8 / b_) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
+
+# Complex
+
+reveal_type(c16 + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(c16 + f8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(c16 + i8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(c16 + c8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(c16 + f4) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(c16 + i4) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(c16 + b_) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(c16 + b) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(c16 + c) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(c16 + f) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(c16 + i) # E: numpy.complexfloating[Any, Any]
+reveal_type(c16 + AR) # E: Any
+
+reveal_type(c16 + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(f8 + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(i8 + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(c8 + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(f4 + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(i4 + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(b_ + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(b + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(c + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(f + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(i + c16) # E: numpy.complexfloating[Any, Any]
+reveal_type(AR + c16) # E: Any
+
+reveal_type(c8 + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(c8 + f8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(c8 + i8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(c8 + c8) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
+reveal_type(c8 + f4) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
+reveal_type(c8 + i4) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
+reveal_type(c8 + b_) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
+reveal_type(c8 + b) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
+reveal_type(c8 + c) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(c8 + f) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(c8 + i) # E: numpy.complexfloating[Any, Any]
+reveal_type(c8 + AR) # E: Any
+
+reveal_type(c16 + c8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(f8 + c8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(i8 + c8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(c8 + c8) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
+reveal_type(f4 + c8) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
+reveal_type(i4 + c8) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
+reveal_type(b_ + c8) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
+reveal_type(b + c8) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
+reveal_type(c + c8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(f + c8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(i + c8) # E: numpy.complexfloating[Any, Any]
+reveal_type(AR + c8) # E: Any
+
+# Float
+
+reveal_type(f8 + f8) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(f8 + i8) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(f8 + f4) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(f8 + i4) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(f8 + b_) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(f8 + b) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(f8 + c) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(f8 + f) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(f8 + i) # E: numpy.floating[Any]
+reveal_type(f8 + AR) # E: Any
+
+reveal_type(f8 + f8) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(i8 + f8) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(f4 + f8) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(i4 + f8) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(b_ + f8) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(b + f8) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(c + f8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(f + f8) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(i + f8) # E: numpy.floating[Any]
+reveal_type(AR + f8) # E: Any
+
+reveal_type(f4 + f8) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(f4 + i8) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(f4 + f4) # E: numpy.floating[numpy.typing._32Bit]
+reveal_type(f4 + i4) # E: numpy.floating[numpy.typing._32Bit]
+reveal_type(f4 + b_) # E: numpy.floating[numpy.typing._32Bit]
+reveal_type(f4 + b) # E: numpy.floating[numpy.typing._32Bit]
+reveal_type(f4 + c) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(f4 + f) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(f4 + i) # E: numpy.floating[Any]
+reveal_type(f4 + AR) # E: Any
+
+reveal_type(f8 + f4) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(i8 + f4) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(f4 + f4) # E: umpy.floating[numpy.typing._32Bit]
+reveal_type(i4 + f4) # E: umpy.floating[numpy.typing._32Bit]
+reveal_type(b_ + f4) # E: umpy.floating[numpy.typing._32Bit]
+reveal_type(b + f4) # E: umpy.floating[numpy.typing._32Bit]
+reveal_type(c + f4) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(f + f4) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(i + f4) # E: numpy.floating[Any]
+reveal_type(AR + f4) # E: Any
+
+# Int
+
+reveal_type(i8 + i8) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(i8 + u8) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]]
+reveal_type(i8 + i4) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(i8 + u4) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]]
+reveal_type(i8 + b_) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(i8 + b) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(i8 + c) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(i8 + f) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(i8 + i) # E: numpy.signedinteger[Any]
+reveal_type(i8 + AR) # E: Any
+
+reveal_type(u8 + u8) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+reveal_type(u8 + i4) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]]
+reveal_type(u8 + u4) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+reveal_type(u8 + b_) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+reveal_type(u8 + b) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+reveal_type(u8 + c) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(u8 + f) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(u8 + i) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]]
+reveal_type(u8 + AR) # E: Any
+
+reveal_type(i8 + i8) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(u8 + i8) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]]
+reveal_type(i4 + i8) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(u4 + i8) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]]
+reveal_type(b_ + i8) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(b + i8) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(c + i8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(f + i8) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(i + i8) # E: numpy.signedinteger[Any]
+reveal_type(AR + i8) # E: Any
+
+reveal_type(u8 + u8) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+reveal_type(i4 + u8) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]]
+reveal_type(u4 + u8) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+reveal_type(b_ + u8) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+reveal_type(b + u8) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+reveal_type(c + u8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
+reveal_type(f + u8) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(i + u8) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]]
+reveal_type(AR + u8) # E: Any
+
+reveal_type(i4 + i8) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(i4 + i4) # E: numpy.signedinteger[numpy.typing._32Bit]
+reveal_type(i4 + i) # E: numpy.signedinteger[Any]
+reveal_type(i4 + b_) # E: numpy.signedinteger[numpy.typing._32Bit]
+reveal_type(i4 + b) # E: numpy.signedinteger[numpy.typing._32Bit]
+reveal_type(i4 + AR) # E: Any
+
+reveal_type(u4 + i8) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]]
+reveal_type(u4 + i4) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]]
+reveal_type(u4 + u8) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+reveal_type(u4 + u4) # E: numpy.unsignedinteger[numpy.typing._32Bit]
+reveal_type(u4 + i) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]]
+reveal_type(u4 + b_) # E: numpy.unsignedinteger[numpy.typing._32Bit]
+reveal_type(u4 + b) # E: numpy.unsignedinteger[numpy.typing._32Bit]
+reveal_type(u4 + AR) # E: Any
+
+reveal_type(i8 + i4) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(i4 + i4) # E: numpy.signedinteger[numpy.typing._32Bit]
+reveal_type(i + i4) # E: numpy.signedinteger[Any]
+reveal_type(b_ + i4) # E: numpy.signedinteger[numpy.typing._32Bit]
+reveal_type(b + i4) # E: numpy.signedinteger[numpy.typing._32Bit]
+reveal_type(AR + i4) # E: Any
+
+reveal_type(i8 + u4) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]]
+reveal_type(i4 + u4) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]]
+reveal_type(u8 + u4) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+reveal_type(u4 + u4) # E: numpy.unsignedinteger[numpy.typing._32Bit]
+reveal_type(b_ + u4) # E: numpy.unsignedinteger[numpy.typing._32Bit]
+reveal_type(b + u4) # E: numpy.unsignedinteger[numpy.typing._32Bit]
+reveal_type(i + u4) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]]
+reveal_type(AR + u4) # E: Any
diff --git a/numpy/typing/tests/data/reveal/array_constructors.py b/numpy/typing/tests/data/reveal/array_constructors.py
new file mode 100644
index 000000000..04d5cd229
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/array_constructors.py
@@ -0,0 +1,102 @@
+from typing import List, Any
+import numpy as np
+
+class SubClass(np.ndarray): ...
+
+i8: np.int64
+
+A: np.ndarray
+B: SubClass
+C: List[int]
+
+def func(i: int, j: int, **kwargs: Any) -> SubClass: ...
+
+reveal_type(np.asarray(A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.asarray(B)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.asarray(C)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.asanyarray(A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.asanyarray(B)) # E: SubClass
+reveal_type(np.asanyarray(B, dtype=int)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.asanyarray(C)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.ascontiguousarray(A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.ascontiguousarray(B)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.ascontiguousarray(C)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.asfortranarray(A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.asfortranarray(B)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.asfortranarray(C)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.require(A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.require(B)) # E: SubClass
+reveal_type(np.require(B, requirements=None)) # E: SubClass
+reveal_type(np.require(B, dtype=int)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.require(B, requirements="E")) # E: numpy.ndarray[Any, Any]
+reveal_type(np.require(B, requirements=["ENSUREARRAY"])) # E: numpy.ndarray[Any, Any]
+reveal_type(np.require(B, requirements={"F", "E"})) # E: numpy.ndarray[Any, Any]
+reveal_type(np.require(B, requirements=["C", "OWNDATA"])) # E: SubClass
+reveal_type(np.require(B, requirements="W")) # E: SubClass
+reveal_type(np.require(B, requirements="A")) # E: SubClass
+reveal_type(np.require(C)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.linspace(0, 10)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.linspace(0, 10, retstep=True)) # E: Tuple[numpy.ndarray[Any, Any], numpy.inexact[Any]]
+reveal_type(np.logspace(0, 10)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.geomspace(1, 10)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.zeros_like(A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.zeros_like(C)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.zeros_like(B)) # E: SubClass
+reveal_type(np.zeros_like(B, dtype=np.int64)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.ones_like(A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.ones_like(C)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.ones_like(B)) # E: SubClass
+reveal_type(np.ones_like(B, dtype=np.int64)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.empty_like(A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.empty_like(C)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.empty_like(B)) # E: SubClass
+reveal_type(np.empty_like(B, dtype=np.int64)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.full_like(A, i8)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.full_like(C, i8)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.full_like(B, i8)) # E: SubClass
+reveal_type(np.full_like(B, i8, dtype=np.int64)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.ones(1)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.ones([1, 1, 1])) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.full(1, i8)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.full([1, 1, 1], i8)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.indices([1, 2, 3])) # E: numpy.ndarray[Any, Any]
+reveal_type(np.indices([1, 2, 3], sparse=True)) # E: tuple[numpy.ndarray[Any, Any]]
+
+reveal_type(np.fromfunction(func, (3, 5))) # E: SubClass
+
+reveal_type(np.identity(10)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.atleast_1d(A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.atleast_1d(C)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.atleast_1d(A, A)) # E: list[numpy.ndarray[Any, Any]]
+reveal_type(np.atleast_1d(A, C)) # E: list[numpy.ndarray[Any, Any]]
+reveal_type(np.atleast_1d(C, C)) # E: list[numpy.ndarray[Any, Any]]
+
+reveal_type(np.atleast_2d(A)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.atleast_3d(A)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.vstack([A, A])) # E: numpy.ndarray[Any, Any]
+reveal_type(np.vstack([A, C])) # E: numpy.ndarray[Any, Any]
+reveal_type(np.vstack([C, C])) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.hstack([A, A])) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.stack([A, A])) # E: numpy.ndarray[Any, Any]
+reveal_type(np.stack([A, A], axis=0)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.stack([A, A], out=B)) # E: SubClass
+
+reveal_type(np.block([[A, A], [A, A]])) # E: numpy.ndarray[Any, Any]
+reveal_type(np.block(C)) # E: numpy.ndarray[Any, Any]
diff --git a/numpy/typing/tests/data/reveal/bitwise_ops.py b/numpy/typing/tests/data/reveal/bitwise_ops.py
new file mode 100644
index 000000000..cb9131a96
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/bitwise_ops.py
@@ -0,0 +1,131 @@
+import numpy as np
+
+i8 = np.int64(1)
+u8 = np.uint64(1)
+
+i4 = np.int32(1)
+u4 = np.uint32(1)
+
+b_ = np.bool_(1)
+
+b = bool(1)
+i = int(1)
+
+AR = np.array([0, 1, 2], dtype=np.int32)
+AR.setflags(write=False)
+
+
+reveal_type(i8 << i8) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(i8 >> i8) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(i8 | i8) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(i8 ^ i8) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(i8 & i8) # E: numpy.signedinteger[numpy.typing._64Bit]
+
+reveal_type(i8 << AR) # E: Any
+reveal_type(i8 >> AR) # E: Any
+reveal_type(i8 | AR) # E: Any
+reveal_type(i8 ^ AR) # E: Any
+reveal_type(i8 & AR) # E: Any
+
+reveal_type(i4 << i4) # E: numpy.signedinteger[numpy.typing._32Bit]
+reveal_type(i4 >> i4) # E: numpy.signedinteger[numpy.typing._32Bit]
+reveal_type(i4 | i4) # E: numpy.signedinteger[numpy.typing._32Bit]
+reveal_type(i4 ^ i4) # E: numpy.signedinteger[numpy.typing._32Bit]
+reveal_type(i4 & i4) # E: numpy.signedinteger[numpy.typing._32Bit]
+
+reveal_type(i8 << i4) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(i8 >> i4) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(i8 | i4) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(i8 ^ i4) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(i8 & i4) # E: numpy.signedinteger[numpy.typing._64Bit]
+
+reveal_type(i8 << i) # E: numpy.signedinteger[Any]
+reveal_type(i8 >> i) # E: numpy.signedinteger[Any]
+reveal_type(i8 | i) # E: numpy.signedinteger[Any]
+reveal_type(i8 ^ i) # E: numpy.signedinteger[Any]
+reveal_type(i8 & i) # E: numpy.signedinteger[Any]
+
+reveal_type(i8 << b_) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(i8 >> b_) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(i8 | b_) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(i8 ^ b_) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(i8 & b_) # E: numpy.signedinteger[numpy.typing._64Bit]
+
+reveal_type(i8 << b) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(i8 >> b) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(i8 | b) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(i8 ^ b) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(i8 & b) # E: numpy.signedinteger[numpy.typing._64Bit]
+
+reveal_type(u8 << u8) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+reveal_type(u8 >> u8) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+reveal_type(u8 | u8) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+reveal_type(u8 ^ u8) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+reveal_type(u8 & u8) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+
+reveal_type(u8 << AR) # E: Any
+reveal_type(u8 >> AR) # E: Any
+reveal_type(u8 | AR) # E: Any
+reveal_type(u8 ^ AR) # E: Any
+reveal_type(u8 & AR) # E: Any
+
+reveal_type(u4 << u4) # E: numpy.unsignedinteger[numpy.typing._32Bit]
+reveal_type(u4 >> u4) # E: numpy.unsignedinteger[numpy.typing._32Bit]
+reveal_type(u4 | u4) # E: numpy.unsignedinteger[numpy.typing._32Bit]
+reveal_type(u4 ^ u4) # E: numpy.unsignedinteger[numpy.typing._32Bit]
+reveal_type(u4 & u4) # E: numpy.unsignedinteger[numpy.typing._32Bit]
+
+reveal_type(u4 << i4) # E: numpy.signedinteger[Any]
+reveal_type(u4 >> i4) # E: numpy.signedinteger[Any]
+reveal_type(u4 | i4) # E: numpy.signedinteger[Any]
+reveal_type(u4 ^ i4) # E: numpy.signedinteger[Any]
+reveal_type(u4 & i4) # E: numpy.signedinteger[Any]
+
+reveal_type(u4 << i) # E: numpy.signedinteger[Any]
+reveal_type(u4 >> i) # E: numpy.signedinteger[Any]
+reveal_type(u4 | i) # E: numpy.signedinteger[Any]
+reveal_type(u4 ^ i) # E: numpy.signedinteger[Any]
+reveal_type(u4 & i) # E: numpy.signedinteger[Any]
+
+reveal_type(u8 << b_) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+reveal_type(u8 >> b_) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+reveal_type(u8 | b_) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+reveal_type(u8 ^ b_) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+reveal_type(u8 & b_) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+
+reveal_type(u8 << b) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+reveal_type(u8 >> b) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+reveal_type(u8 | b) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+reveal_type(u8 ^ b) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+reveal_type(u8 & b) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+
+reveal_type(b_ << b_) # E: numpy.signedinteger[numpy.typing._8Bit]
+reveal_type(b_ >> b_) # E: numpy.signedinteger[numpy.typing._8Bit]
+reveal_type(b_ | b_) # E: numpy.bool_
+reveal_type(b_ ^ b_) # E: numpy.bool_
+reveal_type(b_ & b_) # E: numpy.bool_
+
+reveal_type(b_ << AR) # E: Any
+reveal_type(b_ >> AR) # E: Any
+reveal_type(b_ | AR) # E: Any
+reveal_type(b_ ^ AR) # E: Any
+reveal_type(b_ & AR) # E: Any
+
+reveal_type(b_ << b) # E: numpy.signedinteger[numpy.typing._8Bit]
+reveal_type(b_ >> b) # E: numpy.signedinteger[numpy.typing._8Bit]
+reveal_type(b_ | b) # E: numpy.bool_
+reveal_type(b_ ^ b) # E: numpy.bool_
+reveal_type(b_ & b) # E: numpy.bool_
+
+reveal_type(b_ << i) # E: numpy.signedinteger[Any]
+reveal_type(b_ >> i) # E: numpy.signedinteger[Any]
+reveal_type(b_ | i) # E: numpy.signedinteger[Any]
+reveal_type(b_ ^ i) # E: numpy.signedinteger[Any]
+reveal_type(b_ & i) # E: numpy.signedinteger[Any]
+
+reveal_type(~i8) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(~i4) # E: numpy.signedinteger[numpy.typing._32Bit]
+reveal_type(~u8) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+reveal_type(~u4) # E: numpy.unsignedinteger[numpy.typing._32Bit]
+reveal_type(~b_) # E: numpy.bool_
+reveal_type(~AR) # E: Any
diff --git a/numpy/typing/tests/data/reveal/comparisons.py b/numpy/typing/tests/data/reveal/comparisons.py
new file mode 100644
index 000000000..507f713c7
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/comparisons.py
@@ -0,0 +1,247 @@
+import numpy as np
+
+c16 = np.complex128()
+f8 = np.float64()
+i8 = np.int64()
+u8 = np.uint64()
+
+c8 = np.complex64()
+f4 = np.float32()
+i4 = np.int32()
+u4 = np.uint32()
+
+dt = np.datetime64(0, "D")
+td = np.timedelta64(0, "D")
+
+b_ = np.bool_()
+
+b = bool()
+c = complex()
+f = float()
+i = int()
+
+AR = np.array([0], dtype=np.int64)
+AR.setflags(write=False)
+
+SEQ = (0, 1, 2, 3, 4)
+
+# Time structures
+
+reveal_type(dt > dt) # E: numpy.bool_
+
+reveal_type(td > td) # E: numpy.bool_
+reveal_type(td > i) # E: numpy.bool_
+reveal_type(td > i4) # E: numpy.bool_
+reveal_type(td > i8) # E: numpy.bool_
+reveal_type(td > AR) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+reveal_type(td > SEQ) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+
+# boolean
+
+reveal_type(b_ > b) # E: numpy.bool_
+reveal_type(b_ > b_) # E: numpy.bool_
+reveal_type(b_ > i) # E: numpy.bool_
+reveal_type(b_ > i8) # E: numpy.bool_
+reveal_type(b_ > i4) # E: numpy.bool_
+reveal_type(b_ > u8) # E: numpy.bool_
+reveal_type(b_ > u4) # E: numpy.bool_
+reveal_type(b_ > f) # E: numpy.bool_
+reveal_type(b_ > f8) # E: numpy.bool_
+reveal_type(b_ > f4) # E: numpy.bool_
+reveal_type(b_ > c) # E: numpy.bool_
+reveal_type(b_ > c16) # E: numpy.bool_
+reveal_type(b_ > c8) # E: numpy.bool_
+reveal_type(b_ > AR) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+reveal_type(b_ > SEQ) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+
+# Complex
+
+reveal_type(c16 > c16) # E: numpy.bool_
+reveal_type(c16 > f8) # E: numpy.bool_
+reveal_type(c16 > i8) # E: numpy.bool_
+reveal_type(c16 > c8) # E: numpy.bool_
+reveal_type(c16 > f4) # E: numpy.bool_
+reveal_type(c16 > i4) # E: numpy.bool_
+reveal_type(c16 > b_) # E: numpy.bool_
+reveal_type(c16 > b) # E: numpy.bool_
+reveal_type(c16 > c) # E: numpy.bool_
+reveal_type(c16 > f) # E: numpy.bool_
+reveal_type(c16 > i) # E: numpy.bool_
+reveal_type(c16 > AR) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+reveal_type(c16 > SEQ) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+
+reveal_type(c16 > c16) # E: numpy.bool_
+reveal_type(f8 > c16) # E: numpy.bool_
+reveal_type(i8 > c16) # E: numpy.bool_
+reveal_type(c8 > c16) # E: numpy.bool_
+reveal_type(f4 > c16) # E: numpy.bool_
+reveal_type(i4 > c16) # E: numpy.bool_
+reveal_type(b_ > c16) # E: numpy.bool_
+reveal_type(b > c16) # E: numpy.bool_
+reveal_type(c > c16) # E: numpy.bool_
+reveal_type(f > c16) # E: numpy.bool_
+reveal_type(i > c16) # E: numpy.bool_
+reveal_type(AR > c16) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+reveal_type(SEQ > c16) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+
+reveal_type(c8 > c16) # E: numpy.bool_
+reveal_type(c8 > f8) # E: numpy.bool_
+reveal_type(c8 > i8) # E: numpy.bool_
+reveal_type(c8 > c8) # E: numpy.bool_
+reveal_type(c8 > f4) # E: numpy.bool_
+reveal_type(c8 > i4) # E: numpy.bool_
+reveal_type(c8 > b_) # E: numpy.bool_
+reveal_type(c8 > b) # E: numpy.bool_
+reveal_type(c8 > c) # E: numpy.bool_
+reveal_type(c8 > f) # E: numpy.bool_
+reveal_type(c8 > i) # E: numpy.bool_
+reveal_type(c8 > AR) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+reveal_type(c8 > SEQ) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+
+reveal_type(c16 > c8) # E: numpy.bool_
+reveal_type(f8 > c8) # E: numpy.bool_
+reveal_type(i8 > c8) # E: numpy.bool_
+reveal_type(c8 > c8) # E: numpy.bool_
+reveal_type(f4 > c8) # E: numpy.bool_
+reveal_type(i4 > c8) # E: numpy.bool_
+reveal_type(b_ > c8) # E: numpy.bool_
+reveal_type(b > c8) # E: numpy.bool_
+reveal_type(c > c8) # E: numpy.bool_
+reveal_type(f > c8) # E: numpy.bool_
+reveal_type(i > c8) # E: numpy.bool_
+reveal_type(AR > c8) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+reveal_type(SEQ > c8) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+
+# Float
+
+reveal_type(f8 > f8) # E: numpy.bool_
+reveal_type(f8 > i8) # E: numpy.bool_
+reveal_type(f8 > f4) # E: numpy.bool_
+reveal_type(f8 > i4) # E: numpy.bool_
+reveal_type(f8 > b_) # E: numpy.bool_
+reveal_type(f8 > b) # E: numpy.bool_
+reveal_type(f8 > c) # E: numpy.bool_
+reveal_type(f8 > f) # E: numpy.bool_
+reveal_type(f8 > i) # E: numpy.bool_
+reveal_type(f8 > AR) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+reveal_type(f8 > SEQ) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+
+reveal_type(f8 > f8) # E: numpy.bool_
+reveal_type(i8 > f8) # E: numpy.bool_
+reveal_type(f4 > f8) # E: numpy.bool_
+reveal_type(i4 > f8) # E: numpy.bool_
+reveal_type(b_ > f8) # E: numpy.bool_
+reveal_type(b > f8) # E: numpy.bool_
+reveal_type(c > f8) # E: numpy.bool_
+reveal_type(f > f8) # E: numpy.bool_
+reveal_type(i > f8) # E: numpy.bool_
+reveal_type(AR > f8) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+reveal_type(SEQ > f8) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+
+reveal_type(f4 > f8) # E: numpy.bool_
+reveal_type(f4 > i8) # E: numpy.bool_
+reveal_type(f4 > f4) # E: numpy.bool_
+reveal_type(f4 > i4) # E: numpy.bool_
+reveal_type(f4 > b_) # E: numpy.bool_
+reveal_type(f4 > b) # E: numpy.bool_
+reveal_type(f4 > c) # E: numpy.bool_
+reveal_type(f4 > f) # E: numpy.bool_
+reveal_type(f4 > i) # E: numpy.bool_
+reveal_type(f4 > AR) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+reveal_type(f4 > SEQ) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+
+reveal_type(f8 > f4) # E: numpy.bool_
+reveal_type(i8 > f4) # E: numpy.bool_
+reveal_type(f4 > f4) # E: numpy.bool_
+reveal_type(i4 > f4) # E: numpy.bool_
+reveal_type(b_ > f4) # E: numpy.bool_
+reveal_type(b > f4) # E: numpy.bool_
+reveal_type(c > f4) # E: numpy.bool_
+reveal_type(f > f4) # E: numpy.bool_
+reveal_type(i > f4) # E: numpy.bool_
+reveal_type(AR > f4) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+reveal_type(SEQ > f4) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+
+# Int
+
+reveal_type(i8 > i8) # E: numpy.bool_
+reveal_type(i8 > u8) # E: numpy.bool_
+reveal_type(i8 > i4) # E: numpy.bool_
+reveal_type(i8 > u4) # E: numpy.bool_
+reveal_type(i8 > b_) # E: numpy.bool_
+reveal_type(i8 > b) # E: numpy.bool_
+reveal_type(i8 > c) # E: numpy.bool_
+reveal_type(i8 > f) # E: numpy.bool_
+reveal_type(i8 > i) # E: numpy.bool_
+reveal_type(i8 > AR) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+reveal_type(i8 > SEQ) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+
+reveal_type(u8 > u8) # E: numpy.bool_
+reveal_type(u8 > i4) # E: numpy.bool_
+reveal_type(u8 > u4) # E: numpy.bool_
+reveal_type(u8 > b_) # E: numpy.bool_
+reveal_type(u8 > b) # E: numpy.bool_
+reveal_type(u8 > c) # E: numpy.bool_
+reveal_type(u8 > f) # E: numpy.bool_
+reveal_type(u8 > i) # E: numpy.bool_
+reveal_type(u8 > AR) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+reveal_type(u8 > SEQ) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+
+reveal_type(i8 > i8) # E: numpy.bool_
+reveal_type(u8 > i8) # E: numpy.bool_
+reveal_type(i4 > i8) # E: numpy.bool_
+reveal_type(u4 > i8) # E: numpy.bool_
+reveal_type(b_ > i8) # E: numpy.bool_
+reveal_type(b > i8) # E: numpy.bool_
+reveal_type(c > i8) # E: numpy.bool_
+reveal_type(f > i8) # E: numpy.bool_
+reveal_type(i > i8) # E: numpy.bool_
+reveal_type(AR > i8) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+reveal_type(SEQ > i8) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+
+reveal_type(u8 > u8) # E: numpy.bool_
+reveal_type(i4 > u8) # E: numpy.bool_
+reveal_type(u4 > u8) # E: numpy.bool_
+reveal_type(b_ > u8) # E: numpy.bool_
+reveal_type(b > u8) # E: numpy.bool_
+reveal_type(c > u8) # E: numpy.bool_
+reveal_type(f > u8) # E: numpy.bool_
+reveal_type(i > u8) # E: numpy.bool_
+reveal_type(AR > u8) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+reveal_type(SEQ > u8) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+
+reveal_type(i4 > i8) # E: numpy.bool_
+reveal_type(i4 > i4) # E: numpy.bool_
+reveal_type(i4 > i) # E: numpy.bool_
+reveal_type(i4 > b_) # E: numpy.bool_
+reveal_type(i4 > b) # E: numpy.bool_
+reveal_type(i4 > AR) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+reveal_type(i4 > SEQ) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+
+reveal_type(u4 > i8) # E: numpy.bool_
+reveal_type(u4 > i4) # E: numpy.bool_
+reveal_type(u4 > u8) # E: numpy.bool_
+reveal_type(u4 > u4) # E: numpy.bool_
+reveal_type(u4 > i) # E: numpy.bool_
+reveal_type(u4 > b_) # E: numpy.bool_
+reveal_type(u4 > b) # E: numpy.bool_
+reveal_type(u4 > AR) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+reveal_type(u4 > SEQ) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+
+reveal_type(i8 > i4) # E: numpy.bool_
+reveal_type(i4 > i4) # E: numpy.bool_
+reveal_type(i > i4) # E: numpy.bool_
+reveal_type(b_ > i4) # E: numpy.bool_
+reveal_type(b > i4) # E: numpy.bool_
+reveal_type(AR > i4) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+reveal_type(SEQ > i4) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+
+reveal_type(i8 > u4) # E: numpy.bool_
+reveal_type(i4 > u4) # E: numpy.bool_
+reveal_type(u8 > u4) # E: numpy.bool_
+reveal_type(u4 > u4) # E: numpy.bool_
+reveal_type(b_ > u4) # E: numpy.bool_
+reveal_type(b > u4) # E: numpy.bool_
+reveal_type(i > u4) # E: numpy.bool_
+reveal_type(AR > u4) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
+reveal_type(SEQ > u4) # E: Union[numpy.ndarray[Any, Any], numpy.bool_]
diff --git a/numpy/typing/tests/data/reveal/constants.py b/numpy/typing/tests/data/reveal/constants.py
new file mode 100644
index 000000000..b2382e861
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/constants.py
@@ -0,0 +1,52 @@
+import numpy as np
+
+reveal_type(np.Inf) # E: float
+reveal_type(np.Infinity) # E: float
+reveal_type(np.NAN) # E: float
+reveal_type(np.NINF) # E: float
+reveal_type(np.NZERO) # E: float
+reveal_type(np.NaN) # E: float
+reveal_type(np.PINF) # E: float
+reveal_type(np.PZERO) # E: float
+reveal_type(np.e) # E: float
+reveal_type(np.euler_gamma) # E: float
+reveal_type(np.inf) # E: float
+reveal_type(np.infty) # E: float
+reveal_type(np.nan) # E: float
+reveal_type(np.pi) # E: float
+
+reveal_type(np.ALLOW_THREADS) # E: int
+reveal_type(np.BUFSIZE) # E: int
+reveal_type(np.CLIP) # E: int
+reveal_type(np.ERR_CALL) # E: int
+reveal_type(np.ERR_DEFAULT) # E: int
+reveal_type(np.ERR_IGNORE) # E: int
+reveal_type(np.ERR_LOG) # E: int
+reveal_type(np.ERR_PRINT) # E: int
+reveal_type(np.ERR_RAISE) # E: int
+reveal_type(np.ERR_WARN) # E: int
+reveal_type(np.FLOATING_POINT_SUPPORT) # E: int
+reveal_type(np.FPE_DIVIDEBYZERO) # E: int
+reveal_type(np.FPE_INVALID) # E: int
+reveal_type(np.FPE_OVERFLOW) # E: int
+reveal_type(np.FPE_UNDERFLOW) # E: int
+reveal_type(np.MAXDIMS) # E: int
+reveal_type(np.MAY_SHARE_BOUNDS) # E: int
+reveal_type(np.MAY_SHARE_EXACT) # E: int
+reveal_type(np.RAISE) # E: int
+reveal_type(np.SHIFT_DIVIDEBYZERO) # E: int
+reveal_type(np.SHIFT_INVALID) # E: int
+reveal_type(np.SHIFT_OVERFLOW) # E: int
+reveal_type(np.SHIFT_UNDERFLOW) # E: int
+reveal_type(np.UFUNC_BUFSIZE_DEFAULT) # E: int
+reveal_type(np.WRAP) # E: int
+reveal_type(np.tracemalloc_domain) # E: int
+
+reveal_type(np.little_endian) # E: bool
+reveal_type(np.True_) # E: numpy.bool_
+reveal_type(np.False_) # E: numpy.bool_
+
+reveal_type(np.UFUNC_PYVALS_NAME) # E: str
+
+reveal_type(np.sctypeDict) # E: dict
+reveal_type(np.sctypes) # E: TypedDict
diff --git a/numpy/typing/tests/data/reveal/dtype.py b/numpy/typing/tests/data/reveal/dtype.py
new file mode 100644
index 000000000..626a15270
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/dtype.py
@@ -0,0 +1,41 @@
+import numpy as np
+
+dtype_obj: np.dtype[np.str_]
+
+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]]
+
+# String aliases
+reveal_type(np.dtype("float64")) # E: numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(np.dtype("float32")) # E: numpy.dtype[numpy.floating[numpy.typing._32Bit]]
+reveal_type(np.dtype("int64")) # E: numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]
+reveal_type(np.dtype("int32")) # E: numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]]
+reveal_type(np.dtype("bool")) # E: numpy.dtype[numpy.bool_]
+reveal_type(np.dtype("bytes")) # E: numpy.dtype[numpy.bytes_]
+reveal_type(np.dtype("str")) # E: numpy.dtype[numpy.str_]
+
+# Python types
+reveal_type(np.dtype(complex)) # E: numpy.dtype[numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]]
+reveal_type(np.dtype(float)) # E: numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(np.dtype(int)) # E: numpy.dtype
+reveal_type(np.dtype(bool)) # E: numpy.dtype[numpy.bool_]
+reveal_type(np.dtype(str)) # E: numpy.dtype[numpy.str_]
+reveal_type(np.dtype(bytes)) # E: numpy.dtype[numpy.bytes_]
+
+# Special case for None
+reveal_type(np.dtype(None)) # E: numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+# Dtypes of dtypes
+reveal_type(np.dtype(np.dtype(np.float64))) # E: numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+# Parameterized dtypes
+reveal_type(np.dtype("S8")) # E: numpy.dtype
+
+# Void
+reveal_type(np.dtype(("U", 10))) # E: numpy.dtype[numpy.void]
+
+# Methods and attributes
+reveal_type(dtype_obj.base) # E: numpy.dtype[numpy.str_]
+reveal_type(dtype_obj.subdtype) # E: Union[Tuple[numpy.dtype[numpy.str_], builtins.tuple[builtins.int]], None]
+reveal_type(dtype_obj.newbyteorder()) # E: numpy.dtype[numpy.str_]
+reveal_type(dtype_obj.type) # E: Type[numpy.str_]
diff --git a/numpy/typing/tests/data/reveal/flatiter.py b/numpy/typing/tests/data/reveal/flatiter.py
new file mode 100644
index 000000000..221101ebb
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/flatiter.py
@@ -0,0 +1,17 @@
+from typing import Any
+import numpy as np
+
+a: np.flatiter[np.ndarray[Any, np.dtype[np.str_]]]
+
+reveal_type(a.base) # E: numpy.ndarray[Any, numpy.dtype[numpy.str_]]
+reveal_type(a.copy()) # E: numpy.ndarray[Any, numpy.dtype[numpy.str_]]
+reveal_type(a.coords) # E: tuple[builtins.int]
+reveal_type(a.index) # E: int
+reveal_type(iter(a)) # E: Iterator[numpy.str_]
+reveal_type(next(a)) # E: numpy.str_
+reveal_type(a[0]) # E: numpy.str_
+reveal_type(a[[0, 1, 2]]) # E: numpy.ndarray[Any, numpy.dtype[numpy.str_]]
+reveal_type(a[...]) # E: numpy.ndarray[Any, numpy.dtype[numpy.str_]]
+reveal_type(a[:]) # E: numpy.ndarray[Any, numpy.dtype[numpy.str_]]
+reveal_type(a.__array__()) # E: numpy.ndarray[Any, numpy.dtype[numpy.str_]]
+reveal_type(a.__array__(np.float64)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
diff --git a/numpy/typing/tests/data/reveal/fromnumeric.py b/numpy/typing/tests/data/reveal/fromnumeric.py
new file mode 100644
index 000000000..2972fa1af
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/fromnumeric.py
@@ -0,0 +1,278 @@
+"""Tests for :mod:`numpy.core.fromnumeric`."""
+
+import numpy as np
+
+A = np.array(True, ndmin=2, dtype=bool)
+B = np.array(1.0, ndmin=2, dtype=np.float32)
+A.setflags(write=False)
+B.setflags(write=False)
+
+a = np.bool_(True)
+b = np.float32(1.0)
+c = 1.0
+d = np.array(1.0, dtype=np.float32) # writeable
+
+reveal_type(np.take(a, 0)) # E: numpy.bool_
+reveal_type(np.take(b, 0)) # E: numpy.floating[numpy.typing._32Bit]
+reveal_type(
+ np.take(c, 0) # E: Union[numpy.generic, datetime.datetime, datetime.timedelta]
+)
+reveal_type(
+ np.take(A, 0) # E: Union[numpy.generic, datetime.datetime, datetime.timedelta]
+)
+reveal_type(
+ np.take(B, 0) # E: Union[numpy.generic, datetime.datetime, datetime.timedelta]
+)
+reveal_type(
+ np.take( # E: Union[Union[numpy.generic, datetime.datetime, datetime.timedelta], numpy.ndarray[Any, Any]]
+ A, [0]
+ )
+)
+reveal_type(
+ np.take( # E: Union[Union[numpy.generic, datetime.datetime, datetime.timedelta], numpy.ndarray[Any, Any]]
+ B, [0]
+ )
+)
+
+reveal_type(np.reshape(a, 1)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.reshape(b, 1)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.reshape(c, 1)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.reshape(A, 1)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.reshape(B, 1)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.choose(a, [True, True])) # E: numpy.bool_
+reveal_type(np.choose(A, [True, True])) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.repeat(a, 1)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.repeat(b, 1)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.repeat(c, 1)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.repeat(A, 1)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.repeat(B, 1)) # E: numpy.ndarray[Any, Any]
+
+# TODO: Add tests for np.put()
+
+reveal_type(np.swapaxes(A, 0, 0)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.swapaxes(B, 0, 0)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.transpose(a)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.transpose(b)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.transpose(c)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.transpose(A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.transpose(B)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.partition(a, 0, axis=None)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.partition(b, 0, axis=None)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.partition(c, 0, axis=None)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.partition(A, 0)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.partition(B, 0)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.argpartition(a, 0)) # E: numpy.integer[Any]
+reveal_type(np.argpartition(b, 0)) # E: numpy.integer[Any]
+reveal_type(np.argpartition(c, 0)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.argpartition(A, 0)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.argpartition(B, 0)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.sort(A, 0)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.sort(B, 0)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.argsort(A, 0)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.argsort(B, 0)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.argmax(A)) # E: numpy.integer[Any]
+reveal_type(np.argmax(B)) # E: numpy.integer[Any]
+reveal_type(np.argmax(A, axis=0)) # E: Union[numpy.integer[Any], numpy.ndarray[Any, Any]]
+reveal_type(np.argmax(B, axis=0)) # E: Union[numpy.integer[Any], numpy.ndarray[Any, Any]]
+
+reveal_type(np.argmin(A)) # E: numpy.integer[Any]
+reveal_type(np.argmin(B)) # E: numpy.integer[Any]
+reveal_type(np.argmin(A, axis=0)) # E: Union[numpy.integer[Any], numpy.ndarray[Any, Any]]
+reveal_type(np.argmin(B, axis=0)) # E: Union[numpy.integer[Any], numpy.ndarray[Any, Any]]
+
+reveal_type(np.searchsorted(A[0], 0)) # E: numpy.integer[Any]
+reveal_type(np.searchsorted(B[0], 0)) # E: numpy.integer[Any]
+reveal_type(np.searchsorted(A[0], [0])) # E: numpy.ndarray[Any, Any]
+reveal_type(np.searchsorted(B[0], [0])) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.resize(a, (5, 5))) # E: numpy.ndarray[Any, Any]
+reveal_type(np.resize(b, (5, 5))) # E: numpy.ndarray[Any, Any]
+reveal_type(np.resize(c, (5, 5))) # E: numpy.ndarray[Any, Any]
+reveal_type(np.resize(A, (5, 5))) # E: numpy.ndarray[Any, Any]
+reveal_type(np.resize(B, (5, 5))) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.squeeze(a)) # E: numpy.bool_
+reveal_type(np.squeeze(b)) # E: numpy.floating[numpy.typing._32Bit]
+reveal_type(np.squeeze(c)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.squeeze(A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.squeeze(B)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.diagonal(A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.diagonal(B)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.trace(A)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(np.trace(B)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+
+reveal_type(np.ravel(a)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.ravel(b)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.ravel(c)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.ravel(A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.ravel(B)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.nonzero(a)) # E: tuple[numpy.ndarray[Any, Any]]
+reveal_type(np.nonzero(b)) # E: tuple[numpy.ndarray[Any, Any]]
+reveal_type(np.nonzero(c)) # E: tuple[numpy.ndarray[Any, Any]]
+reveal_type(np.nonzero(A)) # E: tuple[numpy.ndarray[Any, Any]]
+reveal_type(np.nonzero(B)) # E: tuple[numpy.ndarray[Any, Any]]
+
+reveal_type(np.shape(a)) # E: tuple[builtins.int]
+reveal_type(np.shape(b)) # E: tuple[builtins.int]
+reveal_type(np.shape(c)) # E: tuple[builtins.int]
+reveal_type(np.shape(A)) # E: tuple[builtins.int]
+reveal_type(np.shape(B)) # E: tuple[builtins.int]
+
+reveal_type(np.compress([True], a)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.compress([True], b)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.compress([True], c)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.compress([True], A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.compress([True], B)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.clip(a, 0, 1.0)) # E: numpy.number[Any]
+reveal_type(np.clip(b, -1, 1)) # E: numpy.floating[numpy.typing._32Bit]
+reveal_type(np.clip(c, 0, 1)) # E: numpy.number[Any]
+reveal_type(np.clip(A, 0, 1)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(np.clip(B, 0, 1)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+
+reveal_type(np.sum(a)) # E: numpy.number[Any]
+reveal_type(np.sum(b)) # E: numpy.floating[numpy.typing._32Bit]
+reveal_type(np.sum(c)) # E: numpy.number[Any]
+reveal_type(np.sum(A)) # E: numpy.number[Any]
+reveal_type(np.sum(B)) # E: numpy.number[Any]
+reveal_type(np.sum(A, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(np.sum(B, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+
+reveal_type(np.all(a)) # E: numpy.bool_
+reveal_type(np.all(b)) # E: numpy.bool_
+reveal_type(np.all(c)) # E: numpy.bool_
+reveal_type(np.all(A)) # E: numpy.bool_
+reveal_type(np.all(B)) # E: numpy.bool_
+reveal_type(np.all(A, axis=0)) # E: Union[numpy.bool_, numpy.ndarray[Any, Any]]
+reveal_type(np.all(B, axis=0)) # E: Union[numpy.bool_, numpy.ndarray[Any, Any]]
+reveal_type(np.all(A, keepdims=True)) # E: Union[numpy.bool_, numpy.ndarray[Any, Any]]
+reveal_type(np.all(B, keepdims=True)) # E: Union[numpy.bool_, numpy.ndarray[Any, Any]]
+
+reveal_type(np.any(a)) # E: numpy.bool_
+reveal_type(np.any(b)) # E: numpy.bool_
+reveal_type(np.any(c)) # E: numpy.bool_
+reveal_type(np.any(A)) # E: numpy.bool_
+reveal_type(np.any(B)) # E: numpy.bool_
+reveal_type(np.any(A, axis=0)) # E: Union[numpy.bool_, numpy.ndarray[Any, Any]]
+reveal_type(np.any(B, axis=0)) # E: Union[numpy.bool_, numpy.ndarray[Any, Any]]
+reveal_type(np.any(A, keepdims=True)) # E: Union[numpy.bool_, numpy.ndarray[Any, Any]]
+reveal_type(np.any(B, keepdims=True)) # E: Union[numpy.bool_, numpy.ndarray[Any, Any]]
+
+reveal_type(np.cumsum(a)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.cumsum(b)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.cumsum(c)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.cumsum(A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.cumsum(B)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.ptp(a)) # E: numpy.number[Any]
+reveal_type(np.ptp(b)) # E: numpy.floating[numpy.typing._32Bit]
+reveal_type(np.ptp(c)) # E: numpy.number[Any]
+reveal_type(np.ptp(A)) # E: numpy.number[Any]
+reveal_type(np.ptp(B)) # E: numpy.number[Any]
+reveal_type(np.ptp(A, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(np.ptp(B, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(np.ptp(A, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(np.ptp(B, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+
+reveal_type(np.amax(a)) # E: numpy.number[Any]
+reveal_type(np.amax(b)) # E: numpy.floating[numpy.typing._32Bit]
+reveal_type(np.amax(c)) # E: numpy.number[Any]
+reveal_type(np.amax(A)) # E: numpy.number[Any]
+reveal_type(np.amax(B)) # E: numpy.number[Any]
+reveal_type(np.amax(A, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(np.amax(B, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(np.amax(A, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(np.amax(B, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+
+reveal_type(np.amin(a)) # E: numpy.number[Any]
+reveal_type(np.amin(b)) # E: numpy.floating[numpy.typing._32Bit]
+reveal_type(np.amin(c)) # E: numpy.number[Any]
+reveal_type(np.amin(A)) # E: numpy.number[Any]
+reveal_type(np.amin(B)) # E: numpy.number[Any]
+reveal_type(np.amin(A, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(np.amin(B, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(np.amin(A, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(np.amin(B, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+
+reveal_type(np.prod(a)) # E: numpy.number[Any]
+reveal_type(np.prod(b)) # E: numpy.floating[numpy.typing._32Bit]
+reveal_type(np.prod(c)) # E: numpy.number[Any]
+reveal_type(np.prod(A)) # E: numpy.number[Any]
+reveal_type(np.prod(B)) # E: numpy.number[Any]
+reveal_type(np.prod(A, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(np.prod(B, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(np.prod(A, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(np.prod(B, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(np.prod(b, out=d)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.prod(B, out=d)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.cumprod(a)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.cumprod(b)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.cumprod(c)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.cumprod(A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.cumprod(B)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.ndim(a)) # E: int
+reveal_type(np.ndim(b)) # E: int
+reveal_type(np.ndim(c)) # E: int
+reveal_type(np.ndim(A)) # E: int
+reveal_type(np.ndim(B)) # E: int
+
+reveal_type(np.size(a)) # E: int
+reveal_type(np.size(b)) # E: int
+reveal_type(np.size(c)) # E: int
+reveal_type(np.size(A)) # E: int
+reveal_type(np.size(B)) # E: int
+
+reveal_type(np.around(a)) # E: numpy.number[Any]
+reveal_type(np.around(b)) # E: numpy.floating[numpy.typing._32Bit]
+reveal_type(np.around(c)) # E: numpy.number[Any]
+reveal_type(np.around(A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.around(B)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.mean(a)) # E: numpy.number[Any]
+reveal_type(np.mean(b)) # E: numpy.number[Any]
+reveal_type(np.mean(c)) # E: numpy.number[Any]
+reveal_type(np.mean(A)) # E: numpy.number[Any]
+reveal_type(np.mean(B)) # E: numpy.number[Any]
+reveal_type(np.mean(A, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(np.mean(B, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(np.mean(A, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(np.mean(B, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(np.mean(b, out=d)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.mean(B, out=d)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.std(a)) # E: numpy.number[Any]
+reveal_type(np.std(b)) # E: numpy.number[Any]
+reveal_type(np.std(c)) # E: numpy.number[Any]
+reveal_type(np.std(A)) # E: numpy.number[Any]
+reveal_type(np.std(B)) # E: numpy.number[Any]
+reveal_type(np.std(A, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(np.std(B, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(np.std(A, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(np.std(B, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(np.std(b, out=d)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.std(B, out=d)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.var(a)) # E: numpy.number[Any]
+reveal_type(np.var(b)) # E: numpy.number[Any]
+reveal_type(np.var(c)) # E: numpy.number[Any]
+reveal_type(np.var(A)) # E: numpy.number[Any]
+reveal_type(np.var(B)) # E: numpy.number[Any]
+reveal_type(np.var(A, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(np.var(B, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(np.var(A, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(np.var(B, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(np.var(b, out=d)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.var(B, out=d)) # E: numpy.ndarray[Any, Any]
diff --git a/numpy/typing/tests/data/reveal/mod.py b/numpy/typing/tests/data/reveal/mod.py
new file mode 100644
index 000000000..4292041f8
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/mod.py
@@ -0,0 +1,149 @@
+import numpy as np
+
+f8 = np.float64()
+i8 = np.int64()
+u8 = np.uint64()
+
+f4 = np.float32()
+i4 = np.int32()
+u4 = np.uint32()
+
+td = np.timedelta64(0, "D")
+b_ = np.bool_()
+
+b = bool()
+f = float()
+i = int()
+
+AR = np.array([1], dtype=np.bool_)
+AR.setflags(write=False)
+
+AR2 = np.array([1], dtype=np.timedelta64)
+AR2.setflags(write=False)
+
+# Time structures
+
+reveal_type(td % td) # E: numpy.timedelta64
+reveal_type(AR2 % td) # E: Any
+reveal_type(td % AR2) # E: Any
+
+reveal_type(divmod(td, td)) # E: Tuple[numpy.signedinteger[numpy.typing._64Bit], numpy.timedelta64]
+reveal_type(divmod(AR2, td)) # E: Tuple[Any, Any]
+reveal_type(divmod(td, AR2)) # E: Tuple[Any, Any]
+
+# Bool
+
+reveal_type(b_ % b) # E: numpy.signedinteger[numpy.typing._8Bit]
+reveal_type(b_ % i) # E: numpy.signedinteger[Any]
+reveal_type(b_ % f) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(b_ % b_) # E: numpy.signedinteger[numpy.typing._8Bit]
+reveal_type(b_ % i8) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(b_ % u8) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+reveal_type(b_ % f8) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(b_ % AR) # E: Any
+
+reveal_type(divmod(b_, b)) # E: Tuple[numpy.signedinteger[numpy.typing._8Bit], numpy.signedinteger[numpy.typing._8Bit]]
+reveal_type(divmod(b_, i)) # E: Tuple[numpy.signedinteger[Any], numpy.signedinteger[Any]]
+reveal_type(divmod(b_, f)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
+reveal_type(divmod(b_, b_)) # E: Tuple[numpy.signedinteger[numpy.typing._8Bit], numpy.signedinteger[numpy.typing._8Bit]]
+reveal_type(divmod(b_, i8)) # E: Tuple[numpy.signedinteger[numpy.typing._64Bit], numpy.signedinteger[numpy.typing._64Bit]]
+reveal_type(divmod(b_, u8)) # E: Tuple[numpy.unsignedinteger[numpy.typing._64Bit], numpy.unsignedinteger[numpy.typing._64Bit]]
+reveal_type(divmod(b_, f8)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
+reveal_type(divmod(b_, AR)) # E: Tuple[Any, Any]
+
+reveal_type(b % b_) # E: numpy.signedinteger[numpy.typing._8Bit]
+reveal_type(i % b_) # E: numpy.signedinteger[Any]
+reveal_type(f % b_) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(b_ % b_) # E: numpy.signedinteger[numpy.typing._8Bit]
+reveal_type(i8 % b_) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(u8 % b_) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+reveal_type(f8 % b_) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(AR % b_) # E: Any
+
+reveal_type(divmod(b, b_)) # E: Tuple[numpy.signedinteger[numpy.typing._8Bit], numpy.signedinteger[numpy.typing._8Bit]]
+reveal_type(divmod(i, b_)) # E: Tuple[numpy.signedinteger[Any], numpy.signedinteger[Any]]
+reveal_type(divmod(f, b_)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
+reveal_type(divmod(b_, b_)) # E: Tuple[numpy.signedinteger[numpy.typing._8Bit], numpy.signedinteger[numpy.typing._8Bit]]
+reveal_type(divmod(i8, b_)) # E: Tuple[numpy.signedinteger[numpy.typing._64Bit], numpy.signedinteger[numpy.typing._64Bit]]
+reveal_type(divmod(u8, b_)) # E: Tuple[numpy.unsignedinteger[numpy.typing._64Bit], numpy.unsignedinteger[numpy.typing._64Bit]]
+reveal_type(divmod(f8, b_)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
+reveal_type(divmod(AR, b_)) # E: Tuple[Any, Any]
+
+# int
+
+reveal_type(i8 % b) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(i8 % i) # E: numpy.signedinteger[Any]
+reveal_type(i8 % f) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(i8 % i8) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(i8 % f8) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(i4 % i8) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(i4 % f8) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(i4 % i4) # E: numpy.signedinteger[numpy.typing._32Bit]
+reveal_type(i4 % f4) # E: numpy.floating[numpy.typing._32Bit]
+reveal_type(i8 % AR) # E: Any
+
+reveal_type(divmod(i8, b)) # E: Tuple[numpy.signedinteger[numpy.typing._64Bit], numpy.signedinteger[numpy.typing._64Bit]]
+reveal_type(divmod(i8, i)) # E: Tuple[numpy.signedinteger[Any], numpy.signedinteger[Any]]
+reveal_type(divmod(i8, f)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
+reveal_type(divmod(i8, i8)) # E: Tuple[numpy.signedinteger[numpy.typing._64Bit], numpy.signedinteger[numpy.typing._64Bit]]
+reveal_type(divmod(i8, f8)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
+reveal_type(divmod(i8, i4)) # E: Tuple[numpy.signedinteger[numpy.typing._64Bit], numpy.signedinteger[numpy.typing._64Bit]]
+reveal_type(divmod(i8, f4)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
+reveal_type(divmod(i4, i4)) # E: Tuple[numpy.signedinteger[numpy.typing._32Bit], numpy.signedinteger[numpy.typing._32Bit]]
+reveal_type(divmod(i4, f4)) # E: Tuple[numpy.floating[numpy.typing._32Bit], numpy.floating[numpy.typing._32Bit]]
+reveal_type(divmod(i8, AR)) # E: Tuple[Any, Any]
+
+reveal_type(b % i8) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(i % i8) # E: numpy.signedinteger[Any]
+reveal_type(f % i8) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(i8 % i8) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(f8 % i8) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(i8 % i4) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(f8 % i4) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(i4 % i4) # E: numpy.signedinteger[numpy.typing._32Bit]
+reveal_type(f4 % i4) # E: numpy.floating[numpy.typing._32Bit]
+reveal_type(AR % i8) # E: Any
+
+reveal_type(divmod(b, i8)) # E: Tuple[numpy.signedinteger[numpy.typing._64Bit], numpy.signedinteger[numpy.typing._64Bit]]
+reveal_type(divmod(i, i8)) # E: Tuple[numpy.signedinteger[Any], numpy.signedinteger[Any]]
+reveal_type(divmod(f, i8)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
+reveal_type(divmod(i8, i8)) # E: Tuple[numpy.signedinteger[numpy.typing._64Bit], numpy.signedinteger[numpy.typing._64Bit]]
+reveal_type(divmod(f8, i8)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
+reveal_type(divmod(i4, i8)) # E: Tuple[numpy.signedinteger[numpy.typing._64Bit], numpy.signedinteger[numpy.typing._64Bit]]
+reveal_type(divmod(f4, i8)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
+reveal_type(divmod(i4, i4)) # E: Tuple[numpy.signedinteger[numpy.typing._32Bit], numpy.signedinteger[numpy.typing._32Bit]]
+reveal_type(divmod(f4, i4)) # E: Tuple[numpy.floating[numpy.typing._32Bit], numpy.floating[numpy.typing._32Bit]]
+reveal_type(divmod(AR, i8)) # E: Tuple[Any, Any]
+
+# float
+
+reveal_type(f8 % b) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(f8 % i) # E: numpy.floating[Any]
+reveal_type(f8 % f) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(i8 % f4) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(f4 % f4) # E: numpy.floating[numpy.typing._32Bit]
+reveal_type(f8 % AR) # E: Any
+
+reveal_type(divmod(f8, b)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
+reveal_type(divmod(f8, i)) # E: Tuple[numpy.floating[Any], numpy.floating[Any]]
+reveal_type(divmod(f8, f)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
+reveal_type(divmod(f8, f8)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
+reveal_type(divmod(f8, f4)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
+reveal_type(divmod(f4, f4)) # E: Tuple[numpy.floating[numpy.typing._32Bit], numpy.floating[numpy.typing._32Bit]]
+reveal_type(divmod(f8, AR)) # E: Tuple[Any, Any]
+
+reveal_type(b % f8) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(i % f8) # E: numpy.floating[Any]
+reveal_type(f % f8) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(f8 % f8) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(f8 % f8) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(f4 % f4) # E: numpy.floating[numpy.typing._32Bit]
+reveal_type(AR % f8) # E: Any
+
+reveal_type(divmod(b, f8)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
+reveal_type(divmod(i, f8)) # E: Tuple[numpy.floating[Any], numpy.floating[Any]]
+reveal_type(divmod(f, f8)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
+reveal_type(divmod(f8, f8)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
+reveal_type(divmod(f4, f8)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
+reveal_type(divmod(f4, f4)) # E: Tuple[numpy.floating[numpy.typing._32Bit], numpy.floating[numpy.typing._32Bit]]
+reveal_type(divmod(AR, f8)) # E: Tuple[Any, Any]
diff --git a/numpy/typing/tests/data/reveal/modules.py b/numpy/typing/tests/data/reveal/modules.py
new file mode 100644
index 000000000..406463152
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/modules.py
@@ -0,0 +1,20 @@
+import numpy as np
+
+reveal_type(np) # E: ModuleType
+
+reveal_type(np.char) # E: ModuleType
+reveal_type(np.ctypeslib) # E: ModuleType
+reveal_type(np.emath) # E: ModuleType
+reveal_type(np.fft) # E: ModuleType
+reveal_type(np.lib) # E: ModuleType
+reveal_type(np.linalg) # E: ModuleType
+reveal_type(np.ma) # E: ModuleType
+reveal_type(np.matrixlib) # E: ModuleType
+reveal_type(np.polynomial) # E: ModuleType
+reveal_type(np.random) # E: ModuleType
+reveal_type(np.rec) # E: ModuleType
+reveal_type(np.testing) # E: ModuleType
+reveal_type(np.version) # E: ModuleType
+
+# TODO: Remove when annotations have been added to `np.testing.assert_equal`
+reveal_type(np.testing.assert_equal) # E: Any
diff --git a/numpy/typing/tests/data/reveal/nbit_base_example.py b/numpy/typing/tests/data/reveal/nbit_base_example.py
new file mode 100644
index 000000000..0c4c53f9b
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/nbit_base_example.py
@@ -0,0 +1,18 @@
+from typing import TypeVar, Union
+import numpy as np
+import numpy.typing as npt
+
+T = TypeVar("T", bound=npt.NBitBase)
+
+def add(a: np.floating[T], b: np.integer[T]) -> np.floating[T]:
+ return a + b
+
+i8: np.int64
+i4: np.int32
+f8: np.float64
+f4: np.float32
+
+reveal_type(add(f8, i8)) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(add(f4, i8)) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(add(f8, i4)) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(add(f4, i4)) # E: numpy.floating[numpy.typing._32Bit]
diff --git a/numpy/typing/tests/data/reveal/ndarray_conversion.py b/numpy/typing/tests/data/reveal/ndarray_conversion.py
new file mode 100644
index 000000000..4ee637b75
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/ndarray_conversion.py
@@ -0,0 +1,54 @@
+import numpy as np
+
+nd = np.array([[1, 2], [3, 4]])
+
+# item
+reveal_type(nd.item()) # E: Any
+reveal_type(nd.item(1)) # E: Any
+reveal_type(nd.item(0, 1)) # E: Any
+reveal_type(nd.item((0, 1))) # E: Any
+
+# tolist
+reveal_type(nd.tolist()) # E: Any
+
+# itemset does not return a value
+# tostring is pretty simple
+# tobytes is pretty simple
+# tofile does not return a value
+# dump does not return a value
+# dumps is pretty simple
+
+# astype
+reveal_type(nd.astype("float")) # E: numpy.ndarray
+reveal_type(nd.astype(float)) # E: numpy.ndarray
+reveal_type(nd.astype(float, "K")) # E: numpy.ndarray
+reveal_type(nd.astype(float, "K", "unsafe")) # E: numpy.ndarray
+reveal_type(nd.astype(float, "K", "unsafe", True)) # E: numpy.ndarray
+reveal_type(nd.astype(float, "K", "unsafe", True, True)) # E: numpy.ndarray
+
+# byteswap
+reveal_type(nd.byteswap()) # E: numpy.ndarray
+reveal_type(nd.byteswap(True)) # E: numpy.ndarray
+
+# copy
+reveal_type(nd.copy()) # E: numpy.ndarray
+reveal_type(nd.copy("C")) # E: numpy.ndarray
+
+# view
+class SubArray(np.ndarray):
+ pass
+
+
+reveal_type(nd.view()) # E: numpy.ndarray
+reveal_type(nd.view(np.int64)) # E: numpy.ndarray
+# replace `Any` with `numpy.matrix` when `matrix` will be added to stubs
+reveal_type(nd.view(np.int64, np.matrix)) # E: Any
+reveal_type(nd.view(np.int64, SubArray)) # E: SubArray
+
+# getfield
+reveal_type(nd.getfield("float")) # E: numpy.ndarray
+reveal_type(nd.getfield(float)) # E: numpy.ndarray
+reveal_type(nd.getfield(float, 8)) # E: numpy.ndarray
+
+# setflags does not return a value
+# fill does not return a value
diff --git a/numpy/typing/tests/data/reveal/ndarray_misc.py b/numpy/typing/tests/data/reveal/ndarray_misc.py
new file mode 100644
index 000000000..3e640b3ba
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/ndarray_misc.py
@@ -0,0 +1,150 @@
+"""
+Tests for miscellaneous (non-magic) ``np.ndarray``/``np.generic`` methods.
+
+More extensive tests are performed for the methods'
+function-based counterpart in `../from_numeric.py`.
+
+"""
+
+import numpy as np
+
+class SubClass(np.ndarray): ...
+
+f8: np.float64
+A: np.ndarray
+B: SubClass
+
+reveal_type(f8.all()) # E: numpy.bool_
+reveal_type(A.all()) # E: numpy.bool_
+reveal_type(A.all(axis=0)) # E: Union[numpy.bool_, numpy.ndarray[Any, Any]]
+reveal_type(A.all(keepdims=True)) # E: Union[numpy.bool_, numpy.ndarray[Any, Any]]
+reveal_type(A.all(out=B)) # E: SubClass
+
+reveal_type(f8.any()) # E: numpy.bool_
+reveal_type(A.any()) # E: numpy.bool_
+reveal_type(A.any(axis=0)) # E: Union[numpy.bool_, numpy.ndarray[Any, Any]]
+reveal_type(A.any(keepdims=True)) # E: Union[numpy.bool_, numpy.ndarray[Any, Any]]
+reveal_type(A.any(out=B)) # E: SubClass
+
+reveal_type(f8.argmax()) # E: numpy.signedinteger[Any]
+reveal_type(A.argmax()) # E: numpy.signedinteger[Any]
+reveal_type(A.argmax(axis=0)) # E: Union[numpy.signedinteger[Any], numpy.ndarray[Any, Any]]
+reveal_type(A.argmax(out=B)) # E: SubClass
+
+reveal_type(f8.argmin()) # E: numpy.signedinteger[Any]
+reveal_type(A.argmin()) # E: numpy.signedinteger[Any]
+reveal_type(A.argmin(axis=0)) # E: Union[numpy.signedinteger[Any], numpy.ndarray[Any, Any]]
+reveal_type(A.argmin(out=B)) # E: SubClass
+
+reveal_type(f8.argsort()) # E: numpy.ndarray[Any, Any]
+reveal_type(A.argsort()) # E: numpy.ndarray[Any, Any]
+
+reveal_type(f8.astype(np.int64).choose([()])) # E: numpy.ndarray[Any, Any]
+reveal_type(A.choose([0])) # E: numpy.ndarray[Any, Any]
+reveal_type(A.choose([0], out=B)) # E: SubClass
+
+reveal_type(f8.clip(1)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(A.clip(1)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(A.clip(None, 1)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(A.clip(1, out=B)) # E: SubClass
+reveal_type(A.clip(None, 1, out=B)) # E: SubClass
+
+reveal_type(f8.compress([0])) # E: numpy.ndarray[Any, Any]
+reveal_type(A.compress([0])) # E: numpy.ndarray[Any, Any]
+reveal_type(A.compress([0], out=B)) # E: SubClass
+
+reveal_type(f8.conj()) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(A.conj()) # E: numpy.ndarray[Any, Any]
+reveal_type(B.conj()) # E: SubClass
+
+reveal_type(f8.conjugate()) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(A.conjugate()) # E: numpy.ndarray[Any, Any]
+reveal_type(B.conjugate()) # E: SubClass
+
+reveal_type(f8.cumprod()) # E: numpy.ndarray[Any, Any]
+reveal_type(A.cumprod()) # E: numpy.ndarray[Any, Any]
+reveal_type(A.cumprod(out=B)) # E: SubClass
+
+reveal_type(f8.cumsum()) # E: numpy.ndarray[Any, Any]
+reveal_type(A.cumsum()) # E: numpy.ndarray[Any, Any]
+reveal_type(A.cumsum(out=B)) # E: SubClass
+
+reveal_type(f8.max()) # E: numpy.number[Any]
+reveal_type(A.max()) # E: numpy.number[Any]
+reveal_type(A.max(axis=0)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(A.max(keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(A.max(out=B)) # E: SubClass
+
+reveal_type(f8.mean()) # E: numpy.number[Any]
+reveal_type(A.mean()) # E: numpy.number[Any]
+reveal_type(A.mean(axis=0)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(A.mean(keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(A.mean(out=B)) # E: SubClass
+
+reveal_type(f8.min()) # E: numpy.number[Any]
+reveal_type(A.min()) # E: numpy.number[Any]
+reveal_type(A.min(axis=0)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(A.min(keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(A.min(out=B)) # E: SubClass
+
+reveal_type(f8.newbyteorder()) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(A.newbyteorder()) # E: numpy.ndarray[Any, Any]
+reveal_type(B.newbyteorder('|')) # E: SubClass
+
+reveal_type(f8.prod()) # E: numpy.number[Any]
+reveal_type(A.prod()) # E: numpy.number[Any]
+reveal_type(A.prod(axis=0)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(A.prod(keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(A.prod(out=B)) # E: SubClass
+
+reveal_type(f8.ptp()) # E: numpy.number[Any]
+reveal_type(A.ptp()) # E: numpy.number[Any]
+reveal_type(A.ptp(axis=0)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(A.ptp(keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(A.ptp(out=B)) # E: SubClass
+
+reveal_type(f8.round()) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(A.round()) # E: numpy.ndarray[Any, Any]
+reveal_type(A.round(out=B)) # E: SubClass
+
+reveal_type(f8.repeat(1)) # E: numpy.ndarray[Any, Any]
+reveal_type(A.repeat(1)) # E: numpy.ndarray[Any, Any]
+reveal_type(B.repeat(1)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(f8.std()) # E: numpy.number[Any]
+reveal_type(A.std()) # E: numpy.number[Any]
+reveal_type(A.std(axis=0)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(A.std(keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(A.std(out=B)) # E: SubClass
+
+reveal_type(f8.sum()) # E: numpy.number[Any]
+reveal_type(A.sum()) # E: numpy.number[Any]
+reveal_type(A.sum(axis=0)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(A.sum(keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(A.sum(out=B)) # E: SubClass
+
+reveal_type(f8.take(0)) # E: numpy.generic
+reveal_type(A.take(0)) # E: numpy.generic
+reveal_type(A.take([0])) # E: numpy.ndarray[Any, Any]
+reveal_type(A.take(0, out=B)) # E: SubClass
+reveal_type(A.take([0], out=B)) # E: SubClass
+
+reveal_type(f8.var()) # E: numpy.number[Any]
+reveal_type(A.var()) # E: numpy.number[Any]
+reveal_type(A.var(axis=0)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(A.var(keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(A.var(out=B)) # E: SubClass
+
+reveal_type(A.argpartition([0])) # E: numpy.ndarray[Any, Any]
+
+reveal_type(A.diagonal()) # E: numpy.ndarray[Any, Any]
+
+reveal_type(A.dot(1)) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(A.dot(1, out=B)) # E: SubClass
+
+reveal_type(A.nonzero()) # E: tuple[numpy.ndarray[Any, Any]]
+
+reveal_type(A.searchsorted([1])) # E: numpy.ndarray[Any, Any]
+
+reveal_type(A.trace()) # E: Union[numpy.number[Any], numpy.ndarray[Any, Any]]
+reveal_type(A.trace(out=B)) # E: SubClass
diff --git a/numpy/typing/tests/data/reveal/ndarray_shape_manipulation.py b/numpy/typing/tests/data/reveal/ndarray_shape_manipulation.py
new file mode 100644
index 000000000..a44e1cfa1
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/ndarray_shape_manipulation.py
@@ -0,0 +1,35 @@
+import numpy as np
+
+nd = np.array([[1, 2], [3, 4]])
+
+# reshape
+reveal_type(nd.reshape()) # E: numpy.ndarray
+reveal_type(nd.reshape(4)) # E: numpy.ndarray
+reveal_type(nd.reshape(2, 2)) # E: numpy.ndarray
+reveal_type(nd.reshape((2, 2))) # E: numpy.ndarray
+
+reveal_type(nd.reshape((2, 2), order="C")) # E: numpy.ndarray
+reveal_type(nd.reshape(4, order="C")) # E: numpy.ndarray
+
+# resize does not return a value
+
+# transpose
+reveal_type(nd.transpose()) # E: numpy.ndarray
+reveal_type(nd.transpose(1, 0)) # E: numpy.ndarray
+reveal_type(nd.transpose((1, 0))) # E: numpy.ndarray
+
+# swapaxes
+reveal_type(nd.swapaxes(0, 1)) # E: numpy.ndarray
+
+# flatten
+reveal_type(nd.flatten()) # E: numpy.ndarray
+reveal_type(nd.flatten("C")) # E: numpy.ndarray
+
+# ravel
+reveal_type(nd.ravel()) # E: numpy.ndarray
+reveal_type(nd.ravel("C")) # E: numpy.ndarray
+
+# squeeze
+reveal_type(nd.squeeze()) # E: numpy.ndarray
+reveal_type(nd.squeeze(0)) # E: numpy.ndarray
+reveal_type(nd.squeeze((0, 2))) # E: numpy.ndarray
diff --git a/numpy/typing/tests/data/reveal/numeric.py b/numpy/typing/tests/data/reveal/numeric.py
new file mode 100644
index 000000000..78e5c1d61
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/numeric.py
@@ -0,0 +1,89 @@
+"""
+Tests for :mod:`numpy.core.numeric`.
+
+Does not include tests which fall under ``array_constructors``.
+
+"""
+
+from typing import List
+import numpy as np
+
+class SubClass(np.ndarray):
+ ...
+
+i8: np.int64
+
+A: np.ndarray
+B: List[int]
+C: SubClass
+
+reveal_type(np.count_nonzero(i8)) # E: int
+reveal_type(np.count_nonzero(A)) # E: int
+reveal_type(np.count_nonzero(B)) # E: int
+reveal_type(np.count_nonzero(A, keepdims=True)) # E: Union[numpy.signedinteger[Any], numpy.ndarray[Any, Any]]
+reveal_type(np.count_nonzero(A, axis=0)) # E: Union[numpy.signedinteger[Any], numpy.ndarray[Any, Any]]
+
+reveal_type(np.isfortran(i8)) # E: bool
+reveal_type(np.isfortran(A)) # E: bool
+
+reveal_type(np.argwhere(i8)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.argwhere(A)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.flatnonzero(i8)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.flatnonzero(A)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.correlate(B, A, mode="valid")) # E: numpy.ndarray[Any, Any]
+reveal_type(np.correlate(A, A, mode="same")) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.convolve(B, A, mode="valid")) # E: numpy.ndarray[Any, Any]
+reveal_type(np.convolve(A, A, mode="same")) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.outer(i8, A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.outer(B, A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.outer(A, A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.outer(A, A, out=C)) # E: SubClass
+
+reveal_type(np.tensordot(B, A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.tensordot(A, A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.tensordot(A, A, axes=0)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.tensordot(A, A, axes=(0, 1))) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.isscalar(i8)) # E: bool
+reveal_type(np.isscalar(A)) # E: bool
+reveal_type(np.isscalar(B)) # E: bool
+
+reveal_type(np.roll(A, 1)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.roll(A, (1, 2))) # E: numpy.ndarray[Any, Any]
+reveal_type(np.roll(B, 1)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.rollaxis(A, 0, 1)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.moveaxis(A, 0, 1)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.moveaxis(A, (0, 1), (1, 2))) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.cross(B, A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.cross(A, A)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.indices([0, 1, 2])) # E: numpy.ndarray[Any, Any]
+reveal_type(np.indices([0, 1, 2], sparse=False)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.indices([0, 1, 2], sparse=True)) # E: tuple[numpy.ndarray[Any, Any]]
+
+reveal_type(np.binary_repr(1)) # E: str
+
+reveal_type(np.base_repr(1)) # E: str
+
+reveal_type(np.allclose(i8, A)) # E: bool
+reveal_type(np.allclose(B, A)) # E: bool
+reveal_type(np.allclose(A, A)) # E: bool
+
+reveal_type(np.isclose(i8, A)) # E: Union[numpy.bool_, numpy.ndarray[Any, Any]]
+reveal_type(np.isclose(B, A)) # E: Union[numpy.bool_, numpy.ndarray[Any, Any]]
+reveal_type(np.isclose(A, A)) # E: Union[numpy.bool_, numpy.ndarray[Any, Any]]
+
+reveal_type(np.array_equal(i8, A)) # E: bool
+reveal_type(np.array_equal(B, A)) # E: bool
+reveal_type(np.array_equal(A, A)) # E: bool
+
+reveal_type(np.array_equiv(i8, A)) # E: bool
+reveal_type(np.array_equiv(B, A)) # E: bool
+reveal_type(np.array_equiv(A, A)) # E: bool
diff --git a/numpy/typing/tests/data/reveal/numerictypes.py b/numpy/typing/tests/data/reveal/numerictypes.py
new file mode 100644
index 000000000..e026158cd
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/numerictypes.py
@@ -0,0 +1,18 @@
+import numpy as np
+
+reveal_type(np.issctype(np.generic)) # E: bool
+reveal_type(np.issctype("foo")) # E: bool
+
+reveal_type(np.obj2sctype("S8")) # E: Union[numpy.generic, None]
+reveal_type(np.obj2sctype("S8", default=None)) # E: Union[numpy.generic, None]
+reveal_type(
+ np.obj2sctype("foo", default=int) # E: Union[numpy.generic, Type[builtins.int*]]
+)
+
+reveal_type(np.issubclass_(np.float64, float)) # E: bool
+reveal_type(np.issubclass_(np.float64, (int, float))) # E: bool
+
+reveal_type(np.sctype2char("S8")) # E: str
+reveal_type(np.sctype2char(list)) # E: str
+
+reveal_type(np.find_common_type([np.int64], [np.int64])) # E: numpy.dtype
diff --git a/numpy/typing/tests/data/reveal/scalars.py b/numpy/typing/tests/data/reveal/scalars.py
new file mode 100644
index 000000000..e887e302d
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/scalars.py
@@ -0,0 +1,28 @@
+import numpy as np
+
+x = np.complex64(3 + 2j)
+
+reveal_type(x.real) # E: numpy.floating[numpy.typing._32Bit]
+reveal_type(x.imag) # E: numpy.floating[numpy.typing._32Bit]
+
+reveal_type(x.real.real) # E: numpy.floating[numpy.typing._32Bit]
+reveal_type(x.real.imag) # E: numpy.floating[numpy.typing._32Bit]
+
+reveal_type(x.itemsize) # E: int
+reveal_type(x.shape) # E: Tuple[]
+reveal_type(x.strides) # E: Tuple[]
+
+reveal_type(x.ndim) # E: Literal[0]
+reveal_type(x.size) # E: Literal[1]
+
+reveal_type(x.squeeze()) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
+reveal_type(x.byteswap()) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
+reveal_type(x.transpose()) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
+
+reveal_type(x.dtype) # E: numpy.dtype[numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]]
+
+reveal_type(np.complex64().real) # E: numpy.floating[numpy.typing._32Bit]
+reveal_type(np.complex128().imag) # E: numpy.floating[numpy.typing._64Bit]
+
+reveal_type(np.unicode_('foo')) # E: numpy.str_
+reveal_type(np.str0('foo')) # E: numpy.str_
diff --git a/numpy/typing/tests/data/reveal/ufunc_config.py b/numpy/typing/tests/data/reveal/ufunc_config.py
new file mode 100644
index 000000000..26be80314
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/ufunc_config.py
@@ -0,0 +1,25 @@
+"""Typing tests for `numpy.core._ufunc_config`."""
+
+import numpy as np
+
+def func(a: str, b: int) -> None: ...
+
+class Write:
+ def write(self, value: str) -> None: ...
+
+reveal_type(np.seterr(all=None)) # E: TypedDict('numpy.core._ufunc_config._ErrDict'
+reveal_type(np.seterr(divide="ignore")) # E: TypedDict('numpy.core._ufunc_config._ErrDict'
+reveal_type(np.seterr(over="warn")) # E: TypedDict('numpy.core._ufunc_config._ErrDict'
+reveal_type(np.seterr(under="call")) # E: TypedDict('numpy.core._ufunc_config._ErrDict'
+reveal_type(np.seterr(invalid="raise")) # E: TypedDict('numpy.core._ufunc_config._ErrDict'
+reveal_type(np.geterr()) # E: TypedDict('numpy.core._ufunc_config._ErrDict'
+
+reveal_type(np.setbufsize(4096)) # E: int
+reveal_type(np.getbufsize()) # E: int
+
+reveal_type(np.seterrcall(func)) # E: Union[None, def (builtins.str, builtins.int) -> Any, numpy.core._ufunc_config._SupportsWrite]
+reveal_type(np.seterrcall(Write())) # E: Union[None, def (builtins.str, builtins.int) -> Any, numpy.core._ufunc_config._SupportsWrite]
+reveal_type(np.geterrcall()) # E: Union[None, def (builtins.str, builtins.int) -> Any, numpy.core._ufunc_config._SupportsWrite]
+
+reveal_type(np.errstate(call=func, all="call")) # E: numpy.errstate[def (a: builtins.str, b: builtins.int)]
+reveal_type(np.errstate(call=Write(), divide="log", over="log")) # E: numpy.errstate[ufunc_config.Write]
diff --git a/numpy/typing/tests/data/reveal/warnings_and_errors.py b/numpy/typing/tests/data/reveal/warnings_and_errors.py
new file mode 100644
index 000000000..c428deb7a
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/warnings_and_errors.py
@@ -0,0 +1,10 @@
+from typing import Type
+
+import numpy as np
+
+reveal_type(np.ModuleDeprecationWarning()) # E: numpy.ModuleDeprecationWarning
+reveal_type(np.VisibleDeprecationWarning()) # E: numpy.VisibleDeprecationWarning
+reveal_type(np.ComplexWarning()) # E: numpy.ComplexWarning
+reveal_type(np.RankWarning()) # E: numpy.RankWarning
+reveal_type(np.TooHardError()) # E: numpy.TooHardError
+reveal_type(np.AxisError(1)) # E: numpy.AxisError
diff --git a/numpy/typing/tests/test_isfile.py b/numpy/typing/tests/test_isfile.py
new file mode 100644
index 000000000..569f05435
--- /dev/null
+++ b/numpy/typing/tests/test_isfile.py
@@ -0,0 +1,33 @@
+import os
+from pathlib import Path
+
+import numpy as np
+from numpy.testing import assert_
+
+ROOT = Path(np.__file__).parents[0]
+FILES = [
+ ROOT / "py.typed",
+ ROOT / "__init__.pyi",
+ ROOT / "char.pyi",
+ ROOT / "ctypeslib.pyi",
+ ROOT / "emath.pyi",
+ ROOT / "rec.pyi",
+ ROOT / "core" / "__init__.pyi",
+ ROOT / "distutils" / "__init__.pyi",
+ ROOT / "f2py" / "__init__.pyi",
+ ROOT / "fft" / "__init__.pyi",
+ ROOT / "lib" / "__init__.pyi",
+ ROOT / "linalg" / "__init__.pyi",
+ ROOT / "ma" / "__init__.pyi",
+ ROOT / "matrixlib" / "__init__.pyi",
+ ROOT / "polynomial" / "__init__.pyi",
+ ROOT / "random" / "__init__.pyi",
+ ROOT / "testing" / "__init__.pyi",
+]
+
+
+class TestIsFile:
+ def test_isfile(self):
+ """Test if all ``.pyi`` files are properly installed."""
+ for file in FILES:
+ assert_(os.path.isfile(file))
diff --git a/numpy/typing/tests/test_typing.py b/numpy/typing/tests/test_typing.py
new file mode 100644
index 000000000..90de4fd6d
--- /dev/null
+++ b/numpy/typing/tests/test_typing.py
@@ -0,0 +1,182 @@
+import importlib.util
+import itertools
+import os
+import re
+from collections import defaultdict
+from typing import Optional
+
+import pytest
+try:
+ from mypy import api
+except ImportError:
+ NO_MYPY = True
+else:
+ NO_MYPY = False
+
+
+DATA_DIR = os.path.join(os.path.dirname(__file__), "data")
+PASS_DIR = os.path.join(DATA_DIR, "pass")
+FAIL_DIR = os.path.join(DATA_DIR, "fail")
+REVEAL_DIR = os.path.join(DATA_DIR, "reveal")
+MYPY_INI = os.path.join(DATA_DIR, "mypy.ini")
+CACHE_DIR = os.path.join(DATA_DIR, ".mypy_cache")
+
+
+def get_test_cases(directory):
+ for root, _, files in os.walk(directory):
+ for fname in files:
+ if os.path.splitext(fname)[-1] == ".py":
+ fullpath = os.path.join(root, fname)
+ # Use relative path for nice py.test name
+ relpath = os.path.relpath(fullpath, start=directory)
+
+ yield pytest.param(
+ fullpath,
+ # Manually specify a name for the test
+ id=relpath,
+ )
+
+
+@pytest.mark.slow
+@pytest.mark.skipif(NO_MYPY, reason="Mypy is not installed")
+@pytest.mark.parametrize("path", get_test_cases(PASS_DIR))
+def test_success(path):
+ stdout, stderr, exitcode = api.run([
+ "--config-file",
+ MYPY_INI,
+ "--cache-dir",
+ CACHE_DIR,
+ path,
+ ])
+ assert exitcode == 0, stdout
+ assert re.match(r"Success: no issues found in \d+ source files?", stdout.strip())
+
+
+@pytest.mark.slow
+@pytest.mark.skipif(NO_MYPY, reason="Mypy is not installed")
+@pytest.mark.parametrize("path", get_test_cases(FAIL_DIR))
+def test_fail(path):
+ __tracebackhide__ = True
+
+ stdout, stderr, exitcode = api.run([
+ "--config-file",
+ MYPY_INI,
+ "--cache-dir",
+ CACHE_DIR,
+ path,
+ ])
+ assert exitcode != 0
+
+ with open(path) as fin:
+ lines = fin.readlines()
+
+ errors = defaultdict(lambda: "")
+ error_lines = stdout.rstrip("\n").split("\n")
+ assert re.match(
+ r"Found \d+ errors? in \d+ files? \(checked \d+ source files?\)",
+ error_lines[-1].strip(),
+ )
+ for error_line in error_lines[:-1]:
+ error_line = error_line.strip()
+ if not error_line:
+ continue
+
+ match = re.match(
+ r"^.+\.py:(?P<lineno>\d+): (error|note): .+$",
+ error_line,
+ )
+ if match is None:
+ raise ValueError(f"Unexpected error line format: {error_line}")
+ lineno = int(match.group('lineno'))
+ errors[lineno] += error_line
+
+ for i, line in enumerate(lines):
+ lineno = i + 1
+ if line.startswith('#') or (" E:" not in line and lineno not in errors):
+ continue
+
+ target_line = lines[lineno - 1]
+ if "# E:" in target_line:
+ marker = target_line.split("# E:")[-1].strip()
+ expected_error = errors.get(lineno)
+ _test_fail(path, marker, expected_error, lineno)
+ else:
+ pytest.fail(f"Error {repr(errors[lineno])} not found")
+
+
+_FAIL_MSG1 = """Extra error at line {}
+
+Extra error: {!r}
+"""
+
+_FAIL_MSG2 = """Error mismatch at line {}
+
+Expected error: {!r}
+Observed error: {!r}
+"""
+
+
+def _test_fail(path: str, error: str, expected_error: Optional[str], lineno: int) -> None:
+ if expected_error is None:
+ raise AssertionError(_FAIL_MSG1.format(lineno, error))
+ elif error not in expected_error:
+ raise AssertionError(_FAIL_MSG2.format(lineno, expected_error, error))
+
+
+@pytest.mark.slow
+@pytest.mark.skipif(NO_MYPY, reason="Mypy is not installed")
+@pytest.mark.parametrize("path", get_test_cases(REVEAL_DIR))
+def test_reveal(path):
+ __tracebackhide__ = True
+
+ stdout, stderr, exitcode = api.run([
+ "--config-file",
+ MYPY_INI,
+ "--cache-dir",
+ CACHE_DIR,
+ path,
+ ])
+
+ with open(path) as fin:
+ lines = fin.read().replace('*', '').split("\n")
+
+ stdout_list = stdout.replace('*', '').split("\n")
+ for error_line in stdout_list:
+ error_line = error_line.strip()
+ if not error_line:
+ continue
+
+ match = re.match(
+ r"^.+\.py:(?P<lineno>\d+): note: .+$",
+ error_line,
+ )
+ if match is None:
+ raise ValueError(f"Unexpected reveal line format: {error_line}")
+ lineno = int(match.group('lineno')) - 1
+ assert "Revealed type is" in error_line
+
+ marker = lines[lineno].split("# E:")[-1].strip()
+ _test_reveal(path, marker, error_line, 1 + lineno)
+
+
+_REVEAL_MSG = """Reveal mismatch at line {}
+
+Expected reveal: {!r}
+Observed reveal: {!r}
+"""
+
+
+def _test_reveal(path: str, reveal: str, expected_reveal: str, lineno: int) -> None:
+ if reveal not in expected_reveal:
+ raise AssertionError(_REVEAL_MSG.format(lineno, expected_reveal, reveal))
+
+
+@pytest.mark.slow
+@pytest.mark.skipif(NO_MYPY, reason="Mypy is not installed")
+@pytest.mark.parametrize("path", get_test_cases(PASS_DIR))
+def test_code_runs(path):
+ path_without_extension, _ = os.path.splitext(path)
+ dirname, filename = path.split(os.sep)[-2:]
+ spec = importlib.util.spec_from_file_location(f"{dirname}.{filename}", path)
+ test_module = importlib.util.module_from_spec(spec)
+ spec.loader.exec_module(test_module)