From e562ac3f01dfba259f70d7adab116d0e3009d3bb Mon Sep 17 00:00:00 2001 From: Marco Gorelli <33491632+MarcoGorelli@users.noreply.github.com> Date: Tue, 15 Jul 2025 18:31:53 +0100 Subject: [PATCH 1/6] TYP: Type ``MaskedArray.view`` --- numpy/__init__.pyi | 2 +- numpy/ma/core.pyi | 20 +++++++++++++++++++- numpy/typing/tests/data/reveal/ma.pyi | 9 +++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/numpy/__init__.pyi b/numpy/__init__.pyi index d8c57c87cbbe..908a839e9a76 100644 --- a/numpy/__init__.pyi +++ b/numpy/__init__.pyi @@ -2569,7 +2569,7 @@ class ndarray(_ArrayOrScalarCommon, Generic[_ShapeT_co, _DTypeT_co]): copy: builtins.bool | _CopyMode = ..., ) -> ndarray[_ShapeT_co, dtype]: ... - # + # Keep in sync with `MaskedArray.view` @overload # () def view(self, /) -> Self: ... @overload # (dtype: T) diff --git a/numpy/ma/core.pyi b/numpy/ma/core.pyi index 63dea396de66..f65b513f2551 100644 --- a/numpy/ma/core.pyi +++ b/numpy/ma/core.pyi @@ -8,6 +8,7 @@ from typing_extensions import TypeIs, TypeVar import numpy as np from numpy import ( + _HasDType, _HasDTypeWithRealAndImag, _ModeKind, _OrderKACF, @@ -67,6 +68,7 @@ from numpy._typing import ( _ArrayLikeString_co, _ArrayLikeTD64_co, _ArrayLikeUInt_co, + _DTypeLike, _DTypeLikeBool, _IntLike_co, _ScalarLike_co, @@ -444,7 +446,23 @@ class MaskedArray(ndarray[_ShapeT_co, _DTypeT_co]): def __new__(cls, data=..., mask=..., dtype=..., copy=..., subok=..., ndmin=..., fill_value=..., keep_mask=..., hard_mask=..., shrink=..., order=...): ... def __array_finalize__(self, obj): ... def __array_wrap__(self, obj, context=..., return_scalar=...): ... - def view(self, dtype=..., type=..., fill_value=...): ... + + # Keep in sync with `ndarray.view` (but with extra `fill_value`) + @overload # () + def view(self, /) -> Self: ... + @overload # (dtype: T) + def view(self, /, dtype: _DTypeT | _HasDType[_DTypeT], fill_value: _ScalarLike_co | None = None) -> MaskedArray[_ShapeT_co, _DTypeT]: ... + @overload # (dtype: dtype[T]) + def view(self, /, dtype: _DTypeLike[_ScalarT], fill_value: _ScalarLike_co | None = None) -> _MaskedArray[_ScalarT]: ... + @overload # (type: T) + def view(self, /, *, type: type[_ArrayT], fill_value: _ScalarLike_co | None = None) -> _ArrayT: ... + @overload # (_: T) + def view(self, /, dtype: type[_ArrayT], fill_value: _ScalarLike_co | None = None) -> _ArrayT: ... + @overload # (dtype: ?) + def view(self, /, dtype: DTypeLike, fill_value: _ScalarLike_co | None = None) -> MaskedArray[_ShapeT_co, dtype]: ... + @overload # (dtype: ?, type: type[T]) + def view(self, /, dtype: DTypeLike, type: type[_ArrayT], fill_value: _ScalarLike_co | None = None) -> _ArrayT: ... + def __getitem__(self, indx): ... def __setitem__(self, indx, value): ... @property diff --git a/numpy/typing/tests/data/reveal/ma.pyi b/numpy/typing/tests/data/reveal/ma.pyi index 7c2cb9d5f05e..8da5ef3d0e67 100644 --- a/numpy/typing/tests/data/reveal/ma.pyi +++ b/numpy/typing/tests/data/reveal/ma.pyi @@ -405,6 +405,15 @@ assert_type(MAR_f8.cumprod(out=MAR_subclass), MaskedArraySubclass) assert_type(MAR_f8.cumsum(), MaskedArray[Any]) assert_type(MAR_f8.cumsum(out=MAR_subclass), MaskedArraySubclass) +assert_type(MAR_f8.view(), MaskedArray[np.float64]) +assert_type(MAR_f8.view(dtype=np.float32), MaskedArray[np.float32]) +assert_type(MAR_f8.view(dtype=np.dtype(np.float32)), MaskedArray[np.float32]) +assert_type(MAR_f8.view(dtype=np.float32, fill_value=0), MaskedArray[np.float32]) +assert_type(MAR_f8.view(type=np.ndarray), np.ndarray[Any, Any]) +assert_type(MAR_f8.view(dtype=np.ndarray), np.ndarray[Any, Any]) +assert_type(MAR_f8.view(dtype='float32'), MaskedArray[Any]) +assert_type(MAR_f8.view(dtype='float32', type=np.ndarray), np.ndarray[Any, Any]) + # Masked Array addition assert_type(MAR_b + AR_LIKE_u, MaskedArray[np.uint32]) From d3b578d813a9b923dd2e28c685e62c2ed9610171 Mon Sep 17 00:00:00 2001 From: Marco Gorelli <33491632+MarcoGorelli@users.noreply.github.com> Date: Tue, 15 Jul 2025 19:20:05 +0100 Subject: [PATCH 2/6] preserve shape while we are at it --- numpy/__init__.pyi | 2 +- numpy/ma/core.pyi | 2 +- numpy/typing/tests/data/reveal/ma.pyi | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/numpy/__init__.pyi b/numpy/__init__.pyi index 908a839e9a76..11d5ab814b7c 100644 --- a/numpy/__init__.pyi +++ b/numpy/__init__.pyi @@ -2575,7 +2575,7 @@ class ndarray(_ArrayOrScalarCommon, Generic[_ShapeT_co, _DTypeT_co]): @overload # (dtype: T) def view(self, /, dtype: _DTypeT | _HasDType[_DTypeT]) -> ndarray[_ShapeT_co, _DTypeT]: ... @overload # (dtype: dtype[T]) - def view(self, /, dtype: _DTypeLike[_ScalarT]) -> NDArray[_ScalarT]: ... + def view(self, /, dtype: _DTypeLike[_ScalarT]) -> ndarray[_ShapeT_co, dtype[_ScalarT]]: ... @overload # (type: T) def view(self, /, *, type: type[_ArrayT]) -> _ArrayT: ... @overload # (_: T) diff --git a/numpy/ma/core.pyi b/numpy/ma/core.pyi index f65b513f2551..b8e0974b85e5 100644 --- a/numpy/ma/core.pyi +++ b/numpy/ma/core.pyi @@ -453,7 +453,7 @@ class MaskedArray(ndarray[_ShapeT_co, _DTypeT_co]): @overload # (dtype: T) def view(self, /, dtype: _DTypeT | _HasDType[_DTypeT], fill_value: _ScalarLike_co | None = None) -> MaskedArray[_ShapeT_co, _DTypeT]: ... @overload # (dtype: dtype[T]) - def view(self, /, dtype: _DTypeLike[_ScalarT], fill_value: _ScalarLike_co | None = None) -> _MaskedArray[_ScalarT]: ... + def view(self, /, dtype: _DTypeLike[_ScalarT], fill_value: _ScalarLike_co | None = None) -> MaskedArray[_ShapeT_co, dtype[_ScalarT]]: ... @overload # (type: T) def view(self, /, *, type: type[_ArrayT], fill_value: _ScalarLike_co | None = None) -> _ArrayT: ... @overload # (_: T) diff --git a/numpy/typing/tests/data/reveal/ma.pyi b/numpy/typing/tests/data/reveal/ma.pyi index 8da5ef3d0e67..1cbefc47899c 100644 --- a/numpy/typing/tests/data/reveal/ma.pyi +++ b/numpy/typing/tests/data/reveal/ma.pyi @@ -413,6 +413,8 @@ assert_type(MAR_f8.view(type=np.ndarray), np.ndarray[Any, Any]) assert_type(MAR_f8.view(dtype=np.ndarray), np.ndarray[Any, Any]) assert_type(MAR_f8.view(dtype='float32'), MaskedArray[Any]) assert_type(MAR_f8.view(dtype='float32', type=np.ndarray), np.ndarray[Any, Any]) +assert_type(MAR_2d_f4.view(dtype=np.float16), np.ma.MaskedArray[tuple[int, int], np.dtype[np.float16]]) +assert_type(MAR_2d_f4.view(dtype=np.dtype(np.float16)), np.ma.MaskedArray[tuple[int, int], np.dtype[np.float16]]) # Masked Array addition From bd6793f320dc3b557b8dee9c9c3a32f0637b73c3 Mon Sep 17 00:00:00 2001 From: Marco Gorelli <33491632+MarcoGorelli@users.noreply.github.com> Date: Wed, 16 Jul 2025 11:29:43 +0100 Subject: [PATCH 3/6] include all args in overloads --- numpy/__init__.pyi | 1 - numpy/ma/core.pyi | 23 ++++++++++++----------- numpy/typing/tests/data/reveal/ma.pyi | 1 + 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/numpy/__init__.pyi b/numpy/__init__.pyi index 11d5ab814b7c..9811bc851194 100644 --- a/numpy/__init__.pyi +++ b/numpy/__init__.pyi @@ -2569,7 +2569,6 @@ class ndarray(_ArrayOrScalarCommon, Generic[_ShapeT_co, _DTypeT_co]): copy: builtins.bool | _CopyMode = ..., ) -> ndarray[_ShapeT_co, dtype]: ... - # Keep in sync with `MaskedArray.view` @overload # () def view(self, /) -> Self: ... @overload # (dtype: T) diff --git a/numpy/ma/core.pyi b/numpy/ma/core.pyi index b8e0974b85e5..473585d20609 100644 --- a/numpy/ma/core.pyi +++ b/numpy/ma/core.pyi @@ -447,19 +447,20 @@ class MaskedArray(ndarray[_ShapeT_co, _DTypeT_co]): def __array_finalize__(self, obj): ... def __array_wrap__(self, obj, context=..., return_scalar=...): ... - # Keep in sync with `ndarray.view` (but with extra `fill_value`) @overload # () - def view(self, /) -> Self: ... - @overload # (dtype: T) - def view(self, /, dtype: _DTypeT | _HasDType[_DTypeT], fill_value: _ScalarLike_co | None = None) -> MaskedArray[_ShapeT_co, _DTypeT]: ... - @overload # (dtype: dtype[T]) - def view(self, /, dtype: _DTypeLike[_ScalarT], fill_value: _ScalarLike_co | None = None) -> MaskedArray[_ShapeT_co, dtype[_ScalarT]]: ... - @overload # (type: T) - def view(self, /, *, type: type[_ArrayT], fill_value: _ScalarLike_co | None = None) -> _ArrayT: ... - @overload # (_: T) - def view(self, /, dtype: type[_ArrayT], fill_value: _ScalarLike_co | None = None) -> _ArrayT: ... + def view(self, /, dtype: None = None, type: None = None, fill_value: _ScalarLike_co | None = None) -> Self: ... + @overload # (dtype: DTypeT) + def view(self, /, dtype: _DTypeT | _HasDType[_DTypeT], type: None = None, fill_value: _ScalarLike_co | None = None) -> MaskedArray[_ShapeT_co, _DTypeT]: ... + @overload # (dtype: dtype[ScalarT]) + def view(self, /, dtype: _DTypeLike[_ScalarT], type: None = None, fill_value: _ScalarLike_co | None = None) -> MaskedArray[_ShapeT_co, dtype[_ScalarT]]: ... + @overload # ([dtype: _, ]*, type: ArrayT) + def view(self, /, dtype: DTypeLike | None = None, *, type: type[_ArrayT], fill_value: _ScalarLike_co | None = None) -> _ArrayT: ... + @overload # (dtype: _, type: ArrayT) + def view(self, /, dtype: DTypeLike | None, type: type[_ArrayT], fill_value: _ScalarLike_co | None = None) -> _ArrayT: ... + @overload # (dtype: ArrayT, /) + def view(self, /, dtype: type[_ArrayT], type: None = None, fill_value: _ScalarLike_co | None = None) -> _ArrayT: ... @overload # (dtype: ?) - def view(self, /, dtype: DTypeLike, fill_value: _ScalarLike_co | None = None) -> MaskedArray[_ShapeT_co, dtype]: ... + def view(self, /, dtype: DTypeLike, type: None = None, fill_value: _ScalarLike_co | None = None) -> MaskedArray[_ShapeT_co, dtype]: ... @overload # (dtype: ?, type: type[T]) def view(self, /, dtype: DTypeLike, type: type[_ArrayT], fill_value: _ScalarLike_co | None = None) -> _ArrayT: ... diff --git a/numpy/typing/tests/data/reveal/ma.pyi b/numpy/typing/tests/data/reveal/ma.pyi index 1cbefc47899c..8bd24879dcc3 100644 --- a/numpy/typing/tests/data/reveal/ma.pyi +++ b/numpy/typing/tests/data/reveal/ma.pyi @@ -410,6 +410,7 @@ assert_type(MAR_f8.view(dtype=np.float32), MaskedArray[np.float32]) assert_type(MAR_f8.view(dtype=np.dtype(np.float32)), MaskedArray[np.float32]) assert_type(MAR_f8.view(dtype=np.float32, fill_value=0), MaskedArray[np.float32]) assert_type(MAR_f8.view(type=np.ndarray), np.ndarray[Any, Any]) +assert_type(MAR_f8.view(None, np.ndarray), np.ndarray[Any, Any]) assert_type(MAR_f8.view(dtype=np.ndarray), np.ndarray[Any, Any]) assert_type(MAR_f8.view(dtype='float32'), MaskedArray[Any]) assert_type(MAR_f8.view(dtype='float32', type=np.ndarray), np.ndarray[Any, Any]) From b57696215413c5a3e416d5890027c52fa76841fb Mon Sep 17 00:00:00 2001 From: Marco Gorelli <33491632+MarcoGorelli@users.noreply.github.com> Date: Mon, 21 Jul 2025 18:53:29 +0100 Subject: [PATCH 4/6] reduce diff --- numpy/__init__.pyi | 1 + 1 file changed, 1 insertion(+) diff --git a/numpy/__init__.pyi b/numpy/__init__.pyi index 9811bc851194..089c5cb7f21c 100644 --- a/numpy/__init__.pyi +++ b/numpy/__init__.pyi @@ -2569,6 +2569,7 @@ class ndarray(_ArrayOrScalarCommon, Generic[_ShapeT_co, _DTypeT_co]): copy: builtins.bool | _CopyMode = ..., ) -> ndarray[_ShapeT_co, dtype]: ... + # @overload # () def view(self, /) -> Self: ... @overload # (dtype: T) From 716cc725038d006d69e3dadf40025bbed862846d Mon Sep 17 00:00:00 2001 From: Marco Gorelli <33491632+MarcoGorelli@users.noreply.github.com> Date: Mon, 21 Jul 2025 18:55:06 +0100 Subject: [PATCH 5/6] comment consistency --- numpy/__init__.pyi | 2 +- numpy/ma/core.pyi | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/numpy/__init__.pyi b/numpy/__init__.pyi index 089c5cb7f21c..4521d78b23e8 100644 --- a/numpy/__init__.pyi +++ b/numpy/__init__.pyi @@ -2582,7 +2582,7 @@ class ndarray(_ArrayOrScalarCommon, Generic[_ShapeT_co, _DTypeT_co]): def view(self, /, dtype: type[_ArrayT]) -> _ArrayT: ... @overload # (dtype: ?) def view(self, /, dtype: DTypeLike) -> ndarray[_ShapeT_co, dtype]: ... - @overload # (dtype: ?, type: type[T]) + @overload # (dtype: ?, type: T) def view(self, /, dtype: DTypeLike, type: type[_ArrayT]) -> _ArrayT: ... def setfield(self, /, val: ArrayLike, dtype: DTypeLike, offset: SupportsIndex = 0) -> None: ... diff --git a/numpy/ma/core.pyi b/numpy/ma/core.pyi index 093da95abbf1..e6e4b0b447c3 100644 --- a/numpy/ma/core.pyi +++ b/numpy/ma/core.pyi @@ -461,7 +461,7 @@ class MaskedArray(ndarray[_ShapeT_co, _DTypeT_co]): def view(self, /, dtype: type[_ArrayT], type: None = None, fill_value: _ScalarLike_co | None = None) -> _ArrayT: ... @overload # (dtype: ?) def view(self, /, dtype: DTypeLike, type: None = None, fill_value: _ScalarLike_co | None = None) -> MaskedArray[_ShapeT_co, dtype]: ... - @overload # (dtype: ?, type: type[T]) + @overload # (dtype: ?, type: ArrayT) def view(self, /, dtype: DTypeLike, type: type[_ArrayT], fill_value: _ScalarLike_co | None = None) -> _ArrayT: ... def __getitem__(self, indx): ... From dbb94cec4dcad66039d06c10d18b0b92afab231a Mon Sep 17 00:00:00 2001 From: Marco Gorelli <33491632+MarcoGorelli@users.noreply.github.com> Date: Tue, 22 Jul 2025 16:24:09 +0100 Subject: [PATCH 6/6] avoid overload overlap --- numpy/ma/core.pyi | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/numpy/ma/core.pyi b/numpy/ma/core.pyi index e6e4b0b447c3..0aa214eaa4f8 100644 --- a/numpy/ma/core.pyi +++ b/numpy/ma/core.pyi @@ -75,6 +75,7 @@ from numpy._typing import ( _Shape, _ShapeLike, ) +from numpy._typing._dtype_like import _VoidDTypeLike __all__ = [ "MAError", @@ -450,19 +451,44 @@ class MaskedArray(ndarray[_ShapeT_co, _DTypeT_co]): @overload # () def view(self, /, dtype: None = None, type: None = None, fill_value: _ScalarLike_co | None = None) -> Self: ... @overload # (dtype: DTypeT) - def view(self, /, dtype: _DTypeT | _HasDType[_DTypeT], type: None = None, fill_value: _ScalarLike_co | None = None) -> MaskedArray[_ShapeT_co, _DTypeT]: ... + def view( + self, + /, + dtype: _DTypeT | _HasDType[_DTypeT], + type: None = None, + fill_value: _ScalarLike_co | None = None + ) -> MaskedArray[_ShapeT_co, _DTypeT]: ... @overload # (dtype: dtype[ScalarT]) - def view(self, /, dtype: _DTypeLike[_ScalarT], type: None = None, fill_value: _ScalarLike_co | None = None) -> MaskedArray[_ShapeT_co, dtype[_ScalarT]]: ... + def view( + self, + /, + dtype: _DTypeLike[_ScalarT], + type: None = None, + fill_value: _ScalarLike_co | None = None + ) -> MaskedArray[_ShapeT_co, dtype[_ScalarT]]: ... @overload # ([dtype: _, ]*, type: ArrayT) - def view(self, /, dtype: DTypeLike | None = None, *, type: type[_ArrayT], fill_value: _ScalarLike_co | None = None) -> _ArrayT: ... + def view( + self, + /, + dtype: DTypeLike | None = None, + *, + type: type[_ArrayT], + fill_value: _ScalarLike_co | None = None + ) -> _ArrayT: ... @overload # (dtype: _, type: ArrayT) def view(self, /, dtype: DTypeLike | None, type: type[_ArrayT], fill_value: _ScalarLike_co | None = None) -> _ArrayT: ... @overload # (dtype: ArrayT, /) def view(self, /, dtype: type[_ArrayT], type: None = None, fill_value: _ScalarLike_co | None = None) -> _ArrayT: ... @overload # (dtype: ?) - def view(self, /, dtype: DTypeLike, type: None = None, fill_value: _ScalarLike_co | None = None) -> MaskedArray[_ShapeT_co, dtype]: ... - @overload # (dtype: ?, type: ArrayT) - def view(self, /, dtype: DTypeLike, type: type[_ArrayT], fill_value: _ScalarLike_co | None = None) -> _ArrayT: ... + def view( + self, + /, + # `_VoidDTypeLike | str | None` is like `DTypeLike` but without `_DTypeLike[Any]` to avoid + # overlaps with previous overloads. + dtype: _VoidDTypeLike | str | None, + type: None = None, + fill_value: _ScalarLike_co | None = None + ) -> MaskedArray[_ShapeT_co, dtype]: ... def __getitem__(self, indx): ... def __setitem__(self, indx, value): ...
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: