summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
authorQiyu8 <fangchunlin@huawei.com>2020-12-14 16:02:59 +0800
committerQiyu8 <fangchunlin@huawei.com>2020-12-14 16:02:59 +0800
commit797477d40cbea905a1a4b8bd6c99376f6dc1e1a7 (patch)
treeb4cbae905dd05441a79f4290f920fc16b2a0aefa /numpy
parent3768b8ad352a5595073d1bdb04ea3523affb5732 (diff)
parente3722cea8adb7b66084a7edbc6afb978c5521c16 (diff)
downloadnumpy-797477d40cbea905a1a4b8bd6c99376f6dc1e1a7.tar.gz
Merge branch 'master' of github.com:numpy/numpy into usimd-compiled
Diffstat (limited to 'numpy')
-rw-r--r--numpy/__init__.pyi43
-rw-r--r--numpy/_version.py2
-rw-r--r--numpy/core/function_base.py2
-rw-r--r--numpy/core/src/multiarray/einsum_sumprod.c.src183
-rw-r--r--numpy/distutils/fcompiler/gnu.py2
-rw-r--r--numpy/lib/shape_base.py4
-rw-r--r--numpy/ma/core.py14
-rw-r--r--numpy/typing/_array_like.py21
-rw-r--r--numpy/typing/tests/data/fail/array_like.py4
-rw-r--r--numpy/typing/tests/data/pass/array_like.py8
-rw-r--r--numpy/typing/tests/data/pass/dtype.py8
-rw-r--r--numpy/typing/tests/data/pass/flatiter.py2
-rw-r--r--numpy/typing/tests/data/reveal/dtype.py8
-rw-r--r--numpy/typing/tests/data/reveal/flatiter.py21
14 files changed, 171 insertions, 151 deletions
diff --git a/numpy/__init__.pyi b/numpy/__init__.pyi
index 83afd2e49..cf9b3e86a 100644
--- a/numpy/__init__.pyi
+++ b/numpy/__init__.pyi
@@ -870,7 +870,7 @@ class dtype(Generic[_DTypeScalar]):
@property
def alignment(self) -> int: ...
@property
- def base(self) -> dtype: ...
+ def base(self: _DType) -> _DType: ...
@property
def byteorder(self) -> str: ...
@property
@@ -880,7 +880,7 @@ class dtype(Generic[_DTypeScalar]):
@property
def fields(
self,
- ) -> Optional[Mapping[str, Union[Tuple[dtype, int], Tuple[dtype, int, Any]]]]: ...
+ ) -> Optional[Mapping[str, Union[Tuple[dtype[Any], int], Tuple[dtype[Any], int, Any]]]]: ...
@property
def flags(self) -> int: ...
@property
@@ -906,14 +906,14 @@ class dtype(Generic[_DTypeScalar]):
@property
def ndim(self) -> int: ...
@property
- def subdtype(self) -> Optional[Tuple[dtype, _Shape]]: ...
- def newbyteorder(self, __new_order: _ByteOrder = ...) -> dtype: ...
+ def subdtype(self: _DType) -> Optional[Tuple[_DType, _Shape]]: ...
+ def newbyteorder(self: _DType, __new_order: _ByteOrder = ...) -> _DType: ...
# Leave str and type for end to avoid having to use `builtins.str`
# everywhere. See https://github.com/python/mypy/issues/3775
@property
def str(self) -> builtins.str: ...
@property
- def type(self) -> Type[generic]: ...
+ def type(self) -> Type[_DTypeScalar]: ...
class _flagsobj:
aligned: bool
@@ -955,24 +955,30 @@ _ArrayLikeInt = Union[
_FlatIterSelf = TypeVar("_FlatIterSelf", bound=flatiter)
-class flatiter(Generic[_ArraySelf]):
+class flatiter(Generic[_NdArraySubClass]):
@property
- def base(self) -> _ArraySelf: ...
+ def base(self) -> _NdArraySubClass: ...
@property
def coords(self) -> _Shape: ...
@property
def index(self) -> int: ...
- def copy(self) -> _ArraySelf: ...
+ def copy(self) -> _NdArraySubClass: ...
def __iter__(self: _FlatIterSelf) -> _FlatIterSelf: ...
- def __next__(self) -> generic: ...
+ def __next__(self: flatiter[ndarray[Any, dtype[_ScalarType]]]) -> _ScalarType: ...
def __len__(self) -> int: ...
@overload
- def __getitem__(self, key: Union[int, integer]) -> generic: ...
+ def __getitem__(
+ self: flatiter[ndarray[Any, dtype[_ScalarType]]],
+ key: Union[int, integer],
+ ) -> _ScalarType: ...
@overload
def __getitem__(
self, key: Union[_ArrayLikeInt, slice, ellipsis],
- ) -> _ArraySelf: ...
- def __array__(self, __dtype: DTypeLike = ...) -> ndarray: ...
+ ) -> _NdArraySubClass: ...
+ @overload
+ def __array__(self: flatiter[ndarray[Any, _DType]], __dtype: None = ...) -> ndarray[Any, _DType]: ...
+ @overload
+ def __array__(self, __dtype: DTypeLike) -> ndarray[Any, dtype[Any]]: ...
_OrderKACF = Optional[Literal["K", "A", "C", "F"]]
_OrderACF = Optional[Literal["A", "C", "F"]]
@@ -1004,7 +1010,6 @@ class _ArrayOrScalarCommon:
def itemsize(self) -> int: ...
@property
def nbytes(self) -> int: ...
- def __array__(self, __dtype: DTypeLike = ...) -> ndarray: ...
def __bool__(self) -> bool: ...
def __bytes__(self) -> bytes: ...
def __str__(self) -> str: ...
@@ -1468,6 +1473,10 @@ class ndarray(_ArrayOrScalarCommon, Generic[_ShapeType, _DType]):
strides: _ShapeLike = ...,
order: _OrderKACF = ...,
) -> _ArraySelf: ...
+ @overload
+ def __array__(self, __dtype: None = ...) -> ndarray[Any, _DType]: ...
+ @overload
+ def __array__(self, __dtype: DTypeLike) -> ndarray[Any, dtype[Any]]: ...
@property
def ctypes(self) -> _ctypes: ...
@property
@@ -1481,7 +1490,7 @@ class ndarray(_ArrayOrScalarCommon, Generic[_ShapeType, _DType]):
def byteswap(self: _ArraySelf, inplace: bool = ...) -> _ArraySelf: ...
def fill(self, value: Any) -> None: ...
@property
- def flat(self: _ArraySelf) -> flatiter[_ArraySelf]: ...
+ def flat(self: _NdArraySubClass) -> flatiter[_NdArraySubClass]: ...
@overload
def item(self, *args: int) -> Any: ...
@overload
@@ -1646,6 +1655,10 @@ _NBit_co2 = TypeVar("_NBit_co2", covariant=True, bound=NBitBase)
class generic(_ArrayOrScalarCommon):
@abstractmethod
def __init__(self, *args: Any, **kwargs: Any) -> None: ...
+ @overload
+ def __array__(self: _ScalarType, __dtype: None = ...) -> ndarray[Any, dtype[_ScalarType]]: ...
+ @overload
+ def __array__(self, __dtype: DTypeLike) -> ndarray[Any, dtype[Any]]: ...
@property
def base(self) -> None: ...
@property
@@ -1658,7 +1671,7 @@ class generic(_ArrayOrScalarCommon):
def strides(self) -> Tuple[()]: ...
def byteswap(self: _ScalarType, inplace: Literal[False] = ...) -> _ScalarType: ...
@property
- def flat(self) -> flatiter[ndarray]: ...
+ def flat(self: _ScalarType) -> flatiter[ndarray[Any, dtype[_ScalarType]]]: ...
def item(
self: _ScalarType,
__args: Union[Literal[0], Tuple[()], Tuple[Literal[0]]] = ...,
diff --git a/numpy/_version.py b/numpy/_version.py
index 73f9f5c7f..6605bf4af 100644
--- a/numpy/_version.py
+++ b/numpy/_version.py
@@ -236,7 +236,7 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command):
# if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty]
# if there isn't one, this yields HEX[-dirty] (no NUM)
- describe_out, rc = run_command(GITS, ["describe", "--tags", "--dirty",
+ describe_out, rc = run_command(GITS, ["describe", "--tags", "--dirty=",
"--always", "--long",
"--match", "%s*" % tag_prefix],
cwd=root)
diff --git a/numpy/core/function_base.py b/numpy/core/function_base.py
index 8a1fee99b..e940ac230 100644
--- a/numpy/core/function_base.py
+++ b/numpy/core/function_base.py
@@ -371,7 +371,7 @@ def geomspace(start, stop, num=50, endpoint=True, dtype=None, axis=0):
6.12323400e-17+1.00000000e+00j, 7.07106781e-01+7.07106781e-01j,
1.00000000e+00+0.00000000e+00j])
- Graphical illustration of ``endpoint`` parameter:
+ Graphical illustration of `endpoint` parameter:
>>> import matplotlib.pyplot as plt
>>> N = 10
diff --git a/numpy/core/src/multiarray/einsum_sumprod.c.src b/numpy/core/src/multiarray/einsum_sumprod.c.src
index c58e74287..caba0e00a 100644
--- a/numpy/core/src/multiarray/einsum_sumprod.c.src
+++ b/numpy/core/src/multiarray/einsum_sumprod.c.src
@@ -17,7 +17,8 @@
#include "einsum_sumprod.h"
#include "einsum_debug.h"
-
+#include "simd/simd.h"
+#include "common.h"
#ifdef NPY_HAVE_SSE_INTRINSICS
#define EINSUM_USE_SSE1 1
@@ -41,6 +42,13 @@
#define EINSUM_IS_SSE_ALIGNED(x) ((((npy_intp)x)&0xf) == 0)
+// ARM/Neon don't have instructions for aligned memory access
+#ifdef NPY_HAVE_NEON
+ #define EINSUM_IS_ALIGNED(x) 0
+#else
+ #define EINSUM_IS_ALIGNED(x) npy_is_aligned(x, NPY_SIMD_WIDTH)
+#endif
+
/**********************************************/
/**begin repeat
@@ -56,6 +64,10 @@
* npy_ubyte, npy_ushort, npy_uint, npy_ulong, npy_ulonglong,
* npy_float, npy_float, npy_double, npy_longdouble,
* npy_float, npy_double, npy_longdouble#
+ * #sfx = s8, s16, s32, long, s64,
+ * u8, u16, u32, ulong, u64,
+ * half, f32, f64, longdouble,
+ * f32, f64, clongdouble#
* #to = ,,,,,
* ,,,,,
* npy_float_to_half,,,,
@@ -76,6 +88,10 @@
* 0*5,
* 0,0,1,0,
* 0*3#
+ * #NPYV_CHK = 0*5,
+ * 0*5,
+ * 0, NPY_SIMD, NPY_SIMD_F64, 0,
+ * 0*3#
*/
/**begin repeat1
@@ -250,115 +266,80 @@ static void
@type@ *data0 = (@type@ *)dataptr[0];
@type@ *data1 = (@type@ *)dataptr[1];
@type@ *data_out = (@type@ *)dataptr[2];
-
-#if EINSUM_USE_SSE1 && @float32@
- __m128 a, b;
-#elif EINSUM_USE_SSE2 && @float64@
- __m128d a, b;
-#endif
-
NPY_EINSUM_DBG_PRINT1("@name@_sum_of_products_contig_two (%d)\n",
(int)count);
-
-/* This is placed before the main loop to make small counts faster */
-finish_after_unrolled_loop:
- switch (count) {
-/**begin repeat2
- * #i = 6, 5, 4, 3, 2, 1, 0#
- */
- case @i@+1:
- data_out[@i@] = @to@(@from@(data0[@i@]) *
- @from@(data1[@i@]) +
- @from@(data_out[@i@]));
-/**end repeat2**/
- case 0:
- return;
- }
-
-#if EINSUM_USE_SSE1 && @float32@
+ // NPYV check for @type@
+#if @NPYV_CHK@
/* Use aligned instructions if possible */
- if (EINSUM_IS_SSE_ALIGNED(data0) && EINSUM_IS_SSE_ALIGNED(data1) &&
- EINSUM_IS_SSE_ALIGNED(data_out)) {
- /* Unroll the loop by 8 */
- while (count >= 8) {
- count -= 8;
-
-/**begin repeat2
- * #i = 0, 4#
- */
- a = _mm_mul_ps(_mm_load_ps(data0+@i@), _mm_load_ps(data1+@i@));
- b = _mm_add_ps(a, _mm_load_ps(data_out+@i@));
- _mm_store_ps(data_out+@i@, b);
-/**end repeat2**/
- data0 += 8;
- data1 += 8;
- data_out += 8;
+ const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
+ EINSUM_IS_ALIGNED(data_out);
+ const int vstep = npyv_nlanes_@sfx@;
+
+ /**begin repeat2
+ * #cond = if(is_aligned), else#
+ * #ld = loada, load#
+ * #st = storea, store#
+ */
+ @cond@ {
+ const npy_intp vstepx4 = vstep * 4;
+ for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
+ /**begin repeat3
+ * #i = 0, 1, 2, 3#
+ */
+ npyv_@sfx@ a@i@ = npyv_@ld@_@sfx@(data0 + vstep * @i@);
+ npyv_@sfx@ b@i@ = npyv_@ld@_@sfx@(data1 + vstep * @i@);
+ npyv_@sfx@ c@i@ = npyv_@ld@_@sfx@(data_out + vstep * @i@);
+ /**end repeat3**/
+ /**begin repeat3
+ * #i = 0, 1, 2, 3#
+ */
+ npyv_@sfx@ abc@i@ = npyv_muladd_@sfx@(a@i@, b@i@, c@i@);
+ /**end repeat3**/
+ /**begin repeat3
+ * #i = 0, 1, 2, 3#
+ */
+ npyv_@st@_@sfx@(data_out + vstep * @i@, abc@i@);
+ /**end repeat3**/
}
-
- /* Finish off the loop */
- goto finish_after_unrolled_loop;
}
-#elif EINSUM_USE_SSE2 && @float64@
- /* Use aligned instructions if possible */
- if (EINSUM_IS_SSE_ALIGNED(data0) && EINSUM_IS_SSE_ALIGNED(data1) &&
- EINSUM_IS_SSE_ALIGNED(data_out)) {
- /* Unroll the loop by 8 */
- while (count >= 8) {
- count -= 8;
-
-/**begin repeat2
- * #i = 0, 2, 4, 6#
- */
- a = _mm_mul_pd(_mm_load_pd(data0+@i@), _mm_load_pd(data1+@i@));
- b = _mm_add_pd(a, _mm_load_pd(data_out+@i@));
- _mm_store_pd(data_out+@i@, b);
-/**end repeat2**/
- data0 += 8;
- data1 += 8;
- data_out += 8;
- }
-
- /* Finish off the loop */
- goto finish_after_unrolled_loop;
+ /**end repeat2**/
+ for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
+ npyv_@sfx@ a = npyv_load_tillz_@sfx@(data0, count);
+ npyv_@sfx@ b = npyv_load_tillz_@sfx@(data1, count);
+ npyv_@sfx@ c = npyv_load_tillz_@sfx@(data_out, count);
+ npyv_store_till_@sfx@(data_out, count, npyv_muladd_@sfx@(a, b, c));
}
-#endif
-
- /* Unroll the loop by 8 */
- while (count >= 8) {
- count -= 8;
-
-#if EINSUM_USE_SSE1 && @float32@
-/**begin repeat2
- * #i = 0, 4#
- */
- a = _mm_mul_ps(_mm_loadu_ps(data0+@i@), _mm_loadu_ps(data1+@i@));
- b = _mm_add_ps(a, _mm_loadu_ps(data_out+@i@));
- _mm_storeu_ps(data_out+@i@, b);
-/**end repeat2**/
-#elif EINSUM_USE_SSE2 && @float64@
-/**begin repeat2
- * #i = 0, 2, 4, 6#
- */
- a = _mm_mul_pd(_mm_loadu_pd(data0+@i@), _mm_loadu_pd(data1+@i@));
- b = _mm_add_pd(a, _mm_loadu_pd(data_out+@i@));
- _mm_storeu_pd(data_out+@i@, b);
-/**end repeat2**/
+ npyv_cleanup();
#else
-/**begin repeat2
- * #i = 0, 1, 2, 3, 4, 5, 6, 7#
- */
- data_out[@i@] = @to@(@from@(data0[@i@]) *
- @from@(data1[@i@]) +
- @from@(data_out[@i@]));
-/**end repeat2**/
-#endif
- data0 += 8;
- data1 += 8;
- data_out += 8;
+#ifndef NPY_DISABLE_OPTIMIZATION
+ for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
+ /**begin repeat2
+ * #i = 0, 1, 2, 3#
+ */
+ const @type@ a@i@ = @from@(data0[@i@]);
+ const @type@ b@i@ = @from@(data1[@i@]);
+ const @type@ c@i@ = @from@(data_out[@i@]);
+ /**end repeat2**/
+ /**begin repeat2
+ * #i = 0, 1, 2, 3#
+ */
+ const @type@ abc@i@ = a@i@ * b@i@ + c@i@;
+ /**end repeat2**/
+ /**begin repeat2
+ * #i = 0, 1, 2, 3#
+ */
+ data_out[@i@] = @to@(abc@i@);
+ /**end repeat2**/
}
+#endif // !NPY_DISABLE_OPTIMIZATION
+ for (; count > 0; --count, ++data0, ++data1, ++data_out) {
+ const @type@ a = @from@(*data0);
+ const @type@ b = @from@(*data1);
+ const @type@ c = @from@(*data_out);
+ *data_out = @to@(a * b + c);
+ }
+#endif // NPYV check for @type@
- /* Finish off the loop */
- goto finish_after_unrolled_loop;
}
/* Some extra specializations for the two operand case */
diff --git a/numpy/distutils/fcompiler/gnu.py b/numpy/distutils/fcompiler/gnu.py
index 0d9d769c2..68d1501ee 100644
--- a/numpy/distutils/fcompiler/gnu.py
+++ b/numpy/distutils/fcompiler/gnu.py
@@ -126,7 +126,7 @@ class GnuFCompiler(FCompiler):
target = '10.9'
s = f'Env. variable MACOSX_DEPLOYMENT_TARGET set to {target}'
warnings.warn(s, stacklevel=2)
- os.environ['MACOSX_DEPLOYMENT_TARGET'] = target
+ os.environ['MACOSX_DEPLOYMENT_TARGET'] = str(target)
opt.extend(['-undefined', 'dynamic_lookup', '-bundle'])
else:
opt.append("-shared")
diff --git a/numpy/lib/shape_base.py b/numpy/lib/shape_base.py
index cbc4641d8..f0596444e 100644
--- a/numpy/lib/shape_base.py
+++ b/numpy/lib/shape_base.py
@@ -1088,8 +1088,8 @@ def kron(a, b):
-----
The function assumes that the number of dimensions of `a` and `b`
are the same, if necessary prepending the smallest with ones.
- If `a.shape = (r0,r1,..,rN)` and `b.shape = (s0,s1,...,sN)`,
- the Kronecker product has shape `(r0*s0, r1*s1, ..., rN*SN)`.
+ If ``a.shape = (r0,r1,..,rN)`` and ``b.shape = (s0,s1,...,sN)``,
+ the Kronecker product has shape ``(r0*s0, r1*s1, ..., rN*SN)``.
The elements are products of elements from `a` and `b`, organized
explicitly by::
diff --git a/numpy/ma/core.py b/numpy/ma/core.py
index 4fb7d8c28..d6af22337 100644
--- a/numpy/ma/core.py
+++ b/numpy/ma/core.py
@@ -5439,7 +5439,7 @@ class MaskedArray(ndarray):
When the array contains unmasked values at the same extremes of the
datatype, the ordering of these values and the masked values is
undefined.
- fill_value : {var}, optional
+ fill_value : scalar or None, optional
Value used internally for the masked values.
If ``fill_value`` is not None, it supersedes ``endwith``.
@@ -5497,7 +5497,7 @@ class MaskedArray(ndarray):
axis : {None, integer}
If None, the index is into the flattened array, otherwise along
the specified axis
- fill_value : {var}, optional
+ fill_value : scalar or None, optional
Value used to fill in the masked values. If None, the output of
minimum_fill_value(self._data) is used instead.
out : {None, array}, optional
@@ -5543,7 +5543,7 @@ class MaskedArray(ndarray):
axis : {None, integer}
If None, the index is into the flattened array, otherwise along
the specified axis
- fill_value : {var}, optional
+ fill_value : scalar or None, optional
Value used to fill in the masked values. If None, the output of
maximum_fill_value(self._data) is used instead.
out : {None, array}, optional
@@ -5594,7 +5594,7 @@ class MaskedArray(ndarray):
When the array contains unmasked values sorting at the same extremes of the
datatype, the ordering of these values and the masked values is
undefined.
- fill_value : {var}, optional
+ fill_value : scalar or None, optional
Value used internally for the masked values.
If ``fill_value`` is not None, it supersedes ``endwith``.
@@ -5665,7 +5665,7 @@ class MaskedArray(ndarray):
out : array_like, optional
Alternative output array in which to place the result. Must be of
the same shape and buffer length as the expected output.
- fill_value : {var}, optional
+ fill_value : scalar or None, optional
Value used to fill in the masked values.
If None, use the output of `minimum_fill_value`.
keepdims : bool, optional
@@ -5799,7 +5799,7 @@ class MaskedArray(ndarray):
out : array_like, optional
Alternative output array in which to place the result. Must
be of the same shape and buffer length as the expected output.
- fill_value : {var}, optional
+ fill_value : scalar or None, optional
Value used to fill in the masked values.
If None, use the output of maximum_fill_value().
keepdims : bool, optional
@@ -5876,7 +5876,7 @@ class MaskedArray(ndarray):
Alternative output array in which to place the result. It must
have the same shape and buffer length as the expected output
but the type will be cast if necessary.
- fill_value : {var}, optional
+ fill_value : scalar or None, optional
Value used to fill in the masked values.
keepdims : bool, optional
If this is set to True, the axes which are reduced are left
diff --git a/numpy/typing/_array_like.py b/numpy/typing/_array_like.py
index a1a604239..63b67b33a 100644
--- a/numpy/typing/_array_like.py
+++ b/numpy/typing/_array_like.py
@@ -1,7 +1,9 @@
+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 numpy import ndarray, dtype
from ._scalars import _ScalarLike
from ._dtype_like import DTypeLike
@@ -16,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
@@ -36,5 +41,5 @@ ArrayLike = Union[
_ScalarLike,
Sequence[_ScalarLike],
Sequence[Sequence[Any]], # TODO: Wait for support for recursive types
- _SupportsArray,
+ "_SupportsArray[Any]",
]
diff --git a/numpy/typing/tests/data/fail/array_like.py b/numpy/typing/tests/data/fail/array_like.py
index a97e72dc7..3bbd29061 100644
--- a/numpy/typing/tests/data/fail/array_like.py
+++ b/numpy/typing/tests/data/fail/array_like.py
@@ -11,6 +11,6 @@ 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: Unexpected keyword argument
+scalar.__array__(dtype=np.float64) # E: No overload variant
array = np.array([1])
-array.__array__(dtype=np.float64) # E: Unexpected keyword argument
+array.__array__(dtype=np.float64) # E: No overload variant
diff --git a/numpy/typing/tests/data/pass/array_like.py b/numpy/typing/tests/data/pass/array_like.py
index f85724267..563fc08c7 100644
--- a/numpy/typing/tests/data/pass/array_like.py
+++ b/numpy/typing/tests/data/pass/array_like.py
@@ -25,13 +25,13 @@ class A:
x13: ArrayLike = A()
scalar: _SupportsArray = np.int64(1)
-scalar.__array__(np.float64)
+scalar.__array__(None)
array: _SupportsArray = np.array(1)
-array.__array__(np.float64)
+array.__array__(None)
a: _SupportsArray = A()
-a.__array__(np.int64)
-a.__array__(dtype=np.int64)
+a.__array__(None)
+a.__array__(dtype=None)
# Escape hatch for when you mean to make something like an object
# array.
diff --git a/numpy/typing/tests/data/pass/dtype.py b/numpy/typing/tests/data/pass/dtype.py
index cbae8c078..a97edc302 100644
--- a/numpy/typing/tests/data/pass/dtype.py
+++ b/numpy/typing/tests/data/pass/dtype.py
@@ -1,5 +1,7 @@
import numpy as np
+dtype_obj = np.dtype(np.str_)
+
np.dtype(dtype=np.int64)
np.dtype(int)
np.dtype("int")
@@ -33,3 +35,9 @@ class Test:
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
index c0219eb2b..4fdf25299 100644
--- a/numpy/typing/tests/data/pass/flatiter.py
+++ b/numpy/typing/tests/data/pass/flatiter.py
@@ -12,3 +12,5 @@ a[0]
a[[0, 1, 2]]
a[...]
a[:]
+a.__array__()
+a.__array__(np.float64)
diff --git a/numpy/typing/tests/data/reveal/dtype.py b/numpy/typing/tests/data/reveal/dtype.py
index d414f2c49..626a15270 100644
--- a/numpy/typing/tests/data/reveal/dtype.py
+++ b/numpy/typing/tests/data/reveal/dtype.py
@@ -1,5 +1,7 @@
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]]
@@ -31,3 +33,9 @@ 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
index 56cdc7a0e..221101ebb 100644
--- a/numpy/typing/tests/data/reveal/flatiter.py
+++ b/numpy/typing/tests/data/reveal/flatiter.py
@@ -1,14 +1,17 @@
+from typing import Any
import numpy as np
-a: "np.flatiter[np.ndarray]"
+a: np.flatiter[np.ndarray[Any, np.dtype[np.str_]]]
-reveal_type(a.base) # E: numpy.ndarray*
-reveal_type(a.copy()) # E: numpy.ndarray*
+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.generic*]
-reveal_type(next(a)) # E: numpy.generic
-reveal_type(a[0]) # E: numpy.generic
-reveal_type(a[[0, 1, 2]]) # E: numpy.ndarray*
-reveal_type(a[...]) # E: numpy.ndarray*
-reveal_type(a[:]) # E: numpy.ndarray*
+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]]