python-filewrap 0.0.5__py3-none-any.whl → 0.0.7__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,25 +2,33 @@
2
2
  # encoding: utf-8
3
3
 
4
4
  __author__ = "ChenyangGao <https://chenyanggao.github.io>"
5
- __version__ = (0, 0, 5)
5
+ __version__ = (0, 0, 7)
6
6
  __all__ = [
7
7
  "SupportsRead", "SupportsWrite",
8
8
  "bio_chunk_iter", "bio_chunk_async_iter",
9
9
  "bio_skip_iter", "bio_skip_async_iter",
10
+ "bytes_iter_skip", "bytes_async_iter_skip",
10
11
  "bytes_iter_to_reader", "bytes_iter_to_async_reader",
11
- "bytes_to_chunk_iter", "bytes_to_chunk_async_iter"
12
+ "bytes_to_chunk_iter", "bytes_to_chunk_async_iter",
13
+ "bytes_ensure_part_iter", "bytes_ensure_part_async_iter",
12
14
  ]
13
15
 
14
16
  from asyncio import to_thread, Lock as AsyncLock
15
17
  from collections.abc import Awaitable, AsyncIterable, Iterable
16
18
  from functools import update_wrapper
17
19
  from inspect import isawaitable, iscoroutinefunction
20
+ from itertools import chain
18
21
  from collections.abc import AsyncIterator, Callable, Iterator
19
22
  from shutil import COPY_BUFSIZE # type: ignore
20
23
  from threading import Lock
21
24
  from typing import Any, Protocol, TypeVar
22
25
 
23
- from asynctools import ensure_async
26
+ try:
27
+ from collections.abc import Buffer # type: ignore
28
+ except ImportError:
29
+ Buffer = Any
30
+
31
+ from asynctools import async_chain, ensure_async, ensure_aiter
24
32
 
25
33
 
26
34
  _T_co = TypeVar("_T_co", covariant=True)
@@ -36,12 +44,12 @@ class SupportsWrite(Protocol[_T_contra]):
36
44
 
37
45
 
38
46
  def bio_chunk_iter(
39
- bio: SupportsRead[bytes] | Callable[[int], bytes],
47
+ bio: SupportsRead[Buffer] | Callable[[int], Buffer],
40
48
  /,
41
49
  size: int = -1,
42
50
  chunksize: int = COPY_BUFSIZE,
43
51
  callback: None | Callable[[int], Any] = None,
44
- ) -> Iterator[bytes]:
52
+ ) -> Iterator[Buffer]:
45
53
  if callable(bio):
46
54
  read = bio
47
55
  else:
@@ -67,12 +75,12 @@ def bio_chunk_iter(
67
75
 
68
76
 
69
77
  async def bio_chunk_async_iter(
70
- bio: SupportsRead[bytes] | Callable[[int], bytes | Awaitable[bytes]],
78
+ bio: SupportsRead[Buffer] | Callable[[int], Buffer | Awaitable[Buffer]],
71
79
  /,
72
80
  size: int = -1,
73
81
  chunksize: int = COPY_BUFSIZE,
74
82
  callback: None | Callable[[int], Any] = None,
75
- ) -> AsyncIterator[bytes]:
83
+ ) -> AsyncIterator[Buffer]:
76
84
  if callable(bio):
77
85
  read = ensure_async(bio)
78
86
  else:
@@ -97,7 +105,7 @@ async def bio_chunk_async_iter(
97
105
 
98
106
 
99
107
  def bio_skip_iter(
100
- bio: SupportsRead[bytes] | Callable[[int], bytes],
108
+ bio: SupportsRead[Buffer] | Callable[[int], Buffer],
101
109
  /,
102
110
  size: int = -1,
103
111
  chunksize: int = COPY_BUFSIZE,
@@ -168,7 +176,7 @@ def bio_skip_iter(
168
176
 
169
177
 
170
178
  async def bio_skip_async_iter(
171
- bio: SupportsRead[bytes] | Callable[[int], bytes | Awaitable[bytes]],
179
+ bio: SupportsRead[Buffer] | Callable[[int], Buffer | Awaitable[Buffer]],
172
180
  /,
173
181
  size: int = -1,
174
182
  chunksize: int = COPY_BUFSIZE,
@@ -236,8 +244,59 @@ async def bio_skip_async_iter(
236
244
  yield length
237
245
 
238
246
 
247
+ def bytes_iter_skip(
248
+ it: Iterable[Buffer],
249
+ /,
250
+ size: int = -1,
251
+ callback: None | Callable[[int], Any] = None,
252
+ ) -> Iterator[memoryview | Buffer]:
253
+ it = iter(it)
254
+ if size == 0:
255
+ return it
256
+ if not callable(callback):
257
+ callback = None
258
+ for m in map(memoryview, it):
259
+ l = len(m)
260
+ if callback:
261
+ callback(min(l, size))
262
+ if l == size:
263
+ return it
264
+ elif l > size:
265
+ return chain((m[size:],), it)
266
+ else:
267
+ size -= l
268
+ return iter(())
269
+
270
+
271
+ async def bytes_async_iter_skip(
272
+ it: Iterable[Buffer] | AsyncIterator[Buffer],
273
+ /,
274
+ size: int = -1,
275
+ callback: None | Callable[[int], Any] = None,
276
+ ) -> AsyncIterator[memoryview | Buffer]:
277
+ it = aiter(ensure_aiter(it))
278
+ if size == 0:
279
+ return it
280
+ callback = ensure_async(callback) if callable(callback) else None
281
+ async for b in it:
282
+ m = memoryview(b)
283
+ l = len(m)
284
+ if callback:
285
+ await callback(min(l, size))
286
+ if l == size:
287
+ return it
288
+ elif l > size:
289
+ return async_chain((m[size:],), it)
290
+ else:
291
+ size -= l
292
+ async def make_iter():
293
+ if False:
294
+ yield
295
+ return make_iter()
296
+
297
+
239
298
  def bytes_iter_to_reader(
240
- it: Iterable[bytes | bytearray],
299
+ it: Iterable[Buffer],
241
300
  /,
242
301
  ) -> SupportsRead[bytearray]:
243
302
  getnext = iter(it).__next__
@@ -325,7 +384,7 @@ def bytes_iter_to_reader(
325
384
 
326
385
 
327
386
  def bytes_iter_to_async_reader(
328
- it: Iterable[bytes | bytearray] | AsyncIterable[bytes | bytearray],
387
+ it: Iterable[Buffer] | AsyncIterable[Buffer],
329
388
  /,
330
389
  threaded: bool = True,
331
390
  ) -> SupportsRead[bytearray]:
@@ -417,9 +476,9 @@ def bytes_iter_to_async_reader(
417
476
 
418
477
 
419
478
  def bytes_to_chunk_iter(
420
- b,
479
+ b: Buffer,
421
480
  /,
422
- chunksize=1<<16,
481
+ chunksize: int = COPY_BUFSIZE,
423
482
  ) -> Iterator[memoryview]:
424
483
  m = memoryview(b)
425
484
  for i in range(0, len(m), chunksize):
@@ -427,11 +486,67 @@ def bytes_to_chunk_iter(
427
486
 
428
487
 
429
488
  async def bytes_to_chunk_async_iter(
430
- b,
489
+ b: Buffer,
431
490
  /,
432
- chunksize=1<<16,
491
+ chunksize: int = COPY_BUFSIZE,
433
492
  ) -> AsyncIterator[memoryview]:
434
493
  m = memoryview(b)
435
494
  for i in range(0, len(m), chunksize):
436
495
  yield m[i:i+chunksize]
437
496
 
497
+
498
+ def bytes_ensure_part_iter(
499
+ it: Iterable[Buffer],
500
+ /,
501
+ partsize: int = COPY_BUFSIZE,
502
+ ) -> Iterator[Buffer | memoryview]:
503
+ n = partsize
504
+ for b in it:
505
+ m = memoryview(b)
506
+ l = len(m)
507
+ if l <= n:
508
+ yield b
509
+ if l == n:
510
+ n = partsize
511
+ else:
512
+ n -= l
513
+ else:
514
+ yield m[:n]
515
+ m = m[n:]
516
+ while len(m) >= partsize:
517
+ yield m[:partsize]
518
+ m = m[partsize:]
519
+ if m:
520
+ yield m
521
+ n = partsize - len(m)
522
+ else:
523
+ n = partsize
524
+
525
+
526
+ async def bytes_ensure_part_async_iter(
527
+ it: Iterable[Buffer] | AsyncIterable[Buffer],
528
+ /,
529
+ partsize: int = COPY_BUFSIZE,
530
+ ) -> AsyncIterator[Buffer | memoryview]:
531
+ n = partsize
532
+ async for b in ensure_aiter(it):
533
+ m = memoryview(b)
534
+ l = len(m)
535
+ if l <= n:
536
+ yield b
537
+ if l == n:
538
+ n = partsize
539
+ else:
540
+ n -= l
541
+ else:
542
+ yield m[:n]
543
+ m = m[n:]
544
+ while len(m) >= partsize:
545
+ yield m[:partsize]
546
+ m = m[partsize:]
547
+ if m:
548
+ yield m
549
+ n = partsize - len(m)
550
+ else:
551
+ n = partsize
552
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-filewrap
3
- Version: 0.0.5
3
+ Version: 0.0.7
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=X3RWnRcr2wycOIQJomqKRdwh2lA8GWUJJLZb8tDpodU,16575
3
+ filewrap/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ python_filewrap-0.0.7.dist-info/LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
5
+ python_filewrap-0.0.7.dist-info/METADATA,sha256=Tt3qu_XvzzpK7AuNBh5vPGJJpql5ezi9PYosXqctUbY,1362
6
+ python_filewrap-0.0.7.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
7
+ python_filewrap-0.0.7.dist-info/RECORD,,
@@ -1,7 +0,0 @@
1
- LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
2
- filewrap/__init__.py,sha256=hhvcgtUXhPdw1MP_3ujFDuhMC0PZJgqQ9sEvmebfnFc,13683
3
- filewrap/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- python_filewrap-0.0.5.dist-info/LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
5
- python_filewrap-0.0.5.dist-info/METADATA,sha256=gsU9oW_Nzw8ORTz8aKuuvLKak8AP3kwLuJJugm5kDT4,1362
6
- python_filewrap-0.0.5.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
7
- python_filewrap-0.0.5.dist-info/RECORD,,