relib 1.3.10__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 - len(self.sink)
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]:
@@ -128,10 +131,23 @@ class seekable(Generic[T]):
128
131
  def __getitem__(self, key: slice[int | None]) -> list[T]: ...
129
132
  def __getitem__(self, key: int | slice[int | None]):
130
133
  with self.freeze():
131
- if isinstance(key, slice):
132
- return list(islice(self, key.start, key.stop, key.step))
133
- elif isinstance(key, int):
134
- return self[:key + 1][key]
134
+ if isinstance(key, int):
135
+ return self[key:key + 1][0]
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]
135
151
 
136
152
  def consume(self) -> Iterable[T]:
137
153
  for value in self:
@@ -183,3 +199,15 @@ def transpose(tuples: Iterable[tuple], default_num_returns=0) -> tuple[list, ...
183
199
  if not output:
184
200
  return ([],) * default_num_returns
185
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.10
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=26pZRcqK48cGW6Ffb-bsK0h5aDlFBfdk5zlSab4KP0A,6193
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.10.dist-info/METADATA,sha256=DHDZQ-YhPHmg3cyt2c5SydIMalsCP30Lp3vba4Esaes,1296
10
- relib-1.3.10.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
11
- relib-1.3.10.dist-info/licenses/LICENSE,sha256=9xVsdtv_-uSyY9Xl9yujwAPm4-mjcCLeVy-ljwXEWbo,1059
12
- relib-1.3.10.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