aboutsummaryrefslogtreecommitdiff
path: root/tools/cru-py/cru/_iter.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/cru-py/cru/_iter.py')
-rw-r--r--tools/cru-py/cru/_iter.py96
1 files changed, 61 insertions, 35 deletions
diff --git a/tools/cru-py/cru/_iter.py b/tools/cru-py/cru/_iter.py
index 83a9513..bf1dfde 100644
--- a/tools/cru-py/cru/_iter.py
+++ b/tools/cru-py/cru/_iter.py
@@ -18,7 +18,7 @@ from typing import (
cast,
)
-from ._cru import CRU
+from ._base import CRU, cru_unreachable
from ._const import CruNotFound
_P = ParamSpec("_P")
@@ -238,7 +238,7 @@ class _Generic:
pass
except StopIteration as stop:
return stop.value
- raise RuntimeError("Should not reach here")
+ cru_unreachable()
class _Helper:
@@ -255,38 +255,49 @@ class _Helper:
return wrapper
-class _Dec:
-
- @staticmethod
- def wrap(origin: Callable[_P, Iterable[_T]]) -> Callable[_P, _Wrapper[_T]]:
- def _wrapped(*args: _P.args, **kwargs: _P.kwargs) -> _Wrapper[_T]:
- return _Wrapper(origin(*args, **kwargs))
-
- return _wrapped
-
-
class _Creators:
+
@staticmethod
- @_Dec.wrap
- def empty() -> Iterable[Never]:
- return iter([])
+ def empty(
+ *,
+ wrapper_type: type["_Wrapper[Never]"] | None = None,
+ attr: dict[str, Any] | None = None,
+ ) -> _Wrapper[Never]:
+ wrapper_type = wrapper_type or _Wrapper
+ return wrapper_type(iter([]), attr)
@staticmethod
- @_Dec.wrap
- def range(*args) -> Iterable[int]:
- return iter(range(*args))
+ def range(
+ *args,
+ wrapper_type: type["_Wrapper[int]"] | None = None,
+ attr: dict[str, Any] | None = None,
+ ) -> _Wrapper[int]:
+ wrapper_type = wrapper_type or _Wrapper
+ return wrapper_type(iter(range(*args)), attr)
@staticmethod
- @_Dec.wrap
- def unite(*args: _O) -> Iterable[_O]:
- return iter(args)
+ def unite(
+ *args: _O,
+ wrapper_type: type["_Wrapper[_O]"] | None = None,
+ attr: dict[str, Any] | None = None,
+ ) -> _Wrapper[_O]:
+ wrapper_type = wrapper_type or _Wrapper
+ return wrapper_type(iter(args), attr)
@staticmethod
- @_Dec.wrap
- def concat(*iterables: Iterable[_T]) -> Iterable[_T]:
+ def _concat(*iterables: Iterable[_T]) -> Iterable[_T]:
for iterable in iterables:
yield from iterable
+ @staticmethod
+ def concat(
+ *iterables: Iterable[_T],
+ wrapper_type: type["_Wrapper[_T]"] | None = None,
+ attr: dict[str, Any] | None = None,
+ ) -> _Wrapper[_T]:
+ wrapper_type = wrapper_type or _Wrapper
+ return wrapper_type(_Creators._concat(*iterables), attr)
+
class _Wrapper(Generic[_T]):
ElementOperation: TypeAlias = Callable[[_V], Any]
@@ -297,10 +308,10 @@ class _Wrapper(Generic[_T]):
AnyElementTransformer: TypeAlias = ElementTransformer[Any, Any]
def __init__(
- self,
- iterable: Iterable[_T],
+ self, iterable: Iterable[_T], attr: dict[str, Any] | None = None
) -> None:
self._iterable = iterable
+ self._attr = attr or {}
def __iter__(self) -> Iterator[_T]:
return self._iterable.__iter__()
@@ -309,23 +320,39 @@ class _Wrapper(Generic[_T]):
def me(self) -> Iterable[_T]:
return self._iterable
- _wrap = _Dec.wrap
+ @property
+ def my_attr(self) -> dict[str, Any]:
+ return self._attr
+
+ def create_with_me(self, iterable: Iterable[_O]) -> _Wrapper[_O]:
+ return type(self)(iterable, self._attr) # type: ignore
+
+ @staticmethod
+ def _wrap(
+ f: Callable[Concatenate[_Wrapper[_T], _P], Iterable[_O]]
+ ) -> Callable[Concatenate[_Wrapper[_T], _P], _Wrapper[_O]]:
+ def _wrapped(
+ self: _Wrapper[_T], *args: _P.args, **kwargs: _P.kwargs
+ ) -> _Wrapper[_O]:
+ return self.create_with_me(f(self, *args, **kwargs))
+
+ return _wrapped
@_wrap
def replace_me(self, iterable: Iterable[_O]) -> Iterable[_O]:
return iterable
def replace_me_with_empty(self) -> _Wrapper[Never]:
- return _Creators.empty()
+ return _Creators.empty(wrapper_type=type(self), attr=self._attr) # type: ignore
def replace_me_with_range(self, *args) -> _Wrapper[int]:
- return _Creators.range(*args)
+ return _Creators.range(*args, attr=self._attr)
def replace_me_with_unite(self, *args: _O) -> _Wrapper[_O]:
- return _Creators.unite(*args)
+ return _Creators.unite(*args, attr=self._attr)
def replace_me_with_concat(self, *iterables: Iterable[_T]) -> _Wrapper[_T]:
- return _Creators.concat(*iterables)
+ return _Creators.concat(*iterables, attr=self._attr)
def to_set(self, discard: Iterable[Any]) -> set[_T]:
return set(self.me) - set(discard)
@@ -422,11 +449,10 @@ class _Wrapper(Generic[_T]):
class CruIterable:
- Decorators = _Dec
- Generic = _Generic
- Helper = _Helper
- Creators = _Creators
- Wrapper = _Wrapper
+ Generic: TypeAlias = _Generic
+ Helper: TypeAlias = _Helper
+ Creators: TypeAlias = _Creators
+ Wrapper: TypeAlias = _Wrapper
CRU.add_objects(CruIterable, _Wrapper)