python-iterutils 0.1.3.1__tar.gz → 0.1.4__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-iterutils
3
- Version: 0.1.3.1
3
+ Version: 0.1.4
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
@@ -21,6 +21,7 @@ Classifier: Topic :: Software Development
21
21
  Classifier: Topic :: Software Development :: Libraries
22
22
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
23
  Requires-Dist: python-asynctools (>=0.0.10)
24
+ Requires-Dist: python-texttools (>=0.0.3)
24
25
  Requires-Dist: python-undefined (>=0.0.3)
25
26
  Project-URL: Repository, https://github.com/ChenyangGao/web-mount-packs/tree/main/python-module/python-iterutils
26
27
  Description-Content-Type: text/markdown
@@ -2,30 +2,34 @@
2
2
  # encoding: utf-8
3
3
 
4
4
  __author__ = "ChenyangGao <https://chenyanggao.github.io>"
5
- __version__ = (0, 1, 3)
5
+ __version__ = (0, 1, 4)
6
6
  __all__ = [
7
7
  "Return", "Yield", "YieldFrom", "iterable", "async_iterable", "foreach", "async_foreach",
8
- "through", "async_through", "flatten", "async_flatten", "map", "filter", "reduce", "chunked",
9
- "iter_unique", "async_iter_unique", "wrap_iter", "wrap_aiter", "acc_step", "cut_iter",
10
- "run_gen_step", "run_gen_step_iter", "bfs_gen", "with_iter_next",
8
+ "through", "async_through", "flatten", "async_flatten", "map", "filter", "reduce", "zip",
9
+ "chunked", "iter_unique", "async_iter_unique", "wrap_iter", "wrap_aiter", "acc_step",
10
+ "cut_iter", "run_gen_step", "run_gen_step_iter", "bfs_gen", "with_iter_next", "backgroud_loop",
11
11
  ]
12
12
 
13
13
  from abc import ABC, abstractmethod
14
- from asyncio import to_thread
14
+ from asyncio import create_task, sleep as async_sleep, to_thread
15
+ from builtins import map as _map, filter as _filter, zip as _zip
15
16
  from collections import deque
16
17
  from collections.abc import (
17
18
  AsyncIterable, AsyncIterator, Awaitable, Buffer, Callable, Generator,
18
19
  Iterable, Iterator, MutableSet, Sequence,
19
20
  )
20
- from contextlib import contextmanager
21
+ from contextlib import asynccontextmanager, contextmanager
21
22
  from dataclasses import dataclass
22
23
  from itertools import batched, pairwise
23
24
  from inspect import isawaitable, iscoroutinefunction
24
- from typing import overload, Any, ContextManager, Literal
25
+ from _thread import start_new_thread
26
+ from time import sleep, time
27
+ from typing import overload, Any, AsyncContextManager, ContextManager, Literal
25
28
 
26
29
  from asynctools import (
27
30
  async_filter, async_map, async_reduce, async_zip, async_batched, ensure_async, ensure_aiter,
28
31
  )
32
+ from texttools import format_time
29
33
  from undefined import undefined, Undefined
30
34
 
31
35
 
@@ -76,7 +80,7 @@ def foreach(
76
80
  if not (isinstance(iterable, Iterable) and all(isinstance(it, Iterable) for it in iterables)):
77
81
  return async_foreach(value, iterable, *iterables)
78
82
  if iterables:
79
- for args in zip(iterable, *iterables):
83
+ for args in _zip(iterable, *iterables):
80
84
  value(*args)
81
85
  else:
82
86
  for arg in iterable:
@@ -110,8 +114,7 @@ def through(
110
114
  for _ in iterable:
111
115
  pass
112
116
  else:
113
- from builtins import map
114
- for v in map(take_while, iterable):
117
+ for v in _map(take_while, iterable):
115
118
  if not v:
116
119
  break
117
120
 
@@ -199,11 +202,10 @@ def map(
199
202
  return async_map(function, iterable, *iterables)
200
203
  if function is None:
201
204
  if iterables:
202
- return zip(iterable, *iterables)
205
+ return _zip(iterable, *iterables)
203
206
  else:
204
207
  return iterable
205
- from builtins import map
206
- return map(function, iterable, *iterables)
208
+ return _map(function, iterable, *iterables)
207
209
 
208
210
 
209
211
  def filter(
@@ -213,8 +215,7 @@ def filter(
213
215
  ):
214
216
  if iscoroutinefunction(function) or isinstance(iterable, AsyncIterable):
215
217
  return async_filter(function, iterable)
216
- from builtins import filter
217
- return filter(function, iterable)
218
+ return _filter(function, iterable)
218
219
 
219
220
 
220
221
  def reduce(
@@ -231,6 +232,16 @@ def reduce(
231
232
  return reduce(function, iterable, initial)
232
233
 
233
234
 
235
+ def zip(
236
+ iterable: Iterable | AsyncIterable,
237
+ /,
238
+ *iterables: Iterable | AsyncIterable,
239
+ ):
240
+ if isinstance(iterable, AsyncIterable) or any(isinstance(i, AsyncIterable) for i in iterables):
241
+ return async_zip(iterable, *iterables)
242
+ return _zip(iterable, *iterables)
243
+
244
+
234
245
  @overload
235
246
  def chunked[T](
236
247
  iterable: Iterable[T],
@@ -757,3 +768,69 @@ def with_iter_next[T](
757
768
  except StopIteration:
758
769
  pass
759
770
 
771
+
772
+ @overload
773
+ def backgroud_loop(
774
+ call: None | Callable = None,
775
+ /,
776
+ interval: int | float = 0.05,
777
+ *,
778
+ async_: Literal[False] = False,
779
+ ) -> ContextManager:
780
+ ...
781
+ @overload
782
+ def backgroud_loop(
783
+ call: None | Callable = None,
784
+ /,
785
+ interval: int | float = 0.05,
786
+ *,
787
+ async_: Literal[True],
788
+ ) -> AsyncContextManager:
789
+ ...
790
+ def backgroud_loop(
791
+ call: None | Callable = None,
792
+ /,
793
+ interval: int | float = 0.05,
794
+ *,
795
+ async_: Literal[False, True] = False,
796
+ ) -> ContextManager | AsyncContextManager:
797
+ use_default_call = not callable(call)
798
+ if use_default_call:
799
+ start = time()
800
+ def call():
801
+ print(f"\r\x1b[K{format_time(time() - start)}", end="")
802
+ def run():
803
+ while running:
804
+ try:
805
+ yield call
806
+ except Exception:
807
+ pass
808
+ if interval > 0:
809
+ if async_:
810
+ yield async_sleep(interval)
811
+ else:
812
+ sleep(interval)
813
+ running = True
814
+ if async_:
815
+ async def actx():
816
+ nonlocal running
817
+ try:
818
+ task = create_task(run())
819
+ yield task
820
+ finally:
821
+ running = False
822
+ task.cancel()
823
+ if use_default_call:
824
+ print("\r\x1b[K", end="")
825
+ return asynccontextmanager(actx)()
826
+ else:
827
+ def ctx():
828
+ nonlocal running
829
+ try:
830
+ yield start_new_thread(run, ())
831
+ finally:
832
+ running = False
833
+ if use_default_call:
834
+ print("\r\x1b[K", end="")
835
+ return contextmanager(ctx)()
836
+
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "python-iterutils"
3
- version = "0.1.3.1"
3
+ version = "0.1.4"
4
4
  description = "Python another itertools."
5
5
  authors = ["ChenyangGao <wosiwujm@gmail.com>"]
6
6
  license = "MIT"
@@ -28,6 +28,7 @@ include = [
28
28
  [tool.poetry.dependencies]
29
29
  python = "^3.12"
30
30
  python-asynctools = ">=0.0.10"
31
+ python-texttools = ">=0.0.3"
31
32
  python-undefined = ">=0.0.3"
32
33
 
33
34
  [build-system]