70 lines
1.8 KiB
Python
70 lines
1.8 KiB
Python
|
|
"""Provides an immutable sequence view class."""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from sys import maxsize
|
||
|
|
from typing import TYPE_CHECKING, Generic, Iterator, Sequence, TypeVar, overload
|
||
|
|
|
||
|
|
T = TypeVar("T")
|
||
|
|
|
||
|
|
|
||
|
|
class ImmutableSequenceView(Generic[T]):
|
||
|
|
"""Class to wrap a sequence of some sort, but not allow modification."""
|
||
|
|
|
||
|
|
def __init__(self, wrap: Sequence[T]) -> None:
|
||
|
|
"""Initialise the immutable sequence.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
wrap: The sequence being wrapped.
|
||
|
|
"""
|
||
|
|
self._wrap = wrap
|
||
|
|
|
||
|
|
if TYPE_CHECKING:
|
||
|
|
|
||
|
|
@overload
|
||
|
|
def __getitem__(self, index: int) -> T: ...
|
||
|
|
|
||
|
|
@overload
|
||
|
|
def __getitem__(self, index: slice) -> ImmutableSequenceView[T]: ...
|
||
|
|
|
||
|
|
def __getitem__(self, index: int | slice) -> T | ImmutableSequenceView[T]:
|
||
|
|
return (
|
||
|
|
self._wrap[index]
|
||
|
|
if isinstance(index, int)
|
||
|
|
else ImmutableSequenceView[T](self._wrap[index])
|
||
|
|
)
|
||
|
|
|
||
|
|
def __iter__(self) -> Iterator[T]:
|
||
|
|
return iter(self._wrap)
|
||
|
|
|
||
|
|
def __len__(self) -> int:
|
||
|
|
return len(self._wrap)
|
||
|
|
|
||
|
|
def __length_hint__(self) -> int:
|
||
|
|
return len(self)
|
||
|
|
|
||
|
|
def __bool__(self) -> bool:
|
||
|
|
return bool(self._wrap)
|
||
|
|
|
||
|
|
def __contains__(self, item: T) -> bool:
|
||
|
|
return item in self._wrap
|
||
|
|
|
||
|
|
def index(self, item: T, start: int = 0, stop: int = maxsize) -> int:
|
||
|
|
"""Return the index of the given item.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
item: The item to find in the sequence.
|
||
|
|
start: Optional start location.
|
||
|
|
stop: Optional stop location.
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
The index of the item in the sequence.
|
||
|
|
|
||
|
|
Raises:
|
||
|
|
ValueError: If the item is not in the sequence.
|
||
|
|
"""
|
||
|
|
return self._wrap.index(item, start, stop)
|
||
|
|
|
||
|
|
def __reversed__(self) -> Iterator[T]:
|
||
|
|
return reversed(self._wrap)
|