python-filewrap 0.0.2__py3-none-any.whl → 0.0.3__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.
filewrap/__init__.py CHANGED
@@ -2,14 +2,15 @@
2
2
  # encoding: utf-8
3
3
 
4
4
  __author__ = "ChenyangGao <https://chenyanggao.github.io>"
5
- __version__ = (0, 0, 2)
5
+ __version__ = (0, 0, 3)
6
6
  __all__ = [
7
7
  "SupportsRead", "SupportsWrite", "bio_chunk_iter", "bio_chunk_async_iter",
8
- "bio_skip_iter", "bio_skip_async_iter", "bio_skip_bytes", "bio_skip_bytes_async"
8
+ "bio_skip_iter", "bio_skip_async_iter", "bio_skip_bytes", "bio_skip_bytes_async",
9
+ "bytes_iter_to_reader", "bytes_iter_to_reader_async",
9
10
  ]
10
11
 
11
12
  from asyncio import to_thread
12
- from collections.abc import Awaitable
13
+ from collections.abc import Awaitable, AsyncIterable, Iterable
13
14
  from functools import update_wrapper
14
15
  from inspect import isawaitable, iscoroutinefunction
15
16
  from collections.abc import AsyncIterator, Callable, Iterator
@@ -36,6 +37,7 @@ def ensure_async(func, /):
36
37
  ret = to_thread(func, *args, **kwds)
37
38
  if isawaitable(ret):
38
39
  ret = await ret
40
+ return ret
39
41
  return update_wrapper(wrapper, func)
40
42
 
41
43
 
@@ -261,3 +263,51 @@ async def bio_skip_bytes_async(
261
263
  async for _ in bio_skip_async_iter(bio, size, chunksize, callback=callback):
262
264
  pass
263
265
 
266
+
267
+ def bytes_iter_to_reader(it: Iterable[bytes | bytearray], /) -> SupportsRead[bytes]:
268
+ get_next = iter(it).__next__
269
+ unconsumed = bytearray(b"")
270
+ def read(n=-1):
271
+ nonlocal unconsumed
272
+ if n == 0:
273
+ return b""
274
+ try:
275
+ if n < 0:
276
+ while True:
277
+ unconsumed.extend(get_next())
278
+ else:
279
+ while n > len(unconsumed):
280
+ unconsumed.extend(get_next())
281
+ b, unconsumed = unconsumed[:n], unconsumed[n:]
282
+ return bytes(b)
283
+ except StopIteration:
284
+ return bytes(unconsumed)
285
+ reprs = f"<reader for {it!r}>"
286
+ return type("reader", (), {"read": staticmethod(read), "__repr__": staticmethod(lambda: reprs)})()
287
+
288
+
289
+ def bytes_iter_to_reader_async(it: Iterable[bytes | bytearray] | AsyncIterable[bytes | bytearray], /) -> SupportsRead[bytes]:
290
+ unconsumed = bytearray(b"")
291
+ if isinstance(it, AsyncIterable):
292
+ get_next = aiter(it).__anext__
293
+ else:
294
+ sync_next = iter(it).__next__
295
+ get_next = lambda: to_thread(sync_next)
296
+ async def read(n=-1):
297
+ nonlocal unconsumed
298
+ if n == 0:
299
+ return b""
300
+ try:
301
+ if n < 0:
302
+ while True:
303
+ unconsumed.extend(await get_next())
304
+ else:
305
+ while n > len(unconsumed):
306
+ unconsumed.extend(await get_next())
307
+ b, unconsumed = unconsumed[:n], unconsumed[n:]
308
+ return bytes(b)
309
+ except StopIteration:
310
+ return bytes(unconsumed)
311
+ reprs = f"<reader for {it!r}>"
312
+ return type("reader", (), {"read": staticmethod(read), "__repr__": staticmethod(lambda: reprs)})()
313
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-filewrap
3
- Version: 0.0.2
3
+ Version: 0.0.3
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
@@ -0,0 +1,7 @@
1
+ LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
2
+ filewrap/__init__.py,sha256=Q-2Vh8EycWNA2aEmNGKAJHHuEKpdn89JTmOKJWl21go,9765
3
+ filewrap/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ python_filewrap-0.0.3.dist-info/LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
5
+ python_filewrap-0.0.3.dist-info/METADATA,sha256=n-AMSKOYJZ4eiVIwDEeziJkFkCjW1Mkg6jJZSrXBiyo,1329
6
+ python_filewrap-0.0.3.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
7
+ python_filewrap-0.0.3.dist-info/RECORD,,
@@ -1,7 +0,0 @@
1
- LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
2
- filewrap/__init__.py,sha256=HDbAgI-SEoZP-mvRQCjv2SMM0ZbvcCO5itACB1gWzb8,7929
3
- filewrap/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- python_filewrap-0.0.2.dist-info/LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
5
- python_filewrap-0.0.2.dist-info/METADATA,sha256=5jGrUIgRZkdIou3LzIx7wHq-giQiS8vyZivyu2ClqsY,1329
6
- python_filewrap-0.0.2.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
7
- python_filewrap-0.0.2.dist-info/RECORD,,