<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.3.0/css/all.min.css"
        integrity="sha512-SzlrxWUlpfuzQ+pcUCosxcglQRNAq/DZjVsC0lE40xsADsfeQoEypE+enwcOiGjk/bSuGGKHEyjSoQ1zVisanQ=="
        crossorigin="anonymous" referrerpolicy="no-referrer" />
</head>
</html>
from collections.abc import Generator
from typing import (
    Any,
    TypeVar,
    Union,
    overload,
)

from numpy import ndarray, dtype, generic
from numpy._typing import DTypeLike

# TODO: Set a shape bound once we've got proper shape support
_Shape = TypeVar("_Shape", bound=Any)
_DType = TypeVar("_DType", bound=dtype[Any])
_ScalarType = TypeVar("_ScalarType", bound=generic)

_Index = Union[
    Union[ellipsis, int, slice],
    tuple[Union[ellipsis, int, slice], ...],
]

__all__: list[str]

# NOTE: In reality `Arrayterator` does not actually inherit from `ndarray`,
# but its ``__getattr__` method does wrap around the former and thus has
# access to all its methods

class Arrayterator(ndarray[_Shape, _DType]):
    var: ndarray[_Shape, _DType]  # type: ignore[assignment]
    buf_size: None | int
    start: list[int]
    stop: list[int]
    step: list[int]

    @property  # type: ignore[misc]
    def shape(self) -> tuple[int, ...]: ...
    @property
    def flat(  # type: ignore[override]
        self: ndarray[Any, dtype[_ScalarType]]
    ) -> Generator[_ScalarType, None, None]: ...
    def __init__(
        self, var: ndarray[_Shape, _DType], buf_size: None | int = ...
    ) -> None: ...
    @overload
    def __array__(self, dtype: None = ...) -> ndarray[Any, _DType]: ...
    @overload
    def __array__(self, dtype: DTypeLike) -> ndarray[Any, dtype[Any]]: ...
    def __getitem__(self, index: _Index) -> Arrayterator[Any, _DType]: ...
    def __iter__(self) -> Generator[ndarray[Any, _DType], None, None]: ...
