python-filewrap 0.1.2__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-filewrap
3
- Version: 0.1.2
3
+ Version: 0.1.4
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,12 +2,13 @@
2
2
  # encoding: utf-8
3
3
 
4
4
  __author__ = "ChenyangGao <https://chenyanggao.github.io>"
5
- __version__ = (0, 1, 2)
5
+ __version__ = (0, 1, 4)
6
6
  __all__ = [
7
7
  "Buffer", "SupportsRead", "SupportsReadinto",
8
8
  "SupportsWrite", "SupportsSeek",
9
9
  "bio_chunk_iter", "bio_chunk_async_iter",
10
10
  "bio_skip_iter", "bio_skip_async_iter",
11
+ "bytes_iter", "bytes_async_iter",
11
12
  "bytes_iter_skip", "bytes_async_iter_skip",
12
13
  "bytes_iter_to_reader", "bytes_iter_to_async_reader",
13
14
  "bytes_to_chunk_iter", "bytes_to_chunk_async_iter",
@@ -89,7 +90,7 @@ class SupportsSeek(Protocol):
89
90
 
90
91
 
91
92
  def bio_chunk_iter(
92
- bio: SupportsRead[Buffer] | Callable[[int], Buffer],
93
+ bio: SupportsRead[Buffer] | SupportsReadinto | Callable[[int], Buffer],
93
94
  /,
94
95
  size: int = -1,
95
96
  chunksize: int = COPY_BUFSIZE,
@@ -99,11 +100,19 @@ def bio_chunk_iter(
99
100
  use_readinto = False
100
101
  if callable(bio):
101
102
  read = bio
102
- elif can_buffer and hasattr(bio, "readinto"):
103
+ elif can_buffer and isinstance(bio, SupportsReadinto):
103
104
  readinto = bio.readinto
104
105
  use_readinto = True
105
- else:
106
+ elif isinstance(bio, SupportsRead):
106
107
  read = bio.read
108
+ else:
109
+ readinto = bio.readinto
110
+ def read(_):
111
+ buf = bytearray(chunksize)
112
+ length = readinto(buf)
113
+ if length == chunksize:
114
+ return buf
115
+ return buf[:length]
107
116
  if not callable(callback):
108
117
  callback = None
109
118
  if use_readinto:
@@ -150,7 +159,7 @@ def bio_chunk_iter(
150
159
 
151
160
 
152
161
  async def bio_chunk_async_iter(
153
- bio: SupportsRead[Buffer] | Callable[[int], Buffer | Awaitable[Buffer]],
162
+ bio: SupportsRead[Buffer] | SupportsReadinto | Callable[[int], Buffer | Awaitable[Buffer]],
154
163
  /,
155
164
  size: int = -1,
156
165
  chunksize: int = COPY_BUFSIZE,
@@ -159,12 +168,20 @@ async def bio_chunk_async_iter(
159
168
  ) -> AsyncIterator[Buffer]:
160
169
  use_readinto = False
161
170
  if callable(bio):
162
- read = ensure_async(bio)
163
- elif can_buffer and hasattr(bio, "readinto"):
164
- readinto = ensure_async(bio.readinto)
171
+ read = ensure_async(bio, threaded=True)
172
+ elif can_buffer and isinstance(bio, SupportsReadinto):
173
+ readinto = ensure_async(bio.readinto, threaded=True)
165
174
  use_readinto = True
175
+ elif isinstance(bio, SupportsRead):
176
+ read = ensure_async(bio.read, threaded=True)
166
177
  else:
167
- read = ensure_async(bio.read)
178
+ readinto = ensure_async(bio.readinto, threaded=True)
179
+ async def read(_):
180
+ buf = bytearray(chunksize)
181
+ length = await readinto(buf)
182
+ if length == chunksize:
183
+ return buf
184
+ return buf[:length]
168
185
  callback = ensure_async(callback) if callable(callback) else None
169
186
  if use_readinto:
170
187
  buf = bytearray(chunksize)
@@ -210,7 +227,7 @@ async def bio_chunk_async_iter(
210
227
 
211
228
 
212
229
  def bio_skip_iter(
213
- bio: SupportsRead[Buffer] | Callable[[int], Buffer],
230
+ bio: SupportsRead[Buffer] | SupportsReadinto | Callable[[int], Buffer],
214
231
  /,
215
232
  size: int = -1,
216
233
  chunksize: int = COPY_BUFSIZE,
@@ -281,7 +298,7 @@ def bio_skip_iter(
281
298
 
282
299
 
283
300
  async def bio_skip_async_iter(
284
- bio: SupportsRead[Buffer] | Callable[[int], Buffer | Awaitable[Buffer]],
301
+ bio: SupportsRead[Buffer] | SupportsReadinto | Callable[[int], Buffer | Awaitable[Buffer]],
285
302
  /,
286
303
  size: int = -1,
287
304
  chunksize: int = COPY_BUFSIZE,
@@ -292,7 +309,7 @@ async def bio_skip_async_iter(
292
309
  callback = ensure_async(callback) if callable(callback) else None
293
310
  length: int
294
311
  try:
295
- seek = ensure_async(getattr(bio, "seek"))
312
+ seek = ensure_async(getattr(bio, "seek"), threaded=True)
296
313
  curpos = await seek(0, 1)
297
314
  if size > 0:
298
315
  length = (await seek(size, 1)) - curpos
@@ -302,9 +319,9 @@ async def bio_skip_async_iter(
302
319
  if chunksize <= 0:
303
320
  chunksize = COPY_BUFSIZE
304
321
  if callable(bio):
305
- read = ensure_async(bio)
322
+ read = ensure_async(bio, threaded=True)
306
323
  elif hasattr(bio, "readinto"):
307
- readinto = ensure_async(bio.readinto)
324
+ readinto = ensure_async(bio.readinto, threaded=True)
308
325
  buf = bytearray(chunksize)
309
326
  if size > 0:
310
327
  while size >= chunksize:
@@ -328,7 +345,7 @@ async def bio_skip_async_iter(
328
345
  await callback(length)
329
346
  yield length
330
347
  else:
331
- read = ensure_async(bio.read)
348
+ read = ensure_async(bio.read, threaded=True)
332
349
  if size > 0:
333
350
  while size:
334
351
  readsize = min(chunksize, size)
@@ -350,6 +367,67 @@ async def bio_skip_async_iter(
350
367
  yield length
351
368
 
352
369
 
370
+ def bytes_iter(
371
+ it: Iterable[Buffer],
372
+ /,
373
+ size: int = -1,
374
+ callback: None | Callable[[int], Any] = None,
375
+ ) -> Iterator[Buffer]:
376
+ it = iter(it)
377
+ if size < 0:
378
+ yield from it
379
+ return
380
+ elif size == 0:
381
+ return
382
+ for b in it:
383
+ l = len(b)
384
+ if l <= size:
385
+ yield b
386
+ if callback is not None:
387
+ callback(l)
388
+ if l < size:
389
+ size -= l
390
+ else:
391
+ break
392
+ else:
393
+ yield memoryview(b)[:size]
394
+ if callback is not None:
395
+ callback(size)
396
+ break
397
+
398
+
399
+ async def bytes_async_iter(
400
+ it: Iterable[Buffer] | AsyncIterable[Buffer],
401
+ /,
402
+ size: int = -1,
403
+ callback: None | Callable[[int], Any] = None,
404
+ threaded: bool = False,
405
+ ) -> AsyncIterator[Buffer]:
406
+ it = aiter(ensure_aiter(it, threaded=threaded))
407
+ if size < 0:
408
+ async for chunk in it:
409
+ yield chunk
410
+ return
411
+ elif size == 0:
412
+ return
413
+ callback = ensure_async(callback) if callable(callback) else None
414
+ async for b in it:
415
+ l = len(b)
416
+ if l <= size:
417
+ yield b
418
+ if callback is not None:
419
+ await callback(l)
420
+ if l < size:
421
+ size -= l
422
+ else:
423
+ break
424
+ else:
425
+ yield memoryview(b)[:size]
426
+ if callback is not None:
427
+ await callback(size)
428
+ break
429
+
430
+
353
431
  def bytes_iter_skip(
354
432
  it: Iterable[Buffer],
355
433
  /,
@@ -379,8 +457,9 @@ async def bytes_async_iter_skip(
379
457
  /,
380
458
  size: int = -1,
381
459
  callback: None | Callable[[int], Any] = None,
460
+ threaded: bool = False,
382
461
  ) -> AsyncIterator[Buffer]:
383
- it = aiter(ensure_aiter(it))
462
+ it = aiter(ensure_aiter(it, threaded=threaded))
384
463
  if size == 0:
385
464
  return it
386
465
  callback = ensure_async(callback) if callable(callback) else None
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "python-filewrap"
3
- version = "0.1.2"
3
+ version = "0.1.4"
4
4
  description = "Python file wrappers."
5
5
  authors = ["ChenyangGao <wosiwujm@gmail.com>"]
6
6
  license = "MIT"
File without changes