1"""A module containing the `_NestedSequence` protocol."""
2
3from __future__ import annotations
4
5from typing import (
6 Any,
7 TypeVar,
8 Protocol,
9 runtime_checkable,
10 TYPE_CHECKING,
11)
12
13if TYPE_CHECKING:
14 from collections.abc import Iterator
15
16__all__ = ["_NestedSequence"]
17
18_T_co = TypeVar("_T_co", covariant=True)
19
20
21@runtime_checkable
22class _NestedSequence(Protocol[_T_co]):
23 """A protocol for representing nested sequences.
24
25 Warning
26 -------
27 `_NestedSequence` currently does not work in combination with typevars,
28 *e.g.* ``def func(a: _NestedSequnce[T]) -> T: ...``.
29
30 See Also
31 --------
32 collections.abc.Sequence
33 ABCs for read-only and mutable :term:`sequences`.
34
35 Examples
36 --------
37 .. code-block:: python
38
39 >>> from __future__ import annotations
40
41 >>> from typing import TYPE_CHECKING
42 >>> import numpy as np
43 >>> from numpy._typing import _NestedSequence
44
45 >>> def get_dtype(seq: _NestedSequence[float]) -> np.dtype[np.float64]:
46 ... return np.asarray(seq).dtype
47
48 >>> a = get_dtype([1.0])
49 >>> b = get_dtype([[1.0]])
50 >>> c = get_dtype([[[1.0]]])
51 >>> d = get_dtype([[[[1.0]]]])
52
53 >>> if TYPE_CHECKING:
54 ... reveal_locals()
55 ... # note: Revealed local types are:
56 ... # note: a: numpy.dtype[numpy.floating[numpy._typing._64Bit]]
57 ... # note: b: numpy.dtype[numpy.floating[numpy._typing._64Bit]]
58 ... # note: c: numpy.dtype[numpy.floating[numpy._typing._64Bit]]
59 ... # note: d: numpy.dtype[numpy.floating[numpy._typing._64Bit]]
60
61 """
62
63 def __len__(self, /) -> int:
64 """Implement ``len(self)``."""
65 raise NotImplementedError
66
67 def __getitem__(self, index: int, /) -> _T_co | _NestedSequence[_T_co]:
68 """Implement ``self[x]``."""
69 raise NotImplementedError
70
71 def __contains__(self, x: object, /) -> bool:
72 """Implement ``x in self``."""
73 raise NotImplementedError
74
75 def __iter__(self, /) -> Iterator[_T_co | _NestedSequence[_T_co]]:
76 """Implement ``iter(self)``."""
77 raise NotImplementedError
78
79 def __reversed__(self, /) -> Iterator[_T_co | _NestedSequence[_T_co]]:
80 """Implement ``reversed(self)``."""
81 raise NotImplementedError
82
83 def count(self, value: Any, /) -> int:
84 """Return the number of occurrences of `value`."""
85 raise NotImplementedError
86
87 def index(self, value: Any, /) -> int:
88 """Return the first index of `value`."""
89 raise NotImplementedError