python-filewrap 0.1.0.1__tar.gz → 0.1.1__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-filewrap
3
- Version: 0.1.0.1
3
+ Version: 0.1.1
4
4
  Summary: Python file wrappers.
5
5
  Home-page: https://github.com/ChenyangGao/web-mount-packs/tree/main/python-module/python-filewrap
6
6
  License: MIT
@@ -2,7 +2,7 @@
2
2
  # encoding: utf-8
3
3
 
4
4
  __author__ = "ChenyangGao <https://chenyanggao.github.io>"
5
- __version__ = (0, 1)
5
+ __version__ = (0, 1, 1)
6
6
  __all__ = [
7
7
  "Buffer", "SupportsRead", "SupportsReadinto",
8
8
  "SupportsWrite", "SupportsSeek",
@@ -12,16 +12,17 @@ __all__ = [
12
12
  "bytes_iter_to_reader", "bytes_iter_to_async_reader",
13
13
  "bytes_to_chunk_iter", "bytes_to_chunk_async_iter",
14
14
  "bytes_ensure_part_iter", "bytes_ensure_part_async_iter",
15
+ "progress_bytes_iter", "progress_bytes_async_iter",
15
16
  ]
16
17
 
17
18
  from asyncio import to_thread, Lock as AsyncLock
18
19
  from collections.abc import Awaitable, AsyncIterable, AsyncIterator, Callable, Iterable, Iterator
19
20
  from functools import update_wrapper
20
- from inspect import isawaitable, iscoroutinefunction
21
+ from inspect import isawaitable, iscoroutinefunction, isasyncgen, isgenerator
21
22
  from itertools import chain
22
23
  from shutil import COPY_BUFSIZE # type: ignore
23
24
  from threading import Lock
24
- from typing import runtime_checkable, Any, Protocol, TypeVar
25
+ from typing import runtime_checkable, Any, ParamSpec, Protocol, TypeVar
25
26
 
26
27
  try:
27
28
  from collections.abc import Buffer # type: ignore
@@ -59,10 +60,10 @@ except ImportError:
59
60
  Buffer.register(memoryview)
60
61
  Buffer.register(array)
61
62
 
62
-
63
63
  from asynctools import async_chain, ensure_async, ensure_aiter
64
64
 
65
65
 
66
+ Args = ParamSpec("Args")
66
67
  _T_co = TypeVar("_T_co", covariant=True)
67
68
  _T_contra = TypeVar("_T_contra", contravariant=True)
68
69
 
@@ -655,3 +656,71 @@ async def bytes_ensure_part_async_iter(
655
656
  else:
656
657
  n = partsize
657
658
 
659
+
660
+ def progress_bytes_iter(
661
+ it: Iterable[Buffer],
662
+ make_progress: None | Callable[Args, Any] = None,
663
+ /,
664
+ *args: Args.args,
665
+ **kwds: Args.kwargs,
666
+ ) -> Iterator[Buffer]:
667
+ update_progress: None | Callable = None
668
+ close_progress: None | Callable = None
669
+ if callable(make_progress):
670
+ progress = make_progress(*args, **kwds)
671
+ if isgenerator(progress):
672
+ next(progress)
673
+ update_progress = progress.send
674
+ close_progress = progress.close
675
+ else:
676
+ update_progress = progress
677
+ close_progress = getattr(progress, "close", None)
678
+ try:
679
+ if callable(update_progress):
680
+ for chunk in it:
681
+ yield chunk
682
+ update_progress(len(chunk))
683
+ else:
684
+ for chunk in it:
685
+ yield chunk
686
+ finally:
687
+ if callable(close_progress):
688
+ close_progress()
689
+
690
+
691
+ async def progress_bytes_async_iter(
692
+ it: Iterable[Buffer] | AsyncIterable[Buffer],
693
+ make_progress: None | Callable[Args, Any] = None,
694
+ /,
695
+ *args: Args.args,
696
+ **kwds: Args.kwargs,
697
+ ) -> AsyncIterator[Buffer]:
698
+ update_progress: None | Callable = None
699
+ close_progress: None | Callable = None
700
+ if callable(make_progress):
701
+ progress = make_progress(*args, **kwds)
702
+ if isgenerator(progress):
703
+ await ensure_async(next)(progress)
704
+ update_progress = progress.send
705
+ close_progress = progress.close
706
+ elif isasyncgen(progress):
707
+ await anext(progress)
708
+ update_progress = progress.asend
709
+ close_progress = progress.aclose
710
+ else:
711
+ update_progress = progress
712
+ close_progress = getattr(progress, "close", None)
713
+ try:
714
+ it = ensure_aiter(it)
715
+ if callable(update_progress):
716
+ update_progress = ensure_async(update_progress)
717
+ async for chunk in it:
718
+ yield chunk
719
+ await update_progress(len(chunk))
720
+ else:
721
+ async for chunk in it:
722
+ yield chunk
723
+ finally:
724
+ if callable(close_progress):
725
+ await ensure_async(close_progress)()
726
+
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "python-filewrap"
3
- version = "0.1.0.1"
3
+ version = "0.1.1"
4
4
  description = "Python file wrappers."
5
5
  authors = ["ChenyangGao <wosiwujm@gmail.com>"]
6
6
  license = "MIT"