From 5a5b6504368e35b0fbd399bad79c7385e4e6d10a Mon Sep 17 00:00:00 2001 From: iantra Date: Thu, 1 Sep 2022 15:30:45 +0200 Subject: [PATCH 1/2] BUG: change overload order to play nice with pyright. Pyright just chooses the first matching type whenever there is ambiguity in type resolution, which leads to NoReturn for the cross function in certain situations. Other overloads were changed to match. See ticket #22146 --- numpy/core/numeric.pyi | 54 +++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/numpy/core/numeric.pyi b/numpy/core/numeric.pyi index d09144f90fe1..ed2b03ab4bf4 100644 --- a/numpy/core/numeric.pyi +++ b/numpy/core/numeric.pyi @@ -255,6 +255,12 @@ def argwhere(a: ArrayLike) -> NDArray[intp]: ... def flatnonzero(a: ArrayLike) -> NDArray[intp]: ... +@overload +def correlate( + a: _ArrayLikeObject_co, + v: _ArrayLikeObject_co, + mode: _CorrelateMode = ..., +) -> NDArray[object_]: ... @overload def correlate( a: _ArrayLikeBool_co, @@ -291,13 +297,13 @@ def correlate( v: _ArrayLikeTD64_co, mode: _CorrelateMode = ..., ) -> NDArray[timedelta64]: ... + @overload -def correlate( +def convolve( a: _ArrayLikeObject_co, v: _ArrayLikeObject_co, mode: _CorrelateMode = ..., ) -> NDArray[object_]: ... - @overload def convolve( a: _ArrayLikeBool_co, @@ -334,13 +340,13 @@ def convolve( v: _ArrayLikeTD64_co, mode: _CorrelateMode = ..., ) -> NDArray[timedelta64]: ... + @overload -def convolve( +def outer( a: _ArrayLikeObject_co, - v: _ArrayLikeObject_co, - mode: _CorrelateMode = ..., + b: _ArrayLikeObject_co, + out: None = ..., ) -> NDArray[object_]: ... - @overload def outer( a: _ArrayLikeBool_co, @@ -378,18 +384,18 @@ def outer( out: None = ..., ) -> NDArray[timedelta64]: ... @overload -def outer( - a: _ArrayLikeObject_co, - b: _ArrayLikeObject_co, - out: None = ..., -) -> NDArray[object_]: ... -@overload def outer( a: _ArrayLikeComplex_co | _ArrayLikeTD64_co | _ArrayLikeObject_co, b: _ArrayLikeComplex_co | _ArrayLikeTD64_co | _ArrayLikeObject_co, out: _ArrayType, ) -> _ArrayType: ... +@overload +def tensordot( + a: _ArrayLikeObject_co, + b: _ArrayLikeObject_co, + axes: int | tuple[_ShapeLike, _ShapeLike] = ..., +) -> NDArray[object_]: ... @overload def tensordot( a: _ArrayLikeBool_co, @@ -426,12 +432,6 @@ def tensordot( b: _ArrayLikeTD64_co, axes: int | tuple[_ShapeLike, _ShapeLike] = ..., ) -> NDArray[timedelta64]: ... -@overload -def tensordot( - a: _ArrayLikeObject_co, - b: _ArrayLikeObject_co, - axes: int | tuple[_ShapeLike, _ShapeLike] = ..., -) -> NDArray[object_]: ... @overload def roll( @@ -458,6 +458,15 @@ def moveaxis( destination: _ShapeLike, ) -> NDArray[_SCT]: ... +@overload +def cross( + a: _ArrayLikeObject_co, + b: _ArrayLikeObject_co, + axisa: int = ..., + axisb: int = ..., + axisc: int = ..., + axis: None | int = ..., +) -> NDArray[object_]: ... @overload def cross( a: _ArrayLikeBool_co, @@ -503,15 +512,6 @@ def cross( axisc: int = ..., axis: None | int = ..., ) -> NDArray[complexfloating[Any, Any]]: ... -@overload -def cross( - a: _ArrayLikeObject_co, - b: _ArrayLikeObject_co, - axisa: int = ..., - axisb: int = ..., - axisc: int = ..., - axis: None | int = ..., -) -> NDArray[object_]: ... @overload def indices( From 336f3a48490629c93904ad15c7a545177737bed3 Mon Sep 17 00:00:00 2001 From: iantra Date: Mon, 5 Sep 2022 14:32:34 +0200 Subject: [PATCH 2/2] BUG: Introduce Unknown array type to deal with NDArray[Any] more gracefully. --- numpy/_typing/__init__.py | 1 + numpy/_typing/_array_like.py | 13 ++++++++ numpy/core/numeric.pyi | 62 ++++++++++++++++++++++++++++-------- 3 files changed, 62 insertions(+), 14 deletions(-) diff --git a/numpy/_typing/__init__.py b/numpy/_typing/__init__.py index 37ed06871dfa..76b806c7f7b5 100644 --- a/numpy/_typing/__init__.py +++ b/numpy/_typing/__init__.py @@ -198,6 +198,7 @@ class _8Bit(_16Bit): # type: ignore[misc] _ArrayLikeVoid_co as _ArrayLikeVoid_co, _ArrayLikeStr_co as _ArrayLikeStr_co, _ArrayLikeBytes_co as _ArrayLikeBytes_co, + _ArrayLikeUnknown as _ArrayLikeUnknown, ) from ._generic_alias import ( NDArray as NDArray, diff --git a/numpy/_typing/_array_like.py b/numpy/_typing/_array_like.py index 02f2642226ac..2e5684b0bfb6 100644 --- a/numpy/_typing/_array_like.py +++ b/numpy/_typing/_array_like.py @@ -141,3 +141,16 @@ def __array_function__( "dtype[integer[Any]]", int, ] + +# Extra ArrayLike type so that pyright can deal with NDArray[Any] +# Used as the first overload, should only match NDArray[Any], +# not any actual types. +# https://github.com/numpy/numpy/pull/22193 +class _UnknownType: + ... + + +_ArrayLikeUnknown = _DualArrayLike[ + "dtype[_UnknownType]", + _UnknownType, +] diff --git a/numpy/core/numeric.pyi b/numpy/core/numeric.pyi index ed2b03ab4bf4..98d3789a579e 100644 --- a/numpy/core/numeric.pyi +++ b/numpy/core/numeric.pyi @@ -43,6 +43,7 @@ from numpy._typing import ( _ArrayLikeComplex_co, _ArrayLikeTD64_co, _ArrayLikeObject_co, + _ArrayLikeUnknown, ) _T = TypeVar("_T") @@ -257,10 +258,10 @@ def flatnonzero(a: ArrayLike) -> NDArray[intp]: ... @overload def correlate( - a: _ArrayLikeObject_co, - v: _ArrayLikeObject_co, + a: _ArrayLikeUnknown, + v: _ArrayLikeUnknown, mode: _CorrelateMode = ..., -) -> NDArray[object_]: ... +) -> NDArray[Any]: ... @overload def correlate( a: _ArrayLikeBool_co, @@ -297,13 +298,19 @@ def correlate( v: _ArrayLikeTD64_co, mode: _CorrelateMode = ..., ) -> NDArray[timedelta64]: ... - @overload -def convolve( +def correlate( a: _ArrayLikeObject_co, v: _ArrayLikeObject_co, mode: _CorrelateMode = ..., ) -> NDArray[object_]: ... + +@overload +def convolve( + a: _ArrayLikeUnknown, + v: _ArrayLikeUnknown, + mode: _CorrelateMode = ..., +) -> NDArray[Any]: ... @overload def convolve( a: _ArrayLikeBool_co, @@ -340,13 +347,19 @@ def convolve( v: _ArrayLikeTD64_co, mode: _CorrelateMode = ..., ) -> NDArray[timedelta64]: ... +@overload +def convolve( + a: _ArrayLikeObject_co, + v: _ArrayLikeObject_co, + mode: _CorrelateMode = ..., +) -> NDArray[object_]: ... @overload def outer( - a: _ArrayLikeObject_co, - b: _ArrayLikeObject_co, + a: _ArrayLikeUnknown, + b: _ArrayLikeUnknown, out: None = ..., -) -> NDArray[object_]: ... +) -> NDArray[Any]: ... @overload def outer( a: _ArrayLikeBool_co, @@ -384,6 +397,12 @@ def outer( out: None = ..., ) -> NDArray[timedelta64]: ... @overload +def outer( + a: _ArrayLikeObject_co, + b: _ArrayLikeObject_co, + out: None = ..., +) -> NDArray[object_]: ... +@overload def outer( a: _ArrayLikeComplex_co | _ArrayLikeTD64_co | _ArrayLikeObject_co, b: _ArrayLikeComplex_co | _ArrayLikeTD64_co | _ArrayLikeObject_co, @@ -392,10 +411,10 @@ def outer( @overload def tensordot( - a: _ArrayLikeObject_co, - b: _ArrayLikeObject_co, + a: _ArrayLikeUnknown, + b: _ArrayLikeUnknown, axes: int | tuple[_ShapeLike, _ShapeLike] = ..., -) -> NDArray[object_]: ... +) -> NDArray[Any]: ... @overload def tensordot( a: _ArrayLikeBool_co, @@ -432,6 +451,12 @@ def tensordot( b: _ArrayLikeTD64_co, axes: int | tuple[_ShapeLike, _ShapeLike] = ..., ) -> NDArray[timedelta64]: ... +@overload +def tensordot( + a: _ArrayLikeObject_co, + b: _ArrayLikeObject_co, + axes: int | tuple[_ShapeLike, _ShapeLike] = ..., +) -> NDArray[object_]: ... @overload def roll( @@ -460,13 +485,13 @@ def moveaxis( @overload def cross( - a: _ArrayLikeObject_co, - b: _ArrayLikeObject_co, + a: _ArrayLikeUnknown, + b: _ArrayLikeUnknown, axisa: int = ..., axisb: int = ..., axisc: int = ..., axis: None | int = ..., -) -> NDArray[object_]: ... +) -> NDArray[Any]: ... @overload def cross( a: _ArrayLikeBool_co, @@ -512,6 +537,15 @@ def cross( axisc: int = ..., axis: None | int = ..., ) -> NDArray[complexfloating[Any, Any]]: ... +@overload +def cross( + a: _ArrayLikeObject_co, + b: _ArrayLikeObject_co, + axisa: int = ..., + axisb: int = ..., + axisc: int = ..., + axis: None | int = ..., +) -> NDArray[object_]: ... @overload def indices(