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 +53 -3
- {python_filewrap-0.0.2.dist-info → python_filewrap-0.0.3.dist-info}/METADATA +1 -1
- python_filewrap-0.0.3.dist-info/RECORD +7 -0
- python_filewrap-0.0.2.dist-info/RECORD +0 -7
- {python_filewrap-0.0.2.dist-info → python_filewrap-0.0.3.dist-info}/LICENSE +0 -0
- {python_filewrap-0.0.2.dist-info → python_filewrap-0.0.3.dist-info}/WHEEL +0 -0
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,
|
|
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
|
+
|
|
@@ -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,,
|
|
File without changes
|
|
File without changes
|