relib 1.3.11__py3-none-any.whl → 1.3.12__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
relib/class_utils.py ADDED
@@ -0,0 +1,9 @@
1
+ from typing import Callable, Generic, TypeVar
2
+
3
+ Fn = TypeVar("Fn", bound=Callable)
4
+
5
+ class slicer(Generic[Fn]):
6
+ def __init__(self, fn: Fn):
7
+ self.fn = fn
8
+
9
+ __getitem__: Fn = lambda self, key: self.fn(key) # type: ignore
relib/iter_utils.py CHANGED
@@ -1,7 +1,8 @@
1
1
  from __future__ import annotations
2
2
  from contextlib import contextmanager
3
- from itertools import chain, islice
3
+ from itertools import chain, islice, tee
4
4
  from typing import Any, Generic, Iterable, Literal, Sequence, overload
5
+ from .class_utils import slicer
5
6
  from .dict_utils import dict_firsts
6
7
  from .types import T1, T2, T3, T4, T5, T, U
7
8
 
@@ -17,6 +18,7 @@ __all__ = [
17
18
  "range_of", "reversed_enumerate",
18
19
  "seekable", "sort_by",
19
20
  "transpose",
21
+ "unzip_iterable",
20
22
  ]
21
23
 
22
24
  def as_list(iterable: Iterable[T]) -> list[T]:
@@ -81,6 +83,7 @@ class seekable(Generic[T]):
81
83
  self.index = 0
82
84
  self.source = iter(iterable)
83
85
  self.sink: list[T] = []
86
+ self.abs = slicer(self.abs_getitem)
84
87
 
85
88
  def __iter__(self):
86
89
  return self
@@ -102,10 +105,10 @@ class seekable(Generic[T]):
102
105
  self.index = 0
103
106
 
104
107
  def seek(self, index: int) -> seekable[T]:
105
- remainder = index - self.index
106
- if remainder > 0:
108
+ index = max(0, index)
109
+ self.index = min(index, len(self.sink))
110
+ if (remainder := index - self.index) > 0:
107
111
  next(islice(self, remainder, remainder), None)
108
- self.index = max(0, min(index, len(self.sink)))
109
112
  return self
110
113
 
111
114
  def step(self, count: int) -> seekable[T]:
@@ -130,10 +133,21 @@ class seekable(Generic[T]):
130
133
  with self.freeze():
131
134
  if isinstance(key, int):
132
135
  return self[key:key + 1][0]
133
- parts = (key.start, key.stop, key.step)
134
- if not all(x is None or x >= 0 for x in parts):
135
- raise ValueError(f"Indices for seekable() must be positive int")
136
- return list(islice(self, *parts))
136
+ start, stop, step = key.start, key.stop, key.step
137
+ delta = min(self.index, -min(0, start or 0))
138
+ start = None if start is None else max(0, start + delta)
139
+ stop = None if stop is None else max(0, stop + delta)
140
+ self.step(-delta)
141
+ return list(islice(self, start, stop, step))
142
+
143
+ @overload
144
+ def abs_getitem(self, key: int) -> T: ...
145
+ @overload
146
+ def abs_getitem(self, key: slice[int | None]) -> list[T]: ...
147
+ def abs_getitem(self, key: int | slice[int | None]):
148
+ with self.freeze():
149
+ self.seek(0)
150
+ return self[key]
137
151
 
138
152
  def consume(self) -> Iterable[T]:
139
153
  for value in self:
@@ -185,3 +199,15 @@ def transpose(tuples: Iterable[tuple], default_num_returns=0) -> tuple[list, ...
185
199
  if not output:
186
200
  return ([],) * default_num_returns
187
201
  return tuple(map(list, output))
202
+
203
+ @overload
204
+ def unzip_iterable(iterable: Iterable[tuple[T1, T2]], n: Literal[2]) -> tuple[Iterable[T1], Iterable[T2]]: ...
205
+ @overload
206
+ def unzip_iterable(iterable: Iterable[tuple[T1, T2, T3]], n: Literal[3]) -> tuple[Iterable[T1], Iterable[T2], Iterable[T3]]: ...
207
+ @overload
208
+ def unzip_iterable(iterable: Iterable[tuple[T1, T2, T3, T4]], n: Literal[4]) -> tuple[Iterable[T1], Iterable[T2], Iterable[T3], Iterable[T4]]: ...
209
+ @overload
210
+ def unzip_iterable(iterable: Iterable[tuple[T1, T2, T3, T4, T5]], n: Literal[5]) -> tuple[Iterable[T1], Iterable[T2], Iterable[T3], Iterable[T4], Iterable[T5]]: ...
211
+ def unzip_iterable(iterable: Iterable[tuple], n: int) -> tuple:
212
+ iters = tee(iterable, n)
213
+ return tuple(map(lambda i, iter: (x[i] for x in iter), range(n), iters))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: relib
3
- Version: 1.3.11
3
+ Version: 1.3.12
4
4
  Project-URL: Repository, https://github.com/Reddan/relib.git
5
5
  Author: Hampus Hallman
6
6
  License: Copyright 2018-2025 Hampus Hallman
@@ -1,12 +1,13 @@
1
1
  relib/__init__.py,sha256=WerjUaM_sNvudjXFudLRtXB7viZWEW1RSinkDjrh4nE,163
2
+ relib/class_utils.py,sha256=3z23lxhjFbn68IM_YnJPlvGG2pkybZuK3o_C-9b_LCc,225
2
3
  relib/dict_utils.py,sha256=ez8egTPvO05wVNWIyO-aJjtqaXUDYbzyw32M42q1D44,3677
3
4
  relib/io_utils.py,sha256=cUyUFhrMCUDfkINhYo32QPaVGz3chqDO3ElymSCoWEg,1086
4
- relib/iter_utils.py,sha256=iH8fu9FrNRurOsa--GqDbTzHdrV8eJOONvumMGr2pMA,6303
5
+ relib/iter_utils.py,sha256=NOHO3V-wqweyNzfNyCw8HfZHxQk-2vHbCKGm1lMq12Q,7516
5
6
  relib/processing_utils.py,sha256=kFb4izrR8vec9BFWeGSb-TXR54bbA4X3dxAfIBZItuI,1911
6
7
  relib/runtime_tools.py,sha256=6HpRXmAHHLq4bNRj6fSiaLQeHR2h3OdxFZxaB93fXhI,2979
7
8
  relib/type_utils.py,sha256=68yEhEIBCIKfsIT1u647avHVA_JjVvDYSdtLD3nCrJs,338
8
9
  relib/types.py,sha256=JzSGDl2L6tUWizGSsUpuyCKf-VKgtgfK_n21azSSMLM,288
9
- relib-1.3.11.dist-info/METADATA,sha256=YvXC6KVDCiYFMUUcbP8onzIcGzUzgyerJ4EBVLkDeBM,1296
10
- relib-1.3.11.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
11
- relib-1.3.11.dist-info/licenses/LICENSE,sha256=9xVsdtv_-uSyY9Xl9yujwAPm4-mjcCLeVy-ljwXEWbo,1059
12
- relib-1.3.11.dist-info/RECORD,,
10
+ relib-1.3.12.dist-info/METADATA,sha256=HBuTdPt-iKCNTQw-GBlQ96gTrltroylBPAY0eP4UdZk,1296
11
+ relib-1.3.12.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
12
+ relib-1.3.12.dist-info/licenses/LICENSE,sha256=9xVsdtv_-uSyY9Xl9yujwAPm4-mjcCLeVy-ljwXEWbo,1059
13
+ relib-1.3.12.dist-info/RECORD,,
File without changes