python-iterutils 0.2.4.1__py3-none-any.whl → 0.2.5__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.
iterutils/__init__.py CHANGED
@@ -2,12 +2,12 @@
2
2
  # encoding: utf-8
3
3
 
4
4
  __author__ = "ChenyangGao <https://chenyanggao.github.io>"
5
- __version__ = (0, 2, 4)
5
+ __version__ = (0, 2, 5)
6
6
  __all__ = [
7
7
  "Yield", "YieldFrom", "iterable", "async_iterable",
8
8
  "run_gen_step", "run_gen_step_iter", "as_gen_step",
9
9
  "as_gen_step_iter", "split_cm, ""with_iter_next",
10
- "map", "filter", "reduce", "zip", "chunked",
10
+ "map", "filter", "reduce", "zip", "chain", "chunked",
11
11
  "foreach", "async_foreach", "through", "async_through",
12
12
  "flatten", "async_flatten", "collect", "async_collect",
13
13
  "group_collect", "async_group_collect", "iter_unique",
@@ -30,7 +30,7 @@ from contextlib import (
30
30
  )
31
31
  from copy import copy
32
32
  from dataclasses import dataclass
33
- from itertools import batched, pairwise
33
+ from itertools import batched, chain as _chain, pairwise
34
34
  from inspect import isawaitable, iscoroutinefunction, signature
35
35
  from sys import _getframe, exc_info
36
36
  from _thread import start_new_thread
@@ -42,7 +42,7 @@ from typing import (
42
42
 
43
43
  from asynctools import (
44
44
  async_filter, async_map, async_reduce, async_zip, async_batched,
45
- ensure_async, ensure_aiter, collect as async_collect,
45
+ ensure_async, ensure_aiter, async_chain, collect as async_collect,
46
46
  )
47
47
  from texttools import format_time
48
48
  from undefined import undefined
@@ -338,7 +338,7 @@ def split_cm[T](
338
338
  finally:
339
339
  yield exit()
340
340
 
341
- run_gen_step(gen_step, async_=async_)
341
+ run_gen_step(gen_step, async_)
342
342
  """
343
343
  if isinstance(cm, AbstractAsyncContextManager):
344
344
  enter: Callable = cm.__aenter__
@@ -389,7 +389,7 @@ def with_iter_next[T](
389
389
  e = yield do_next()
390
390
  do_what_you_want()
391
391
 
392
- run_gen_step(gen_step, async_=async_)
392
+ run_gen_step(gen_step, async_)
393
393
  """
394
394
  if isinstance(iterable, AsyncIterable):
395
395
  try:
@@ -408,17 +408,21 @@ def map(
408
408
  iterable: Iterable | AsyncIterable,
409
409
  /,
410
410
  *iterables: Iterable | AsyncIterable,
411
+ threaded: bool = False,
411
412
  ):
412
413
  """
413
414
  """
414
415
  if (
416
+ threaded or
415
417
  iscoroutinefunction(function) or
416
418
  isinstance(iterable, AsyncIterable) or
417
419
  any(isinstance(i, AsyncIterable) for i in iterables)
418
420
  ):
419
421
  if function is None:
420
422
  if iterables:
421
- return async_zip(iterable, *iterables)
423
+ return async_zip(iterable, *iterables, threaded=threaded)
424
+ elif threaded:
425
+ return ensure_aiter(iterable, threaded=threaded)
422
426
  else:
423
427
  return iterable
424
428
  return async_map(function, iterable, *iterables)
@@ -434,11 +438,12 @@ def filter(
434
438
  function: None | Callable,
435
439
  iterable: Iterable | AsyncIterable,
436
440
  /,
441
+ threaded: bool = False,
437
442
  ):
438
443
  """
439
444
  """
440
- if iscoroutinefunction(function) or isinstance(iterable, AsyncIterable):
441
- return async_filter(function, iterable)
445
+ if threaded or iscoroutinefunction(function) or isinstance(iterable, AsyncIterable):
446
+ return async_filter(function, iterable, threaded=threaded)
442
447
  return _filter(function, iterable)
443
448
 
444
449
 
@@ -447,11 +452,12 @@ def reduce(
447
452
  iterable: Iterable | AsyncIterable,
448
453
  initial: Any = undefined,
449
454
  /,
455
+ threaded: bool = False,
450
456
  ):
451
457
  """
452
458
  """
453
- if iscoroutinefunction(function) or isinstance(iterable, AsyncIterable):
454
- return async_reduce(function, iterable, initial)
459
+ if threaded or iscoroutinefunction(function) or isinstance(iterable, AsyncIterable):
460
+ return async_reduce(function, iterable, initial, threaded=threaded)
455
461
  from functools import reduce
456
462
  if initial is undefined:
457
463
  return reduce(function, iterable)
@@ -462,19 +468,78 @@ def zip(
462
468
  iterable: Iterable | AsyncIterable,
463
469
  /,
464
470
  *iterables: Iterable | AsyncIterable,
471
+ threaded: bool = False,
465
472
  ):
466
473
  """
467
474
  """
468
- if isinstance(iterable, AsyncIterable) or any(isinstance(i, AsyncIterable) for i in iterables):
469
- return async_zip(iterable, *iterables)
475
+ if threaded or isinstance(iterable, AsyncIterable) or any(isinstance(i, AsyncIterable) for i in iterables):
476
+ return async_zip(iterable, *iterables, threaded=threaded)
470
477
  return _zip(iterable, *iterables)
471
478
 
472
479
 
480
+ @overload
481
+ def chain[T](
482
+ iterable: Iterable[T],
483
+ /,
484
+ *iterables: Iterable[T],
485
+ threaded: bool = False,
486
+ ) -> Iterator[T]:
487
+ ...
488
+ @overload
489
+ def chain[T](
490
+ iterable: AsyncIterable[T],
491
+ /,
492
+ *iterables: Iterable[T] | AsyncIterable[T],
493
+ threaded: bool = False,
494
+ ) -> AsyncIterator[T]:
495
+ ...
496
+ def chain[T](
497
+ iterable: Iterable[T] | AsyncIterable[T],
498
+ /,
499
+ *iterables: Iterable[T] | AsyncIterable[T],
500
+ threaded: bool = False,
501
+ ) -> Iterator[T] | AsyncIterator[T]:
502
+ if threaded or not isinstance(iterable, Iterable):
503
+ return async_chain(iterable, *iterables, threaded=threaded)
504
+ return _chain(iterable, *iterables) # type: ignore
505
+
506
+
507
+ @overload
508
+ def chain_from_iterable[T](
509
+ iterables: Iterable[Iterable[T]],
510
+ threaded: Literal[False] = False,
511
+ *,
512
+ async_: Literal[False] = False,
513
+ ) -> Iterator[T]:
514
+ ...
515
+ @overload
516
+ def chain_from_iterable[T](
517
+ iterables: Iterable[Iterable[T] | AsyncIterable[T]] | AsyncIterable[Iterable[T] | AsyncIterable[T]],
518
+ threaded: bool = False,
519
+ *,
520
+ async_: Literal[True],
521
+ ) -> AsyncIterator[T]:
522
+ ...
523
+ def chain_from_iterable[T](
524
+ iterables: Iterable[Iterable[T]] | Iterable[Iterable[T] | AsyncIterable[T]] | AsyncIterable[Iterable[T] | AsyncIterable[T]],
525
+ threaded: bool = False,
526
+ *,
527
+ async_: Literal[False, True] = False,
528
+ ) -> Iterator[T] | AsyncIterator[T]:
529
+ if async_ or threaded or not isinstance(iterables, Iterable):
530
+ if isinstance(iterables, Iterable):
531
+ return async_chain.from_iterable(iterables, threaded=threaded)
532
+ else:
533
+ return async_chain.from_iterable(iterables, threaded=threaded)
534
+ return _chain.from_iterable(iterables) # type: ignore
535
+
536
+
473
537
  @overload
474
538
  def chunked[T](
475
539
  iterable: Iterable[T],
476
540
  n: int = 1,
477
541
  /,
542
+ threaded: bool = False,
478
543
  ) -> Iterator[Sequence[T]]:
479
544
  ...
480
545
  @overload
@@ -482,12 +547,14 @@ def chunked[T](
482
547
  iterable: AsyncIterable[T],
483
548
  n: int = 1,
484
549
  /,
550
+ threaded: bool = False,
485
551
  ) -> AsyncIterator[Sequence[T]]:
486
552
  ...
487
553
  def chunked[T](
488
554
  iterable: Iterable[T] | AsyncIterable[T],
489
555
  n: int = 1,
490
556
  /,
557
+ threaded: bool = False,
491
558
  ) -> Iterator[Sequence[T]] | AsyncIterator[Sequence[T]]:
492
559
  """
493
560
  """
@@ -497,10 +564,10 @@ def chunked[T](
497
564
  if n == 1:
498
565
  return ((e,) for e in iterable)
499
566
  return (iterable[i:j] for i, j in pairwise(range(0, len(iterable)+n, n)))
500
- elif isinstance(iterable, Iterable):
567
+ elif not threaded and isinstance(iterable, Iterable):
501
568
  return batched(iterable, n)
502
569
  else:
503
- return async_batched(iterable, n)
570
+ return async_batched(iterable, n, threaded=threaded)
504
571
 
505
572
 
506
573
  def foreach(
@@ -508,11 +575,12 @@ def foreach(
508
575
  iterable: Iterable | AsyncIterable,
509
576
  /,
510
577
  *iterables: Iterable | AsyncIterable,
578
+ threaded: bool = False,
511
579
  ):
512
580
  """
513
581
  """
514
- if not (isinstance(iterable, Iterable) and all(isinstance(it, Iterable) for it in iterables)):
515
- return async_foreach(value, iterable, *iterables)
582
+ if threaded or not (isinstance(iterable, Iterable) and all(isinstance(it, Iterable) for it in iterables)):
583
+ return async_foreach(value, iterable, *iterables, threaded=threaded)
516
584
  if iterables:
517
585
  for args in _zip(iterable, *iterables):
518
586
  value(*args)
@@ -543,11 +611,12 @@ def through(
543
611
  iterable: Iterable | AsyncIterable,
544
612
  /,
545
613
  take_while: None | Callable = None,
614
+ threaded: bool = False,
546
615
  ):
547
616
  """
548
617
  """
549
- if not isinstance(iterable, Iterable):
550
- return async_through(iterable, take_while)
618
+ if threaded or not isinstance(iterable, Iterable):
619
+ return async_through(iterable, take_while, threaded=threaded)
551
620
  if take_while is None:
552
621
  for _ in iterable:
553
622
  pass
@@ -584,6 +653,7 @@ def flatten(
584
653
  iterable: Iterable,
585
654
  /,
586
655
  exclude_types: type | tuple[type, ...] = (Buffer, str),
656
+ threaded: bool = False,
587
657
  ) -> Iterator:
588
658
  ...
589
659
  @overload
@@ -591,17 +661,19 @@ def flatten(
591
661
  iterable: AsyncIterable,
592
662
  /,
593
663
  exclude_types: type | tuple[type, ...] = (Buffer, str),
664
+ threaded: bool = False,
594
665
  ) -> AsyncIterator:
595
666
  ...
596
667
  def flatten(
597
668
  iterable: Iterable | AsyncIterable,
598
669
  /,
599
670
  exclude_types: type | tuple[type, ...] = (Buffer, str),
671
+ threaded: bool = False,
600
672
  ) -> Iterator | AsyncIterator:
601
673
  """
602
674
  """
603
- if not isinstance(iterable, Iterable):
604
- return async_flatten(iterable, exclude_types)
675
+ if threaded or not isinstance(iterable, Iterable):
676
+ return async_flatten(iterable, exclude_types, threaded=threaded)
605
677
  def gen(iterable):
606
678
  for e in iterable:
607
679
  if isinstance(e, (Iterable, AsyncIterable)) and not isinstance(e, exclude_types):
@@ -632,6 +704,7 @@ def collect[K, V](
632
704
  iterable: Iterable[tuple[K, V]] | Mapping[K, V],
633
705
  /,
634
706
  rettype: Callable[[Iterable[tuple[K, V]]], MutableMapping[K, V]],
707
+ threaded: bool = False,
635
708
  ) -> MutableMapping[K, V]:
636
709
  ...
637
710
  @overload
@@ -639,6 +712,7 @@ def collect[T](
639
712
  iterable: Iterable[T],
640
713
  /,
641
714
  rettype: Callable[[Iterable[T]], Collection[T]] = list,
715
+ threaded: bool = False,
642
716
  ) -> Collection[T]:
643
717
  ...
644
718
  @overload
@@ -646,6 +720,7 @@ def collect[K, V](
646
720
  iterable: AsyncIterable[tuple[K, V]],
647
721
  /,
648
722
  rettype: Callable[[Iterable[tuple[K, V]]], MutableMapping[K, V]],
723
+ threaded: bool = False,
649
724
  ) -> Coroutine[Any, Any, MutableMapping[K, V]]:
650
725
  ...
651
726
  @overload
@@ -653,17 +728,19 @@ def collect[T](
653
728
  iterable: AsyncIterable[T],
654
729
  /,
655
730
  rettype: Callable[[Iterable[T]], Collection[T]] = list,
731
+ threaded: bool = False,
656
732
  ) -> Coroutine[Any, Any, Collection[T]]:
657
733
  ...
658
734
  def collect(
659
735
  iterable: Iterable | AsyncIterable | Mapping,
660
736
  /,
661
737
  rettype: Callable[[Iterable], Collection] = list,
738
+ threaded: bool = False,
662
739
  ) -> Collection | Coroutine[Any, Any, Collection]:
663
740
  """
664
741
  """
665
- if not isinstance(iterable, Iterable):
666
- return async_collect(iterable, rettype)
742
+ if threaded or not isinstance(iterable, Iterable):
743
+ return async_collect(iterable, rettype, threaded=threaded)
667
744
  return rettype(iterable)
668
745
 
669
746
 
@@ -672,6 +749,7 @@ def group_collect[K, V, C: Container](
672
749
  iterable: Iterable[tuple[K, V]],
673
750
  mapping: None = None,
674
751
  factory: None | C | Callable[[], C] = None,
752
+ threaded: bool = False,
675
753
  ) -> dict[K, C]:
676
754
  ...
677
755
  @overload
@@ -679,6 +757,7 @@ def group_collect[K, V, C: Container, M: MutableMapping](
679
757
  iterable: Iterable[tuple[K, V]],
680
758
  mapping: M,
681
759
  factory: None | C | Callable[[], C] = None,
760
+ threaded: bool = False,
682
761
  ) -> M:
683
762
  ...
684
763
  @overload
@@ -686,6 +765,7 @@ def group_collect[K, V, C: Container](
686
765
  iterable: AsyncIterable[tuple[K, V]],
687
766
  mapping: None = None,
688
767
  factory: None | C | Callable[[], C] = None,
768
+ threaded: bool = False,
689
769
  ) -> Coroutine[Any, Any, dict[K, C]]:
690
770
  ...
691
771
  @overload
@@ -693,17 +773,19 @@ def group_collect[K, V, C: Container, M: MutableMapping](
693
773
  iterable: AsyncIterable[tuple[K, V]],
694
774
  mapping: M,
695
775
  factory: None | C | Callable[[], C] = None,
776
+ threaded: bool = False,
696
777
  ) -> Coroutine[Any, Any, M]:
697
778
  ...
698
779
  def group_collect[K, V, C: Container, M: MutableMapping](
699
780
  iterable: Iterable[tuple[K, V]] | AsyncIterable[tuple[K, V]],
700
781
  mapping: None | M = None,
701
782
  factory: None | C | Callable[[], C] = None,
783
+ threaded: bool = False,
702
784
  ) -> dict[K, C] | M | Coroutine[Any, Any, dict[K, C]] | Coroutine[Any, Any, M]:
703
785
  """
704
786
  """
705
- if not isinstance(iterable, Iterable):
706
- return async_group_collect(iterable, mapping, factory)
787
+ if threaded or not isinstance(iterable, Iterable):
788
+ return async_group_collect(iterable, mapping, factory, threaded=threaded)
707
789
  if factory is None:
708
790
  if isinstance(mapping, defaultdict):
709
791
  factory = mapping.default_factory
@@ -800,6 +882,7 @@ def iter_unique[T](
800
882
  iterable: Iterable[T],
801
883
  /,
802
884
  seen: None | MutableSet = None,
885
+ threaded: bool = False,
803
886
  ) -> Iterator[T]:
804
887
  ...
805
888
  @overload
@@ -807,17 +890,19 @@ def iter_unique[T](
807
890
  iterable: AsyncIterable[T],
808
891
  /,
809
892
  seen: None | MutableSet = None,
893
+ threaded: bool = False,
810
894
  ) -> AsyncIterator[T]:
811
895
  ...
812
896
  def iter_unique[T](
813
897
  iterable: Iterable[T] | AsyncIterable[T],
814
898
  /,
815
899
  seen: None | MutableSet = None,
900
+ threaded: bool = False,
816
901
  ) -> Iterator[T] | AsyncIterator[T]:
817
902
  """
818
903
  """
819
- if not isinstance(iterable, Iterable):
820
- return async_iter_unique(iterable, seen)
904
+ if threaded or not isinstance(iterable, Iterable):
905
+ return async_iter_unique(iterable, seen, threaded=threaded)
821
906
  if seen is None:
822
907
  seen = set()
823
908
  def gen(iterable):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-iterutils
3
- Version: 0.2.4.1
3
+ Version: 0.2.5
4
4
  Summary: Python another itertools.
5
5
  Home-page: https://github.com/ChenyangGao/web-mount-packs/tree/main/python-module/python-iterutils
6
6
  License: MIT
@@ -20,7 +20,7 @@ Classifier: Programming Language :: Python :: 3 :: Only
20
20
  Classifier: Topic :: Software Development
21
21
  Classifier: Topic :: Software Development :: Libraries
22
22
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
- Requires-Dist: python-asynctools (>=0.1.2)
23
+ Requires-Dist: python-asynctools (>=0.1.3.4)
24
24
  Requires-Dist: python-texttools (>=0.0.3)
25
25
  Requires-Dist: python-undefined (>=0.0.3)
26
26
  Project-URL: Repository, https://github.com/ChenyangGao/web-mount-packs/tree/main/python-module/python-iterutils
@@ -0,0 +1,7 @@
1
+ LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
2
+ iterutils/__init__.py,sha256=GJWB55mT2qVPXmSKIR0qfVQXiH2_7wZwpQTLVSNmqwg,33272
3
+ iterutils/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ python_iterutils-0.2.5.dist-info/LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
5
+ python_iterutils-0.2.5.dist-info/METADATA,sha256=boKzeiFl7sWgEEk0XU9MShqgHHzbUbqAn37UWikXmrE,1427
6
+ python_iterutils-0.2.5.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
7
+ python_iterutils-0.2.5.dist-info/RECORD,,
@@ -1,7 +0,0 @@
1
- LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
2
- iterutils/__init__.py,sha256=PW8t1JlDHbCxjkGy5zS-N0ciichPcweQUnmQ8VVjPZM,30357
3
- iterutils/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- python_iterutils-0.2.4.1.dist-info/LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
5
- python_iterutils-0.2.4.1.dist-info/METADATA,sha256=0GJMUTpixBKxJj_YZHvwHPUzry3zhTI0jU11H7vrGQs,1427
6
- python_iterutils-0.2.4.1.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
7
- python_iterutils-0.2.4.1.dist-info/RECORD,,