pyochain 0.5.1__py3-none-any.whl → 0.5.31__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.

Potentially problematic release.


This version of pyochain might be problematic. Click here for more details.

@@ -33,7 +33,7 @@ class BaseFilter[T](IterWrapper[T]):
33
33
  def _filter(data: Iterable[T]) -> Iterator[T]:
34
34
  return (x for x in data if func(x))
35
35
 
36
- return self.apply(_filter)
36
+ return self._lazy(_filter)
37
37
 
38
38
  def filter_isin(self, values: Iterable[T]) -> Iter[T]:
39
39
  """
@@ -54,7 +54,7 @@ class BaseFilter[T](IterWrapper[T]):
54
54
  value_set: set[T] = set(values)
55
55
  return (x for x in data if x in value_set)
56
56
 
57
- return self.apply(_filter_isin)
57
+ return self._lazy(_filter_isin)
58
58
 
59
59
  def filter_notin(self, values: Iterable[T]) -> Iter[T]:
60
60
  """
@@ -75,7 +75,7 @@ class BaseFilter[T](IterWrapper[T]):
75
75
  value_set: set[T] = set(values)
76
76
  return (x for x in data if x not in value_set)
77
77
 
78
- return self.apply(_filter_notin)
78
+ return self._lazy(_filter_notin)
79
79
 
80
80
  def filter_contain(
81
81
  self: IterWrapper[str], text: str, format: Callable[[str], str] | None = None
@@ -84,6 +84,7 @@ class BaseFilter[T](IterWrapper[T]):
84
84
  Return elements that contain the given text.
85
85
 
86
86
  Optionally, a format function can be provided to preprocess each element before checking for the substring.
87
+
87
88
  Args:
88
89
  text: Substring to check for.
89
90
  format: Optional function to preprocess each element before checking. Defaults to None.
@@ -107,7 +108,7 @@ class BaseFilter[T](IterWrapper[T]):
107
108
 
108
109
  return (x for x in data if _(x))
109
110
 
110
- return self.apply(_filter_contain)
111
+ return self._lazy(_filter_contain)
111
112
 
112
113
  def filter_attr[U](self, attr: str, dtype: type[U] = object) -> Iter[U]:
113
114
  """
@@ -135,7 +136,7 @@ class BaseFilter[T](IterWrapper[T]):
135
136
 
136
137
  return (x for x in data if _(x))
137
138
 
138
- return self.apply(check)
139
+ return self._lazy(check)
139
140
 
140
141
  def filter_false(self, func: Callable[[T], bool]) -> Iter[T]:
141
142
  """
@@ -151,7 +152,7 @@ class BaseFilter[T](IterWrapper[T]):
151
152
 
152
153
  ```
153
154
  """
154
- return self.apply(partial(itertools.filterfalse, func))
155
+ return self._lazy(partial(itertools.filterfalse, func))
155
156
 
156
157
  def filter_except(
157
158
  self, func: Callable[[T], object], *exceptions: type[BaseException]
@@ -181,7 +182,7 @@ class BaseFilter[T](IterWrapper[T]):
181
182
  def _filter_except(data: Iterable[T]) -> Iterator[T]:
182
183
  return mit.filter_except(func, data, *exceptions)
183
184
 
184
- return self.apply(_filter_except)
185
+ return self._lazy(_filter_except)
185
186
 
186
187
  def take_while(self, predicate: Callable[[T], bool]) -> Iter[T]:
187
188
  """
@@ -197,7 +198,7 @@ class BaseFilter[T](IterWrapper[T]):
197
198
 
198
199
  ```
199
200
  """
200
- return self.apply(partial(itertools.takewhile, predicate))
201
+ return self._lazy(partial(itertools.takewhile, predicate))
201
202
 
202
203
  def skip_while(self, predicate: Callable[[T], bool]) -> Iter[T]:
203
204
  """
@@ -213,7 +214,7 @@ class BaseFilter[T](IterWrapper[T]):
213
214
 
214
215
  ```
215
216
  """
216
- return self.apply(partial(itertools.dropwhile, predicate))
217
+ return self._lazy(partial(itertools.dropwhile, predicate))
217
218
 
218
219
  def compress(self, *selectors: bool) -> Iter[T]:
219
220
  """
@@ -229,7 +230,7 @@ class BaseFilter[T](IterWrapper[T]):
229
230
 
230
231
  ```
231
232
  """
232
- return self.apply(itertools.compress, selectors)
233
+ return self._lazy(itertools.compress, selectors)
233
234
 
234
235
  def unique(self, key: Callable[[T], Any] | None = None) -> Iter[T]:
235
236
  """
@@ -253,7 +254,7 @@ class BaseFilter[T](IterWrapper[T]):
253
254
 
254
255
  ```
255
256
  """
256
- return self.apply(cz.itertoolz.unique, key=key)
257
+ return self._lazy(cz.itertoolz.unique, key=key)
257
258
 
258
259
  def take(self, n: int) -> Iter[T]:
259
260
  """
@@ -280,7 +281,7 @@ class BaseFilter[T](IterWrapper[T]):
280
281
  ```
281
282
  """
282
283
 
283
- return self.apply(partial(cz.itertoolz.take, n))
284
+ return self._lazy(partial(cz.itertoolz.take, n))
284
285
 
285
286
  def skip(self, n: int) -> Iter[T]:
286
287
  """
@@ -296,7 +297,7 @@ class BaseFilter[T](IterWrapper[T]):
296
297
 
297
298
  ```
298
299
  """
299
- return self.apply(partial(cz.itertoolz.drop, n))
300
+ return self._lazy(partial(cz.itertoolz.drop, n))
300
301
 
301
302
  def unique_justseen(self, key: Callable[[T], Any] | None = None) -> Iter[T]:
302
303
  """
@@ -314,7 +315,7 @@ class BaseFilter[T](IterWrapper[T]):
314
315
 
315
316
  ```
316
317
  """
317
- return self.apply(mit.unique_justseen, key=key)
318
+ return self._lazy(mit.unique_justseen, key=key)
318
319
 
319
320
  def unique_in_window(
320
321
  self, n: int, key: Callable[[T], Any] | None = None
@@ -323,6 +324,7 @@ class BaseFilter[T](IterWrapper[T]):
323
324
  Yield the items from iterable that haven't been seen recently.
324
325
 
325
326
  The items in iterable must be hashable.
327
+
326
328
  Args:
327
329
  n: Size of the lookback window.
328
330
  key: Function to transform items before comparison. Defaults to None.
@@ -342,7 +344,7 @@ class BaseFilter[T](IterWrapper[T]):
342
344
 
343
345
  ```
344
346
  """
345
- return self.apply(mit.unique_in_window, n, key=key)
347
+ return self._lazy(mit.unique_in_window, n, key=key)
346
348
 
347
349
  def extract(self, indices: Iterable[int]) -> Iter[T]:
348
350
  """
@@ -364,7 +366,7 @@ class BaseFilter[T](IterWrapper[T]):
364
366
 
365
367
  ```
366
368
  """
367
- return self.apply(mit.extract, indices)
369
+ return self._lazy(mit.extract, indices)
368
370
 
369
371
  def every(self, index: int) -> Iter[T]:
370
372
  """
@@ -380,28 +382,33 @@ class BaseFilter[T](IterWrapper[T]):
380
382
 
381
383
  ```
382
384
  """
383
- return self.apply(partial(cz.itertoolz.take_nth, index))
385
+ return self._lazy(partial(cz.itertoolz.take_nth, index))
384
386
 
385
- def slice(self, start: int | None = None, stop: int | None = None) -> Iter[T]:
387
+ def slice(
388
+ self, start: int | None = None, stop: int | None = None, step: int | None = None
389
+ ) -> Iter[T]:
386
390
  """
387
391
  Return a slice of the iterable.
388
392
 
389
393
  Args:
390
394
  start: Starting index of the slice. Defaults to None.
391
395
  stop: Ending index of the slice. Defaults to None.
396
+ step: Step size for the slice. Defaults to None.
392
397
  Example:
393
398
  ```python
394
399
  >>> import pyochain as pc
395
400
  >>> pc.Iter.from_([1, 2, 3, 4, 5]).slice(1, 4).into(list)
396
401
  [2, 3, 4]
402
+ >>> pc.Iter.from_([1, 2, 3, 4, 5]).slice(step=2).into(list)
403
+ [1, 3, 5]
397
404
 
398
405
  ```
399
406
  """
400
407
 
401
408
  def _slice(data: Iterable[T]) -> Iterator[T]:
402
- return itertools.islice(data, start, stop)
409
+ return itertools.islice(data, start, stop, step)
403
410
 
404
- return self.apply(_slice)
411
+ return self._lazy(_slice)
405
412
 
406
413
  def filter_subclass[U: type[Any], R](
407
414
  self: IterWrapper[U], parent: type[R], keep_parent: bool = True
@@ -441,7 +448,7 @@ class BaseFilter[T](IterWrapper[T]):
441
448
  else:
442
449
  return (x for x in data if issubclass(x, parent) and x is not parent)
443
450
 
444
- return self.apply(_filter_subclass)
451
+ return self._lazy(_filter_subclass)
445
452
 
446
453
  def filter_type[R](self, typ: type[R]) -> Iter[R]:
447
454
  """
@@ -461,7 +468,7 @@ class BaseFilter[T](IterWrapper[T]):
461
468
  def _filter_type(data: Iterable[T]) -> Generator[R, None, None]:
462
469
  return (x for x in data if isinstance(x, typ))
463
470
 
464
- return self.apply(_filter_type)
471
+ return self._lazy(_filter_type)
465
472
 
466
473
  def filter_callable(self) -> Iter[Callable[..., Any]]:
467
474
  """
@@ -481,7 +488,7 @@ class BaseFilter[T](IterWrapper[T]):
481
488
  ) -> Generator[Callable[..., Any], None, None]:
482
489
  return (x for x in data if callable(x))
483
490
 
484
- return self.apply(_filter_callable)
491
+ return self._lazy(_filter_callable)
485
492
 
486
493
  def filter_map[R](self, func: Callable[[T], R]) -> Iter[R]:
487
494
  """
@@ -500,4 +507,4 @@ class BaseFilter[T](IterWrapper[T]):
500
507
 
501
508
  ```
502
509
  """
503
- return self.apply(partial(mit.filter_map, func))
510
+ return self._lazy(partial(mit.filter_map, func))
pyochain/_iter/_joins.py CHANGED
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import itertools
4
4
  from collections.abc import Callable, Generator, Iterable, Iterator
5
- from typing import TYPE_CHECKING, Any, overload
5
+ from typing import TYPE_CHECKING, Any, TypeIs, overload
6
6
 
7
7
  import cytoolz as cz
8
8
  import more_itertools as mit
@@ -67,7 +67,7 @@ class BaseJoins[T](IterWrapper[T]):
67
67
 
68
68
  ```
69
69
  """
70
- return self.apply(zip, *others, strict=strict)
70
+ return self._lazy(zip, *others, strict=strict)
71
71
 
72
72
  def zip_offset[U](
73
73
  self,
@@ -113,7 +113,7 @@ class BaseJoins[T](IterWrapper[T]):
113
113
  fillvalue=fillvalue,
114
114
  )
115
115
 
116
- return self.apply(_zip_offset)
116
+ return self._lazy(_zip_offset)
117
117
 
118
118
  @overload
119
119
  def zip_broadcast[T1](
@@ -162,6 +162,7 @@ class BaseJoins[T](IterWrapper[T]):
162
162
  `str` and `bytes` are not treated as iterables.
163
163
 
164
164
  If the strict keyword argument is True, then UnequalIterablesError will be raised if any of the iterables have different lengths.
165
+
165
166
  Args:
166
167
  *others: Other iterables or scalars to zip with.
167
168
  strict: Whether to enforce equal lengths of iterables. Defaults to False.
@@ -182,15 +183,10 @@ class BaseJoins[T](IterWrapper[T]):
182
183
  ) -> Generator[tuple[Iterable[Any], ...] | tuple[object, ...], Any, None]:
183
184
  """from more_itertools.zip_broadcast"""
184
185
 
185
- def is_scalar(obj: Any) -> bool:
186
+ def is_scalar(obj: Any) -> TypeIs[object]:
186
187
  if isinstance(obj, (str, bytes)):
187
188
  return True
188
- try:
189
- iter(obj)
190
- except TypeError:
191
- return True
192
- else:
193
- return False
189
+ return cz.itertoolz.isiterable(obj) is False
194
190
 
195
191
  size = len(objects)
196
192
  if not size:
@@ -216,7 +212,7 @@ class BaseJoins[T](IterWrapper[T]):
216
212
  pass
217
213
  yield tuple(new_item)
218
214
 
219
- return self.apply(_zip_broadcast, *others)
215
+ return self._lazy(_zip_broadcast, *others)
220
216
 
221
217
  @overload
222
218
  def zip_equal(self) -> Iter[tuple[T]]: ...
@@ -265,7 +261,7 @@ class BaseJoins[T](IterWrapper[T]):
265
261
  def _zip_equal(data: Iterable[T]) -> Iterator[tuple[Any, ...]]:
266
262
  return mit.zip_equal(data, *others)
267
263
 
268
- return self.apply(_zip_equal)
264
+ return self._lazy(_zip_equal)
269
265
 
270
266
  def zip_longest[U](
271
267
  self, *others: Iterable[T], fill_value: U = None
@@ -284,7 +280,7 @@ class BaseJoins[T](IterWrapper[T]):
284
280
 
285
281
  ```
286
282
  """
287
- return self.apply(itertools.zip_longest, *others, fillvalue=fill_value)
283
+ return self._lazy(itertools.zip_longest, *others, fillvalue=fill_value)
288
284
 
289
285
  @overload
290
286
  def product(self) -> Iter[tuple[T]]: ...
@@ -328,7 +324,7 @@ class BaseJoins[T](IterWrapper[T]):
328
324
 
329
325
  ```
330
326
  """
331
- return self.apply(itertools.product, *others)
327
+ return self._lazy(itertools.product, *others)
332
328
 
333
329
  def diff_at(
334
330
  self,
@@ -341,6 +337,7 @@ class BaseJoins[T](IterWrapper[T]):
341
337
  Each output item is a tuple where the i-th element is from the i-th input iterable.
342
338
 
343
339
  If an input iterable is exhausted before others, then the corresponding output items will be filled with *default*.
340
+
344
341
  Args:
345
342
  *others: Other iterables to compare with.
346
343
  default: Value to use for missing elements. Defaults to None.
@@ -364,7 +361,7 @@ class BaseJoins[T](IterWrapper[T]):
364
361
 
365
362
  ```
366
363
  """
367
- return self.apply(cz.itertoolz.diff, *others, default=default, key=key)
364
+ return self._lazy(cz.itertoolz.diff, *others, default=default, key=key)
368
365
 
369
366
  def join[R, K](
370
367
  self,
@@ -404,4 +401,4 @@ class BaseJoins[T](IterWrapper[T]):
404
401
  right_default=right_default,
405
402
  )
406
403
 
407
- return self.apply(_join)
404
+ return self._lazy(_join)
pyochain/_iter/_lists.py CHANGED
@@ -29,7 +29,7 @@ class BaseList[T](IterWrapper[T]):
29
29
  def _implode(data: Iterable[T]) -> Generator[list[T], None, None]:
30
30
  return ([x] for x in data)
31
31
 
32
- return self.apply(_implode)
32
+ return self._lazy(_implode)
33
33
 
34
34
  def split_at(
35
35
  self,
@@ -73,7 +73,7 @@ class BaseList[T](IterWrapper[T]):
73
73
 
74
74
  ```
75
75
  """
76
- return self.apply(mit.split_at, pred, maxsplit, keep_separator)
76
+ return self._lazy(mit.split_at, pred, maxsplit, keep_separator)
77
77
 
78
78
  def split_after(
79
79
  self, predicate: Callable[[T], bool], max_split: int = -1
@@ -100,7 +100,7 @@ class BaseList[T](IterWrapper[T]):
100
100
 
101
101
  ```
102
102
  """
103
- return self.apply(mit.split_after, predicate, max_split)
103
+ return self._lazy(mit.split_after, predicate, max_split)
104
104
 
105
105
  def split_before(
106
106
  self, predicate: Callable[[T], bool], max_split: int = -1
@@ -133,7 +133,7 @@ class BaseList[T](IterWrapper[T]):
133
133
 
134
134
  ```
135
135
  """
136
- return self.apply(mit.split_before, predicate, max_split)
136
+ return self._lazy(mit.split_before, predicate, max_split)
137
137
 
138
138
  def split_into(self, sizes: Iterable[int | None]) -> Iter[list[T]]:
139
139
  """
@@ -179,7 +179,7 @@ class BaseList[T](IterWrapper[T]):
179
179
  - multiple columns represent elements of the same feature (e.g. a point represented by x,y,z)
180
180
  - the format is not the same for all columns.
181
181
  """
182
- return self.apply(mit.split_into, sizes)
182
+ return self._lazy(mit.split_into, sizes)
183
183
 
184
184
  def split_when(
185
185
  self, predicate: Callable[[T, T], bool], max_split: int = -1
@@ -209,7 +209,7 @@ class BaseList[T](IterWrapper[T]):
209
209
 
210
210
  ```
211
211
  """
212
- return self.apply(mit.split_when, predicate, max_split)
212
+ return self._lazy(mit.split_when, predicate, max_split)
213
213
 
214
214
  def chunks(self, n: int, strict: bool = False) -> Iter[list[T]]:
215
215
  """
@@ -225,6 +225,7 @@ class BaseList[T](IterWrapper[T]):
225
225
  - *strict* is `True`
226
226
 
227
227
  then `ValueError` will be raised before the last list is yielded.
228
+
228
229
  Args:
229
230
  n: Number of elements in each chunk.
230
231
  strict: Whether to raise an error if the last chunk is smaller than n. Defaults to False.
@@ -238,13 +239,14 @@ class BaseList[T](IterWrapper[T]):
238
239
 
239
240
  ```
240
241
  """
241
- return self.apply(mit.chunked, n, strict)
242
+ return self._lazy(mit.chunked, n, strict)
242
243
 
243
244
  def chunks_even(self, n: int) -> Iter[list[T]]:
244
245
  """
245
246
  Break iterable into lists of approximately length n.
246
247
 
247
248
  Items are distributed such the lengths of the lists differ by at most 1 item.
249
+
248
250
  Args:
249
251
  n: Approximate number of elements in each chunk.
250
252
  Example:
@@ -258,7 +260,7 @@ class BaseList[T](IterWrapper[T]):
258
260
 
259
261
  ```
260
262
  """
261
- return self.apply(mit.chunked_even, n)
263
+ return self._lazy(mit.chunked_even, n)
262
264
 
263
265
  def unique_to_each[U: Iterable[Any]](self: IterWrapper[U]) -> Iter[list[U]]:
264
266
  """
@@ -303,4 +305,4 @@ class BaseList[T](IterWrapper[T]):
303
305
  uniques: set[U] = {element for element in counts if counts[element] == 1}
304
306
  return ((list(filter(uniques.__contains__, it))) for it in pool)
305
307
 
306
- return self.apply(_unique_to_each)
308
+ return self._lazy(_unique_to_each)