summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRalf Gommers <ralf.gommers@gmail.com>2021-03-06 20:54:23 +0100
committerGitHub <noreply@github.com>2021-03-06 20:54:23 +0100
commiteff28c4c903d39c9be373434e7e5ef1fdf194a77 (patch)
treef15e3982c1dc508aa63e9efcfb76648d69f4038e
parentdcf580482569352275acff282fa0548fbc12042e (diff)
parentc6bdbad5458c3b48ee92350fa0b723ee3b98743f (diff)
downloadnumpy-eff28c4c903d39c9be373434e7e5ef1fdf194a77.tar.gz
Merge pull request #18417 from BvB93/comparison5
ENH: Add dtype-support to the ufunc-based `ndarray` magic methods 4/4
-rw-r--r--numpy/__init__.pyi204
-rw-r--r--numpy/typing/tests/data/fail/arithmetic.py49
-rw-r--r--numpy/typing/tests/data/pass/arithmetic.py73
-rw-r--r--numpy/typing/tests/test_typing.py29
4 files changed, 326 insertions, 29 deletions
diff --git a/numpy/__init__.pyi b/numpy/__init__.pyi
index dba4176f2..9cdc4f2e1 100644
--- a/numpy/__init__.pyi
+++ b/numpy/__init__.pyi
@@ -15,6 +15,7 @@ from numpy.typing import (
_SupportsArray,
_NestedSequence,
_RecursiveSequence,
+ _SupportsArray,
_ArrayLikeBool_co,
_ArrayLikeUInt_co,
_ArrayLikeInt_co,
@@ -1640,7 +1641,7 @@ class ndarray(_ArrayOrScalarCommon, Generic[_ShapeType, _DType_co]):
@overload
def __mod__(self: _ArrayFloat_co, other: _ArrayLikeFloat_co) -> _ArrayOrScalar[floating[Any]]: ... # type: ignore[misc]
@overload
- def __mod__(self: _ArrayTD64_co, other: _ArrayLikeTD64_co) -> _ArrayOrScalar[timedelta64]: ...
+ def __mod__(self: _ArrayTD64_co, other: _NestedSequence[_SupportsArray[dtype[timedelta64]]]) -> _ArrayOrScalar[timedelta64]: ...
@overload
def __mod__(self: _ArrayND[object_], other: Any) -> Any: ...
@overload
@@ -1662,7 +1663,7 @@ class ndarray(_ArrayOrScalarCommon, Generic[_ShapeType, _DType_co]):
@overload
def __rmod__(self: _ArrayFloat_co, other: _ArrayLikeFloat_co) -> _ArrayOrScalar[floating[Any]]: ... # type: ignore[misc]
@overload
- def __rmod__(self: _ArrayTD64_co, other: _ArrayLikeTD64_co) -> _ArrayOrScalar[timedelta64]: ...
+ def __rmod__(self: _ArrayTD64_co, other: _NestedSequence[_SupportsArray[dtype[timedelta64]]]) -> _ArrayOrScalar[timedelta64]: ...
@overload
def __rmod__(self: _ArrayND[object_], other: Any) -> Any: ...
@overload
@@ -1684,7 +1685,7 @@ class ndarray(_ArrayOrScalarCommon, Generic[_ShapeType, _DType_co]):
@overload
def __divmod__(self: _ArrayFloat_co, other: _ArrayLikeFloat_co) -> _2Tuple[_ArrayOrScalar[floating[Any]]]: ... # type: ignore[misc]
@overload
- def __divmod__(self: _ArrayTD64_co, other: _ArrayLikeTD64_co) -> Union[Tuple[int64, timedelta64], Tuple[_ArrayND[int64], _ArrayND[timedelta64]]]: ...
+ def __divmod__(self: _ArrayTD64_co, other: _NestedSequence[_SupportsArray[dtype[timedelta64]]]) -> Union[Tuple[int64, timedelta64], Tuple[_ArrayND[int64], _ArrayND[timedelta64]]]: ...
@overload
def __divmod__(
self: _ArrayND[Union[bool_, integer[Any], floating[Any], timedelta64]],
@@ -1702,7 +1703,7 @@ class ndarray(_ArrayOrScalarCommon, Generic[_ShapeType, _DType_co]):
@overload
def __rdivmod__(self: _ArrayFloat_co, other: _ArrayLikeFloat_co) -> _2Tuple[_ArrayOrScalar[floating[Any]]]: ... # type: ignore[misc]
@overload
- def __rdivmod__(self: _ArrayTD64_co, other: _ArrayLikeTD64_co) -> Union[Tuple[int64, timedelta64], Tuple[_ArrayND[int64], _ArrayND[timedelta64]]]: ...
+ def __rdivmod__(self: _ArrayTD64_co, other: _NestedSequence[_SupportsArray[dtype[timedelta64]]]) -> Union[Tuple[int64, timedelta64], Tuple[_ArrayND[int64], _ArrayND[timedelta64]]]: ...
@overload
def __rdivmod__(
self: _ArrayND[Union[bool_, integer[Any], floating[Any], timedelta64]],
@@ -2202,18 +2203,189 @@ class ndarray(_ArrayOrScalarCommon, Generic[_ShapeType, _DType_co]):
) -> Any: ...
# `np.generic` does not support inplace operations
- def __iadd__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ...
- def __isub__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ...
- def __imul__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ...
- def __itruediv__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ...
- def __ifloordiv__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ...
- def __ipow__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ...
- def __imod__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ...
- def __ilshift__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ...
- def __irshift__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ...
- def __iand__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ...
- def __ixor__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ...
- def __ior__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ...
+ @overload # type: ignore[misc]
+ def __iadd__(self: _ArrayND[Any], other: _NestedSequence[str | bytes]) -> NoReturn: ...
+ @overload
+ def __iadd__(self: _ArrayND[bool_], other: _ArrayLikeBool_co) -> _ArrayND[bool_]: ...
+ @overload
+ def __iadd__(self: _ArrayND[unsignedinteger[_NBit1]], other: _ArrayLikeUInt_co) -> _ArrayND[unsignedinteger[_NBit1]]: ...
+ @overload
+ def __iadd__(self: _ArrayND[signedinteger[_NBit1]], other: _ArrayLikeInt_co) -> _ArrayND[signedinteger[_NBit1]]: ...
+ @overload
+ def __iadd__(self: _ArrayND[floating[_NBit1]], other: _ArrayLikeFloat_co) -> _ArrayND[floating[_NBit1]]: ...
+ @overload
+ def __iadd__(self: _ArrayND[complexfloating[_NBit1, _NBit1]], other: _ArrayLikeComplex_co) -> _ArrayND[complexfloating[_NBit1, _NBit1]]: ...
+ @overload
+ def __iadd__(self: _ArrayND[timedelta64], other: _ArrayLikeTD64_co) -> _ArrayND[timedelta64]: ...
+ @overload
+ def __iadd__(self: _ArrayND[datetime64], other: _ArrayLikeTD64_co) -> _ArrayND[datetime64]: ...
+ @overload
+ def __iadd__(self: _ArrayND[object_], other: Any) -> _ArrayND[object_]: ...
+ @overload
+ def __iadd__(self: _ArrayND[_ScalarType], other: _RecursiveSequence) -> _ArrayND[_ScalarType]: ...
+
+ @overload # type: ignore[misc]
+ def __isub__(self: _ArrayND[Any], other: _NestedSequence[str | bytes]) -> NoReturn: ...
+ @overload
+ def __isub__(self: _ArrayND[unsignedinteger[_NBit1]], other: _ArrayLikeUInt_co) -> _ArrayND[unsignedinteger[_NBit1]]: ...
+ @overload
+ def __isub__(self: _ArrayND[signedinteger[_NBit1]], other: _ArrayLikeInt_co) -> _ArrayND[signedinteger[_NBit1]]: ...
+ @overload
+ def __isub__(self: _ArrayND[floating[_NBit1]], other: _ArrayLikeFloat_co) -> _ArrayND[floating[_NBit1]]: ...
+ @overload
+ def __isub__(self: _ArrayND[complexfloating[_NBit1, _NBit1]], other: _ArrayLikeComplex_co) -> _ArrayND[complexfloating[_NBit1, _NBit1]]: ...
+ @overload
+ def __isub__(self: _ArrayND[timedelta64], other: _ArrayLikeTD64_co) -> _ArrayND[timedelta64]: ...
+ @overload
+ def __isub__(self: _ArrayND[datetime64], other: _ArrayLikeTD64_co) -> _ArrayND[datetime64]: ...
+ @overload
+ def __isub__(self: _ArrayND[object_], other: Any) -> _ArrayND[object_]: ...
+ @overload
+ def __isub__(self: _ArrayND[_ScalarType], other: _RecursiveSequence) -> _ArrayND[_ScalarType]: ...
+
+ @overload # type: ignore[misc]
+ def __imul__(self: _ArrayND[Any], other: _NestedSequence[str | bytes]) -> NoReturn: ...
+ @overload
+ def __imul__(self: _ArrayND[bool_], other: _ArrayLikeBool_co) -> _ArrayND[bool_]: ...
+ @overload
+ def __imul__(self: _ArrayND[unsignedinteger[_NBit1]], other: _ArrayLikeUInt_co) -> _ArrayND[unsignedinteger[_NBit1]]: ...
+ @overload
+ def __imul__(self: _ArrayND[signedinteger[_NBit1]], other: _ArrayLikeInt_co) -> _ArrayND[signedinteger[_NBit1]]: ...
+ @overload
+ def __imul__(self: _ArrayND[floating[_NBit1]], other: _ArrayLikeFloat_co) -> _ArrayND[floating[_NBit1]]: ...
+ @overload
+ def __imul__(self: _ArrayND[complexfloating[_NBit1, _NBit1]], other: _ArrayLikeComplex_co) -> _ArrayND[complexfloating[_NBit1, _NBit1]]: ...
+ @overload
+ def __imul__(self: _ArrayND[timedelta64], other: _ArrayLikeFloat_co) -> _ArrayND[timedelta64]: ...
+ @overload
+ def __imul__(self: _ArrayND[object_], other: Any) -> _ArrayND[object_]: ...
+ @overload
+ def __imul__(self: _ArrayND[_ScalarType], other: _RecursiveSequence) -> _ArrayND[_ScalarType]: ...
+
+ @overload # type: ignore[misc]
+ def __itruediv__(self: _ArrayND[Any], other: _NestedSequence[str | bytes]) -> NoReturn: ...
+ @overload
+ def __itruediv__(self: _ArrayND[floating[_NBit1]], other: _ArrayLikeFloat_co) -> _ArrayND[floating[_NBit1]]: ...
+ @overload
+ def __itruediv__(self: _ArrayND[complexfloating[_NBit1, _NBit1]], other: _ArrayLikeComplex_co) -> _ArrayND[complexfloating[_NBit1, _NBit1]]: ...
+ @overload
+ def __itruediv__(self: _ArrayND[timedelta64], other: _ArrayLikeBool_co) -> NoReturn: ...
+ @overload
+ def __itruediv__(self: _ArrayND[timedelta64], other: _ArrayLikeInt_co) -> _ArrayND[timedelta64]: ...
+ @overload
+ def __itruediv__(self: _ArrayND[object_], other: Any) -> _ArrayND[object_]: ...
+ @overload
+ def __itruediv__(self: _ArrayND[_ScalarType], other: _RecursiveSequence) -> _ArrayND[_ScalarType]: ...
+
+ @overload # type: ignore[misc]
+ def __ifloordiv__(self: _ArrayND[Any], other: _NestedSequence[str | bytes]) -> NoReturn: ...
+ @overload
+ def __ifloordiv__(self: _ArrayND[unsignedinteger[_NBit1]], other: _ArrayLikeUInt_co) -> _ArrayND[unsignedinteger[_NBit1]]: ...
+ @overload
+ def __ifloordiv__(self: _ArrayND[signedinteger[_NBit1]], other: _ArrayLikeInt_co) -> _ArrayND[signedinteger[_NBit1]]: ...
+ @overload
+ def __ifloordiv__(self: _ArrayND[floating[_NBit1]], other: _ArrayLikeFloat_co) -> _ArrayND[floating[_NBit1]]: ...
+ @overload
+ def __ifloordiv__(self: _ArrayND[complexfloating[_NBit1, _NBit1]], other: _ArrayLikeComplex_co) -> _ArrayND[complexfloating[_NBit1, _NBit1]]: ...
+ @overload
+ def __ifloordiv__(self: _ArrayND[timedelta64], other: _ArrayLikeBool_co) -> NoReturn: ...
+ @overload
+ def __ifloordiv__(self: _ArrayND[timedelta64], other: _ArrayLikeInt_co) -> _ArrayND[timedelta64]: ...
+ @overload
+ def __ifloordiv__(self: _ArrayND[object_], other: Any) -> _ArrayND[object_]: ...
+ @overload
+ def __ifloordiv__(self: _ArrayND[_ScalarType], other: _RecursiveSequence) -> _ArrayND[_ScalarType]: ...
+
+ @overload # type: ignore[misc]
+ def __ipow__(self: _ArrayND[Any], other: _NestedSequence[str | bytes]) -> NoReturn: ...
+ @overload
+ def __ipow__(self: _ArrayND[unsignedinteger[_NBit1]], other: _ArrayLikeUInt_co) -> _ArrayND[unsignedinteger[_NBit1]]: ...
+ @overload
+ def __ipow__(self: _ArrayND[signedinteger[_NBit1]], other: _ArrayLikeInt_co) -> _ArrayND[signedinteger[_NBit1]]: ...
+ @overload
+ def __ipow__(self: _ArrayND[floating[_NBit1]], other: _ArrayLikeFloat_co) -> _ArrayND[floating[_NBit1]]: ...
+ @overload
+ def __ipow__(self: _ArrayND[complexfloating[_NBit1, _NBit1]], other: _ArrayLikeComplex_co) -> _ArrayND[complexfloating[_NBit1, _NBit1]]: ...
+ @overload
+ def __ipow__(self: _ArrayND[object_], other: Any) -> _ArrayND[object_]: ...
+ @overload
+ def __ipow__(self: _ArrayND[_ScalarType], other: _RecursiveSequence) -> _ArrayND[_ScalarType]: ...
+
+ @overload # type: ignore[misc]
+ def __imod__(self: _ArrayND[Any], other: _NestedSequence[str | bytes]) -> NoReturn: ...
+ @overload
+ def __imod__(self: _ArrayND[unsignedinteger[_NBit1]], other: _ArrayLikeUInt_co) -> _ArrayND[unsignedinteger[_NBit1]]: ...
+ @overload
+ def __imod__(self: _ArrayND[signedinteger[_NBit1]], other: _ArrayLikeInt_co) -> _ArrayND[signedinteger[_NBit1]]: ...
+ @overload
+ def __imod__(self: _ArrayND[floating[_NBit1]], other: _ArrayLikeFloat_co) -> _ArrayND[floating[_NBit1]]: ...
+ @overload
+ def __imod__(self: _ArrayND[timedelta64], other: _NestedSequence[_SupportsArray[dtype[timedelta64]]]) -> _ArrayND[timedelta64]: ...
+ @overload
+ def __imod__(self: _ArrayND[object_], other: Any) -> _ArrayND[object_]: ...
+ @overload
+ def __imod__(self: _ArrayND[_ScalarType], other: _RecursiveSequence) -> _ArrayND[_ScalarType]: ...
+
+ @overload # type: ignore[misc]
+ def __ilshift__(self: _ArrayND[Any], other: _NestedSequence[str | bytes]) -> NoReturn: ...
+ @overload
+ def __ilshift__(self: _ArrayND[unsignedinteger[_NBit1]], other: _ArrayLikeUInt_co) -> _ArrayND[unsignedinteger[_NBit1]]: ...
+ @overload
+ def __ilshift__(self: _ArrayND[signedinteger[_NBit1]], other: _ArrayLikeInt_co) -> _ArrayND[signedinteger[_NBit1]]: ...
+ @overload
+ def __ilshift__(self: _ArrayND[object_], other: Any) -> _ArrayND[object_]: ...
+ @overload
+ def __ilshift__(self: _ArrayND[_ScalarType], other: _RecursiveSequence) -> _ArrayND[_ScalarType]: ...
+
+ @overload # type: ignore[misc]
+ def __irshift__(self: _ArrayND[Any], other: _NestedSequence[str | bytes]) -> NoReturn: ...
+ @overload
+ def __irshift__(self: _ArrayND[unsignedinteger[_NBit1]], other: _ArrayLikeUInt_co) -> _ArrayND[unsignedinteger[_NBit1]]: ...
+ @overload
+ def __irshift__(self: _ArrayND[signedinteger[_NBit1]], other: _ArrayLikeInt_co) -> _ArrayND[signedinteger[_NBit1]]: ...
+ @overload
+ def __irshift__(self: _ArrayND[object_], other: Any) -> _ArrayND[object_]: ...
+ @overload
+ def __irshift__(self: _ArrayND[_ScalarType], other: _RecursiveSequence) -> _ArrayND[_ScalarType]: ...
+
+ @overload # type: ignore[misc]
+ def __iand__(self: _ArrayND[Any], other: _NestedSequence[str | bytes]) -> NoReturn: ...
+ @overload
+ def __iand__(self: _ArrayND[bool_], other: _ArrayLikeBool_co) -> _ArrayND[bool_]: ...
+ @overload
+ def __iand__(self: _ArrayND[unsignedinteger[_NBit1]], other: _ArrayLikeUInt_co) -> _ArrayND[unsignedinteger[_NBit1]]: ...
+ @overload
+ def __iand__(self: _ArrayND[signedinteger[_NBit1]], other: _ArrayLikeInt_co) -> _ArrayND[signedinteger[_NBit1]]: ...
+ @overload
+ def __iand__(self: _ArrayND[object_], other: Any) -> _ArrayND[object_]: ...
+ @overload
+ def __iand__(self: _ArrayND[_ScalarType], other: _RecursiveSequence) -> _ArrayND[_ScalarType]: ...
+
+ @overload # type: ignore[misc]
+ def __ixor__(self: _ArrayND[Any], other: _NestedSequence[str | bytes]) -> NoReturn: ...
+ @overload
+ def __ixor__(self: _ArrayND[bool_], other: _ArrayLikeBool_co) -> _ArrayND[bool_]: ...
+ @overload
+ def __ixor__(self: _ArrayND[unsignedinteger[_NBit1]], other: _ArrayLikeUInt_co) -> _ArrayND[unsignedinteger[_NBit1]]: ...
+ @overload
+ def __ixor__(self: _ArrayND[signedinteger[_NBit1]], other: _ArrayLikeInt_co) -> _ArrayND[signedinteger[_NBit1]]: ...
+ @overload
+ def __ixor__(self: _ArrayND[object_], other: Any) -> _ArrayND[object_]: ...
+ @overload
+ def __ixor__(self: _ArrayND[_ScalarType], other: _RecursiveSequence) -> _ArrayND[_ScalarType]: ...
+
+ @overload # type: ignore[misc]
+ def __ior__(self: _ArrayND[Any], other: _NestedSequence[str | bytes]) -> NoReturn: ...
+ @overload
+ def __ior__(self: _ArrayND[bool_], other: _ArrayLikeBool_co) -> _ArrayND[bool_]: ...
+ @overload
+ def __ior__(self: _ArrayND[unsignedinteger[_NBit1]], other: _ArrayLikeUInt_co) -> _ArrayND[unsignedinteger[_NBit1]]: ...
+ @overload
+ def __ior__(self: _ArrayND[signedinteger[_NBit1]], other: _ArrayLikeInt_co) -> _ArrayND[signedinteger[_NBit1]]: ...
+ @overload
+ def __ior__(self: _ArrayND[object_], other: Any) -> _ArrayND[object_]: ...
+ @overload
+ def __ior__(self: _ArrayND[_ScalarType], other: _RecursiveSequence) -> _ArrayND[_ScalarType]: ...
# Keep `dtype` at the bottom to avoid name conflicts with `np.dtype`
@property
diff --git a/numpy/typing/tests/data/fail/arithmetic.py b/numpy/typing/tests/data/fail/arithmetic.py
index 1ca8a7b70..02bbffa53 100644
--- a/numpy/typing/tests/data/fail/arithmetic.py
+++ b/numpy/typing/tests/data/fail/arithmetic.py
@@ -61,13 +61,50 @@ AR_m // AR_LIKE_M # E: Unsupported operand types
AR_M // AR_LIKE_M # E: Unsupported operand types
_3 = AR_m // AR_LIKE_b # E: Need type annotation
-AR_m // AR_LIKE_c # E: Unsupported operand types
+AR_m // AR_LIKE_c # E: Unsupported operand types
-AR_b // AR_LIKE_m # E: Unsupported operand types
-AR_u // AR_LIKE_m # E: Unsupported operand types
-AR_i // AR_LIKE_m # E: Unsupported operand types
-AR_f // AR_LIKE_m # E: Unsupported operand types
-AR_c // AR_LIKE_m # E: Unsupported operand types
+AR_b // AR_LIKE_m # E: Unsupported operand types
+AR_u // AR_LIKE_m # E: Unsupported operand types
+AR_i // AR_LIKE_m # E: Unsupported operand types
+AR_f // AR_LIKE_m # E: Unsupported operand types
+AR_c // AR_LIKE_m # E: Unsupported operand types
+
+# Array multiplication
+
+AR_b *= AR_LIKE_u # E: incompatible type
+AR_b *= AR_LIKE_i # E: incompatible type
+AR_b *= AR_LIKE_f # E: incompatible type
+AR_b *= AR_LIKE_c # E: incompatible type
+AR_b *= AR_LIKE_m # E: incompatible type
+
+AR_u *= AR_LIKE_i # E: incompatible type
+AR_u *= AR_LIKE_f # E: incompatible type
+AR_u *= AR_LIKE_c # E: incompatible type
+AR_u *= AR_LIKE_m # E: incompatible type
+
+AR_i *= AR_LIKE_f # E: incompatible type
+AR_i *= AR_LIKE_c # E: incompatible type
+AR_i *= AR_LIKE_m # E: incompatible type
+
+AR_f *= AR_LIKE_c # E: incompatible type
+AR_f *= AR_LIKE_m # E: incompatible type
+
+# Array power
+
+AR_b **= AR_LIKE_b # E: incompatible type
+AR_b **= AR_LIKE_u # E: incompatible type
+AR_b **= AR_LIKE_i # E: incompatible type
+AR_b **= AR_LIKE_f # E: incompatible type
+AR_b **= AR_LIKE_c # E: incompatible type
+
+AR_u **= AR_LIKE_i # E: incompatible type
+AR_u **= AR_LIKE_f # E: incompatible type
+AR_u **= AR_LIKE_c # E: incompatible type
+
+AR_i **= AR_LIKE_f # E: incompatible type
+AR_i **= AR_LIKE_c # E: incompatible type
+
+AR_f **= AR_LIKE_c # E: incompatible type
# Scalars
diff --git a/numpy/typing/tests/data/pass/arithmetic.py b/numpy/typing/tests/data/pass/arithmetic.py
index 86e7a92a8..7a297cfc5 100644
--- a/numpy/typing/tests/data/pass/arithmetic.py
+++ b/numpy/typing/tests/data/pass/arithmetic.py
@@ -42,6 +42,18 @@ class Object:
def __rfloordiv__(self, value: Any) -> Object:
return self
+ def __mul__(self, value: Any) -> Object:
+ return self
+
+ def __rmul__(self, value: Any) -> Object:
+ return self
+
+ def __pow__(self, value: Any) -> Object:
+ return self
+
+ def __rpow__(self, value: Any) -> Object:
+ return self
+
AR_b: np.ndarray[Any, np.dtype[np.bool_]] = np.array([True])
AR_u: np.ndarray[Any, np.dtype[np.uint32]] = np.array([1], dtype=np.uint32)
@@ -267,6 +279,67 @@ AR_LIKE_i // AR_O
AR_LIKE_f // AR_O
AR_LIKE_O // AR_O
+# Inplace multiplication
+
+AR_b *= AR_LIKE_b
+
+AR_u *= AR_LIKE_b
+AR_u *= AR_LIKE_u
+
+AR_i *= AR_LIKE_b
+AR_i *= AR_LIKE_u
+AR_i *= AR_LIKE_i
+
+AR_f *= AR_LIKE_b
+AR_f *= AR_LIKE_u
+AR_f *= AR_LIKE_i
+AR_f *= AR_LIKE_f
+
+AR_c *= AR_LIKE_b
+AR_c *= AR_LIKE_u
+AR_c *= AR_LIKE_i
+AR_c *= AR_LIKE_f
+AR_c *= AR_LIKE_c
+
+AR_m *= AR_LIKE_b
+AR_m *= AR_LIKE_u
+AR_m *= AR_LIKE_i
+AR_m *= AR_LIKE_f
+
+AR_O *= AR_LIKE_b
+AR_O *= AR_LIKE_u
+AR_O *= AR_LIKE_i
+AR_O *= AR_LIKE_f
+AR_O *= AR_LIKE_c
+AR_O *= AR_LIKE_O
+
+# Inplace power
+
+AR_u **= AR_LIKE_b
+AR_u **= AR_LIKE_u
+
+AR_i **= AR_LIKE_b
+AR_i **= AR_LIKE_u
+AR_i **= AR_LIKE_i
+
+AR_f **= AR_LIKE_b
+AR_f **= AR_LIKE_u
+AR_f **= AR_LIKE_i
+AR_f **= AR_LIKE_f
+
+AR_c **= AR_LIKE_b
+AR_c **= AR_LIKE_u
+AR_c **= AR_LIKE_i
+AR_c **= AR_LIKE_f
+AR_c **= AR_LIKE_c
+
+AR_O **= AR_LIKE_b
+AR_O **= AR_LIKE_u
+AR_O **= AR_LIKE_i
+AR_O **= AR_LIKE_f
+AR_O **= AR_LIKE_c
+AR_O **= AR_LIKE_O
+
# unary ops
-c16
diff --git a/numpy/typing/tests/test_typing.py b/numpy/typing/tests/test_typing.py
index 70355dcd9..be08c1359 100644
--- a/numpy/typing/tests/test_typing.py
+++ b/numpy/typing/tests/test_typing.py
@@ -40,6 +40,12 @@ def _key_func(key: str) -> str:
return os.path.join(drive, tail.split(":", 1)[0])
+def _strip_filename(msg: str) -> str:
+ """Strip the filename from a mypy message."""
+ _, tail = os.path.splitdrive(msg)
+ return tail.split(":", 1)[-1]
+
+
@pytest.mark.slow
@pytest.mark.skipif(NO_MYPY, reason="Mypy is not installed")
@pytest.fixture(scope="module", autouse=True)
@@ -57,14 +63,17 @@ def run_mypy() -> None:
for directory in (PASS_DIR, REVEAL_DIR, FAIL_DIR, MISC_DIR):
# Run mypy
- stdout, stderr, _ = api.run([
+ stdout, stderr, exit_code = api.run([
"--config-file",
MYPY_INI,
"--cache-dir",
CACHE_DIR,
directory,
])
- assert not stderr, directory
+ if stderr:
+ pytest.fail(f"Unexpected mypy standard error\n\n{stderr}")
+ elif exit_code not in {0, 1}:
+ pytest.fail(f"Unexpected mypy exit code: {exit_code}\n\n{stdout}")
stdout = stdout.replace('*', '')
# Parse the output
@@ -94,7 +103,9 @@ def test_success(path):
# Alias `OUTPUT_MYPY` so that it appears in the local namespace
output_mypy = OUTPUT_MYPY
if path in output_mypy:
- raise AssertionError("\n".join(v for v in output_mypy[path]))
+ msg = "Unexpected mypy output\n\n"
+ msg += "\n".join(_strip_filename(v) for v in output_mypy[path])
+ raise AssertionError(msg)
@pytest.mark.slow
@@ -111,14 +122,15 @@ def test_fail(path):
output_mypy = OUTPUT_MYPY
assert path in output_mypy
for error_line in output_mypy[path]:
+ error_line = _strip_filename(error_line)
match = re.match(
- r"^.+\.py:(?P<lineno>\d+): (error|note): .+$",
+ r"(?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
+ errors[lineno] += f'{error_line}\n'
for i, line in enumerate(lines):
lineno = i + 1
@@ -131,7 +143,7 @@ def test_fail(path):
expected_error = errors.get(lineno)
_test_fail(path, marker, expected_error, lineno)
else:
- pytest.fail(f"Error {repr(errors[lineno])} not found")
+ pytest.fail(f"Unexpected mypy output\n\n{errors[lineno]}")
_FAIL_MSG1 = """Extra error at line {}
@@ -250,8 +262,9 @@ def test_reveal(path):
output_mypy = OUTPUT_MYPY
assert path in output_mypy
for error_line in output_mypy[path]:
+ error_line = _strip_filename(error_line)
match = re.match(
- r"^.+\.py:(?P<lineno>\d+): note: .+$",
+ r"(?P<lineno>\d+): note: .+$",
error_line,
)
if match is None:
@@ -311,6 +324,8 @@ def test_extended_precision() -> None:
for _msg in output_mypy[path]:
*_, _lineno, msg_typ, msg = _msg.split(":")
+
+ msg = _strip_filename(msg)
lineno = int(_lineno)
msg_typ = msg_typ.strip()
assert msg_typ in {"error", "note"}