Repository: numpy/numpy
File: numpy/__init__.pyi (Python)

Code before:
    @overload
    def __array__(self, dtype: _DTypeT, /) -> ndarray[tuple[()], _DTypeT]: ...

    #
    @overload
    def __getitem__(self, key: tuple[()], /) -> Self: ...
    @overload
    def __getitem__(
        self, key: EllipsisType | tuple[EllipsisType], /
    ) -> ndarray[tuple[()], dtype[Self]]: ...
    @overload
    def __getitem__(
        self, key: None | tuple[None], /
    ) -> ndarray[tuple[int], dtype[Self]]: ...
    @overload
    def __getitem__(
        self, key: tuple[None, None], /
    ) -> ndarray[tuple[int, int], dtype[Self]]: ...
    @overload
    def __getitem__(
        self, key: tuple[None, None, None], /
    ) -> ndarray[tuple[int, int, int], dtype[Self]]: ...
    @overload  # Limited support for (None,) * N > 3
    def __getitem__(
        self, key: tuple[None, ...], /
    ) -> ndarray[tuple[int, ...], dtype[Self]]: ...

    #
    @overload
    def __array_wrap__(
        self,
        array: ndarray[_ShapeT, _DTypeT],
        context: tuple[ufunc, tuple[object, ...], int] | None,
        return_scalar: L[False],
        /,
    ) -> ndarray[_ShapeT, _DTypeT]: ...
    @overload
    def __array_wrap__(
        self,
        array: ndarray[tuple[()], dtype[_ScalarT]],
        context: tuple[ufunc, tuple[object, ...], int] | None = None,
        return_scalar: L[True] = True,
        /,
    ) -> _ScalarT: ...
    @overload
    def __array_wrap__(
        self,
        array: ndarray[_Shape1T, _DTypeT],
        context: tuple[ufunc, tuple[object, ...], int] | None = None,
        return_scalar: L[True] = True,
        /,

Review comment (suggestion):
`NDArray` uses the "gradual" tuple type, `tuple[Any, ...]`. That way it'll also be assignable to e.g. arrays with 1d shape type:

```suggestion
    def __getitem__(self, key: tuple[None, ...], /) -> NDArray[Self]: ...
```

Code after:
    @overload
    def __array__(self, dtype: _DTypeT, /) -> ndarray[tuple[()], _DTypeT]: ...

    #
    @overload
    def __getitem__(self, key: tuple[()], /) -> Self: ...
    @overload
    def __getitem__(
        self, key: EllipsisType | tuple[EllipsisType], /
    ) -> ndarray[tuple[()], dtype[Self]]: ...
    @overload
    def __getitem__(
        self, key: None | tuple[None], /
    ) -> ndarray[tuple[int], dtype[Self]]: ...
    @overload
    def __getitem__(
        self, key: tuple[None, None], /
    ) -> ndarray[tuple[int, int], dtype[Self]]: ...
    @overload
    def __getitem__(
        self, key: tuple[None, None, None], /
    ) -> ndarray[tuple[int, int, int], dtype[Self]]: ...
    @overload  # Limited support for (None,) * N > 3
    def __getitem__(self, key: tuple[None, ...], /) -> NDArray[Self]: ...

    #
    @overload
    def __array_wrap__(
        self,
        array: ndarray[_ShapeT, _DTypeT],
        context: tuple[ufunc, tuple[object, ...], int] | None,
        return_scalar: L[False],
        /,
    ) -> ndarray[_ShapeT, _DTypeT]: ...
    @overload
    def __array_wrap__(
        self,
        array: ndarray[tuple[()], dtype[_ScalarT]],
        context: tuple[ufunc, tuple[object, ...], int] | None = None,
        return_scalar: L[True] = True,
        /,
    ) -> _ScalarT: ...
    @overload
    def __array_wrap__(
        self,
        array: ndarray[_Shape1T, _DTypeT],
        context: tuple[ufunc, tuple[object, ...], int] | None = None,
        return_scalar: L[True] = True,
        /,
    ) -> ndarray[_Shape1T, _DTypeT]: ...
    @overload