Rename ImmutableSequence to ImmutableSequenceView

Also, in doing so, drop support for unrolling iterators and making them into
indexable sequences.

See the following feedback:

  https://github.com/Textualize/textual/pull/1495#pullrequestreview-1238616797
  https://github.com/Textualize/textual/pull/1495#issuecomment-1373553580
This commit is contained in:
Dave Pearson
2023-01-06 12:23:51 +00:00
parent e5869b9f7b
commit 71cc1bca1e
3 changed files with 16 additions and 30 deletions

View File

@@ -1,35 +1,35 @@
"""Provides collection-based utility code."""
"""Provides an immutable sequence view class."""
from __future__ import annotations
from typing import Generic, TypeVar, Iterator, overload, Iterable, Sequence
from typing import Generic, TypeVar, Iterator, overload, Sequence
T = TypeVar("T")
class ImmutableSequence(Generic[T]):
class ImmutableSequenceView(Generic[T]):
"""Class to wrap a sequence of some sort, but not allow modification."""
def __init__(self, wrap: Iterable[T]) -> None:
def __init__(self, wrap: Sequence[T]) -> None:
"""Initialise the immutable sequence.
Args:
wrap (Iterable[T]): The iterable value being wrapped.
wrap (Sequence[T]): The sequence being wrapped.
"""
self._wrap = wrap if isinstance(wrap, Sequence) else tuple(wrap)
self._wrap = wrap
@overload
def __getitem__(self, index: int) -> T:
...
@overload
def __getitem__(self, index: slice) -> ImmutableSequence[T]:
def __getitem__(self, index: slice) -> ImmutableSequenceView[T]:
...
def __getitem__(self, index: int | slice) -> T | ImmutableSequence[T]:
def __getitem__(self, index: int | slice) -> T | ImmutableSequenceView[T]:
return (
self._wrap[index]
if isinstance(index, int)
else ImmutableSequence[T](self._wrap[index])
else ImmutableSequenceView[T](self._wrap[index])
)
def __iter__(self) -> Iterator[T]:

View File

@@ -14,7 +14,7 @@ from .._loop import loop_last
from .._segment_tools import line_crop, line_pad
from .._types import MessageTarget
from .._typing import TypeAlias
from .._collections import ImmutableSequence
from .._immutable_sequence_view import ImmutableSequenceView
from ..binding import Binding
from ..geometry import Region, Size, clamp
from ..message import Message
@@ -54,7 +54,7 @@ class _TreeLine:
return guides
class TreeNodes(ImmutableSequence["TreeNode[TreeDataType]"]):
class TreeNodes(ImmutableSequenceView["TreeNode[TreeDataType]"]):
"""An immutable collection of `TreeNode`."""

View File

@@ -1,11 +1,11 @@
import pytest
from typing import Iterable
from textual._collections import ImmutableSequence
from typing import Sequence
from textual._immutable_sequence_view import ImmutableSequenceView
def wrap(source: Iterable[int]) -> ImmutableSequence[int]:
"""Wrap an itertable of integers inside an immutable sequence."""
return ImmutableSequence[int](source)
def wrap(source: Sequence[int]) -> ImmutableSequenceView[int]:
"""Wrap a sequence of integers inside an immutable sequence view."""
return ImmutableSequenceView[int](source)
def test_empty_immutable_sequence() -> None:
@@ -22,20 +22,6 @@ def test_non_empty_immutable_sequence() -> None:
assert list(wrap([0])) == [0]
def test_immutable_sequence_from_empty_iter() -> None:
"""An immutable sequence around an empty iterator should act as anticipated."""
assert len(wrap(iter([]))) == 0
assert bool(wrap(iter([]))) is False
assert list(wrap(iter([]))) == []
def test_immutable_sequence_from_non_empty_iter() -> None:
"""An immutable sequence around a non-empty iterator should act as anticipated."""
assert len(wrap(iter(range(23)))) == 23
assert bool(wrap(iter(range(23)))) is True
assert list(wrap(iter(range(23)))) == list(range(23))
def test_no_assign_to_immutable_sequence() -> None:
"""It should not be possible to assign into an immutable sequence."""
tester = wrap([1,2,3,4,5])