Repository: numpy/numpy
File: numpy/ma/core.pyi (Python)

Code before:
    def __init__(self, ma): ...
    def __iter__(self): ...
    def __getitem__(self, indx): ...
    def __setitem__(self, index, value): ...
    def __next__(self): ...

class MaskedArray(ndarray[_ShapeT_co, _DTypeT_co]):
    __array_priority__: Any
    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=...): ...

    @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]: ...
    @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, 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 __getitem__(self, indx): ...
    def __setitem__(self, indx, value): ...
    @property
    def shape(self) -> _ShapeT_co: ...
    @shape.setter
    def shape(self: MaskedArray[_ShapeT, Any], shape: _ShapeT, /) -> None: ...
    def __setmask__(self, mask: _ArrayLikeBool_co, copy: bool = False) -> None: ...
    @property
    def mask(self) -> NDArray[MaskType] | MaskType: ...
    @mask.setter
    def mask(self, value: _ArrayLikeBool_co, /) -> None: ...
    @property
    def recordmask(self): ...
    @recordmask.setter
    def recordmask(self, mask): ...
    def harden_mask(self) -> Self: ...
    def soften_mask(self) -> Self: ...
    @property
    def hardmask(self) -> bool: ...
    def unshare_mask(self) -> Self: ...
    @property
    def sharedmask(self) -> bool: ...

Review comment (suggestion):
According to pyright:

> Overload 6 for "view" overlaps overload 7 and returns an incompatible type

So we need to make `type[_ArrayT]` and `DTypeLike` disjoint. That's not all that difficult:

```py
DTypeLike: TypeAlias = _DTypeLike[Any] | _VoidDTypeLike | str | None
```

The `_DTypeLike` is the part that contains the `type`, which is already covered by the 2nd and 3rd overloads. So we end up with `_VoidDTypeLike | str | None`. The `_VoidDTypeLike` is a bit annoying, and either has to be imported from `numpy._typing._dtype_like`, or could be replicated as e.g. `tuple[Any, Any] | list[Any] | dict[str, Any]`. Unioning that with the `str | None` should do the trick.

Code after:
    maskiter: Any
    def __init__(self, ma): ...
    def __iter__(self): ...
    def __getitem__(self, indx): ...
    def __setitem__(self, index, value): ...
    def __next__(self): ...

class MaskedArray(ndarray[_ShapeT_co, _DTypeT_co]):
    __array_priority__: Any
    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=...): ...

    @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]: ...
    @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,
        /,
        # `_VoidDTypeLike | str | None` is like `DTypeLike` but without `_DTypeLike[Any]` to avoid
        # overlaps with previous overloads.
        dtype: _VoidDTypeLike | str | None,