python-filewrap 0.2.9__py3-none-any.whl → 0.3.0__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,18 +2,19 @@
2
2
  # encoding: utf-8
3
3
 
4
4
  __author__ = "ChenyangGao <https://chenyanggao.github.io>"
5
- __version__ = (0, 2, 9)
5
+ __version__ = (0, 3, 0)
6
6
  __all__ = [
7
7
  "SupportsRead", "SupportsReadinto", "SupportsWrite", "SupportsSeek",
8
- "AsyncBufferedReader", "AsyncTextIOWrapper", "buffer_length",
9
- "bio_chunk_iter", "bio_chunk_async_iter", "bio_skip_iter", "bio_skip_async_iter",
10
- "bytes_iter", "bytes_async_iter", "bytes_iter_skip", "bytes_async_iter_skip",
11
- "bytes_iter_to_reader", "bytes_iter_to_async_reader", "bytes_to_chunk_iter",
12
- "bytes_to_chunk_async_iter", "bytes_ensure_part_iter", "bytes_ensure_part_async_iter",
13
- "progress_bytes_iter", "progress_bytes_async_iter", "copyfileobj", "copyfileobj_async",
14
- "bound_bytes_reader", "bound_async_bytes_reader",
8
+ "AsyncBufferedReader", "AsyncTextIOWrapper", "buffer_length", "to_string_buffer",
9
+ "to_bytes_buffer", "bio_chunk_iter", "bio_chunk_async_iter", "bio_skip_iter",
10
+ "bio_skip_async_iter", "bytes_iter", "bytes_async_iter", "bytes_iter_skip",
11
+ "bytes_async_iter_skip", "bytes_iter_to_reader", "bytes_iter_to_async_reader",
12
+ "bytes_to_chunk_iter", "bytes_to_chunk_async_iter", "bytes_ensure_part_iter",
13
+ "bytes_ensure_part_async_iter", "progress_bytes_iter", "progress_bytes_async_iter",
14
+ "copyfileobj", "copyfileobj_async", "bound_bytes_reader", "bound_async_bytes_reader",
15
15
  ]
16
16
 
17
+ from array import array
17
18
  from asyncio import Lock as AsyncLock
18
19
  from codecs import getdecoder, getencoder
19
20
  from collections.abc import (
@@ -120,19 +121,19 @@ class AsyncBufferedReader(BufferedReader):
120
121
 
121
122
  @cached_property
122
123
  def _flush(self, /):
123
- return ensure_async(self.raw.flush, threaded=True)
124
+ return ensure_async(getattr(self.raw, "flush"), threaded=True)
124
125
 
125
126
  @cached_property
126
127
  def _read(self, /):
127
- return ensure_async(self.raw.read, threaded=True)
128
+ return ensure_async(getattr(self.raw, "read"), threaded=True)
128
129
 
129
130
  @cached_property
130
131
  def _readinto(self, /):
131
- return ensure_async(self.raw.readinto, threaded=True)
132
+ return ensure_async(getattr(self.raw, "readinto"), threaded=True)
132
133
 
133
134
  @cached_property
134
135
  def _readline(self, /):
135
- return ensure_async(self.raw.readline, threaded=True)
136
+ return ensure_async(getattr(self.raw, "readline"), threaded=True)
136
137
 
137
138
  @cached_property
138
139
  def _seek(self, /):
@@ -262,7 +263,7 @@ class AsyncBufferedReader(BufferedReader):
262
263
  length = buffer_length(data)
263
264
  self._pos += buffer_length(prev_data) + length
264
265
  if BUFSIZE <= length:
265
- buf_view[:] = memoryview(data)[-BUFSIZE:]
266
+ buf_view[:] = memoryview(data).cast("B")[-BUFSIZE:]
266
267
  self._buf_pos = self._buf_stop = BUFSIZE
267
268
  else:
268
269
  buf_pos_stop = buf_stop + length
@@ -307,7 +308,7 @@ class AsyncBufferedReader(BufferedReader):
307
308
  else:
308
309
  return 0
309
310
  BUFSIZE = buffer_length(buf_view)
310
- buffer_view = memoryview(buffer)
311
+ buffer_view = memoryview(buffer).cast("B")
311
312
  buffer_view[:buf_size] = buf_view[buf_pos:buf_stop]
312
313
  buf_pos = self._buf_pos = buf_stop
313
314
  self._pos += buf_size
@@ -379,7 +380,7 @@ class AsyncBufferedReader(BufferedReader):
379
380
  else:
380
381
  return 0
381
382
  BUFSIZE = buffer_length(buf_view)
382
- buffer_view = memoryview(buffer)
383
+ buffer_view = memoryview(buffer).cast("B")
383
384
  buffer_view[:buf_size] = buf_view[buf_pos:buf_stop]
384
385
  buf_pos = self._buf_pos = buf_stop
385
386
  self._pos += buf_size
@@ -470,7 +471,7 @@ class AsyncBufferedReader(BufferedReader):
470
471
  prev_data = buf_view[buf_pos:buf_stop].tobytes()
471
472
  self._pos += buffer_length(prev_data) + length
472
473
  if BUFSIZE <= length:
473
- buf_view[:] = memoryview(data)[-BUFSIZE:]
474
+ buf_view[:] = memoryview(data).cast("B")[-BUFSIZE:]
474
475
  self._buf_pos = self._buf_stop = BUFSIZE
475
476
  else:
476
477
  buf_pos_stop = buf_stop + length
@@ -656,7 +657,7 @@ class AsyncTextIOWrapper(TextIOWrapper):
656
657
  size -= len(text)
657
658
  return n
658
659
 
659
- cache: bytes | memoryview = memoryview(data)
660
+ cache: bytes | memoryview = memoryview(data).cast("B")
660
661
  while size and buffer_length(data) == size:
661
662
  while cache:
662
663
  try:
@@ -826,9 +827,19 @@ def get_bom(encoding: str, /) -> bytes:
826
827
 
827
828
 
828
829
  def buffer_length(b: Buffer, /) -> int:
829
- if isinstance(b, (bytes, bytearray, memoryview)):
830
+ if isinstance(b, (bytes, bytearray)):
830
831
  return len(b)
831
- return len(memoryview(b))
832
+ return memoryview(b).nbytes
833
+
834
+
835
+ def to_string_buffer(s: str, /) -> array:
836
+ return array("w", s)
837
+
838
+
839
+ def to_bytes_buffer(b: Buffer, /) -> bytes | bytearray | memoryview:
840
+ if isinstance(b, (bytes, bytearray)):
841
+ return b
842
+ return memoryview(b).cast("B")
832
843
 
833
844
 
834
845
  def bio_chunk_iter(
@@ -842,10 +853,10 @@ def bio_chunk_iter(
842
853
  use_readinto = False
843
854
  if callable(bio):
844
855
  read = bio
845
- elif can_buffer and isinstance(bio, SupportsReadinto):
856
+ elif can_buffer and hasattr(bio, "readinto"):
846
857
  readinto = bio.readinto
847
858
  use_readinto = True
848
- elif isinstance(bio, SupportsRead):
859
+ elif hasattr(bio, "read"):
849
860
  read = bio.read
850
861
  else:
851
862
  readinto = bio.readinto
@@ -915,10 +926,10 @@ async def bio_chunk_async_iter(
915
926
  use_readinto = False
916
927
  if callable(bio):
917
928
  read: Callable[[int], Awaitable[Buffer]] = ensure_async(bio, threaded=True)
918
- elif can_buffer and isinstance(bio, SupportsReadinto):
929
+ elif can_buffer and hasattr(bio, "readinto"):
919
930
  readinto = ensure_async(bio.readinto, threaded=True)
920
931
  use_readinto = True
921
- elif isinstance(bio, SupportsRead):
932
+ elif hasattr(bio, "read"):
922
933
  read = ensure_async(bio.read, threaded=True)
923
934
  else:
924
935
  readinto = ensure_async(bio.readinto, threaded=True)
@@ -1140,7 +1151,7 @@ def bytes_iter(
1140
1151
  else:
1141
1152
  break
1142
1153
  else:
1143
- yield memoryview(b)[:size]
1154
+ yield memoryview(b).cast("B")[:size]
1144
1155
  if callback is not None:
1145
1156
  callback(size)
1146
1157
  break
@@ -1172,7 +1183,7 @@ async def bytes_async_iter(
1172
1183
  else:
1173
1184
  break
1174
1185
  else:
1175
- yield memoryview(b)[:size]
1186
+ yield memoryview(b).cast("B")[:size]
1176
1187
  if callback is not None:
1177
1188
  await callback(size)
1178
1189
  break
@@ -1189,8 +1200,8 @@ def bytes_iter_skip(
1189
1200
  return it
1190
1201
  if not callable(callback):
1191
1202
  callback = None
1192
- m: memoryview
1193
- for m in map(memoryview, it): # type: ignore
1203
+ for b in it:
1204
+ m = memoryview(b).cast("B")
1194
1205
  l = buffer_length(m)
1195
1206
  if callback:
1196
1207
  callback(min(l, size))
@@ -1215,7 +1226,7 @@ async def bytes_async_iter_skip(
1215
1226
  return it
1216
1227
  callback = ensure_async(callback) if callable(callback) else None
1217
1228
  async for b in it:
1218
- m = memoryview(b)
1229
+ m = memoryview(b).cast("B")
1219
1230
  l = buffer_length(m)
1220
1231
  if callback:
1221
1232
  await callback(min(l, size))
@@ -1291,8 +1302,9 @@ def bytes_iter_to_reader(
1291
1302
  del unconsumed[:]
1292
1303
  try:
1293
1304
  while True:
1294
- if b := memoryview(getnext()):
1295
- m = n + len(b)
1305
+ b = memoryview(getnext()).cast("B")
1306
+ if b_len := b.nbytes:
1307
+ m = n + b_len
1296
1308
  if m >= bufsize:
1297
1309
  delta = bufsize - n
1298
1310
  buf[n:] = b[:delta]
@@ -1301,7 +1313,7 @@ def bytes_iter_to_reader(
1301
1313
  return bufsize
1302
1314
  else:
1303
1315
  buf[n:m] = b
1304
- pos += len(b)
1316
+ pos += b_len
1305
1317
  n = m
1306
1318
  except StopIteration:
1307
1319
  at_end = True
@@ -1460,8 +1472,9 @@ def bytes_iter_to_async_reader(
1460
1472
  del unconsumed[:]
1461
1473
  try:
1462
1474
  while True:
1463
- if b := memoryview(await getnext()):
1464
- m = n + len(b)
1475
+ b = memoryview(await getnext()).cast("B")
1476
+ if b_len := b.nbytes:
1477
+ m = n + b_len
1465
1478
  if m >= bufsize:
1466
1479
  delta = bufsize - n
1467
1480
  buf[n:] = b[:delta]
@@ -1470,7 +1483,7 @@ def bytes_iter_to_async_reader(
1470
1483
  return bufsize
1471
1484
  else:
1472
1485
  buf[n:m] = b
1473
- pos += len(b)
1486
+ pos += b_len
1474
1487
  n = m
1475
1488
  except (StopIteration, StopAsyncIteration):
1476
1489
  at_end = True
@@ -1566,7 +1579,7 @@ def bytes_to_chunk_iter(
1566
1579
  /,
1567
1580
  chunksize: int = READ_BUFSIZE,
1568
1581
  ) -> Iterator[memoryview]:
1569
- m = memoryview(b)
1582
+ m = memoryview(b).cast("B")
1570
1583
  for i in range(0, buffer_length(m), chunksize):
1571
1584
  yield m[i:i+chunksize]
1572
1585
 
@@ -1576,7 +1589,7 @@ async def bytes_to_chunk_async_iter(
1576
1589
  /,
1577
1590
  chunksize: int = READ_BUFSIZE,
1578
1591
  ) -> AsyncIterator[memoryview]:
1579
- m = memoryview(b)
1592
+ m = memoryview(b).cast("B")
1580
1593
  for i in range(0, buffer_length(m), chunksize):
1581
1594
  yield m[i:i+chunksize]
1582
1595
 
@@ -1588,7 +1601,7 @@ def bytes_ensure_part_iter(
1588
1601
  ) -> Iterator[Buffer]:
1589
1602
  n = partsize
1590
1603
  for b in it:
1591
- m = memoryview(b)
1604
+ m = memoryview(b).cast("B")
1592
1605
  l = buffer_length(m)
1593
1606
  if l <= n:
1594
1607
  yield b
@@ -1616,7 +1629,7 @@ async def bytes_ensure_part_async_iter(
1616
1629
  ) -> AsyncIterator[Buffer]:
1617
1630
  n = partsize
1618
1631
  async for b in ensure_aiter(it):
1619
- m = memoryview(b)
1632
+ m = memoryview(b).cast("B")
1620
1633
  l = buffer_length(m)
1621
1634
  if l <= n:
1622
1635
  yield b
@@ -1730,7 +1743,7 @@ def copyfileobj(
1730
1743
  fsrc_readinto = getattr(fsrc, "readinto", None)
1731
1744
  if callable(fsrc_readinto):
1732
1745
  buf = bytearray(chunksize)
1733
- view = memoryview(buf)
1746
+ view = memoryview(buf).cast("B")
1734
1747
  while size := fsrc_readinto(buf):
1735
1748
  fdst_write(view[:size])
1736
1749
  elif callable(fsrc_read):
@@ -1757,7 +1770,7 @@ async def copyfileobj_async(
1757
1770
  if callable(fsrc_readinto):
1758
1771
  fsrc_readinto = ensure_async(fsrc_readinto, threaded=threaded)
1759
1772
  buf = bytearray(chunksize)
1760
- view = memoryview(buf)
1773
+ view = memoryview(buf).cast("B")
1761
1774
  while size := await fsrc_readinto(buf):
1762
1775
  await fdst_write(view[:size])
1763
1776
  elif callable(fsrc_read):
@@ -1798,7 +1811,7 @@ def bound_bytes_reader(
1798
1811
  if f_readinto is None:
1799
1812
  raise NotImplementedError("readinto")
1800
1813
  if size > 0:
1801
- n = f_readinto(memoryview(buffer)[:size])
1814
+ n = f_readinto(memoryview(buffer).cast("B")[:size])
1802
1815
  size -= n
1803
1816
  return n
1804
1817
  return 0
@@ -1833,7 +1846,7 @@ def bound_async_bytes_reader(
1833
1846
  if f_readinto is None:
1834
1847
  raise NotImplementedError("readinto")
1835
1848
  if size > 0:
1836
- n = await f_readinto(memoryview(buffer)[:size])
1849
+ n = await f_readinto(memoryview(buffer).cast("B")[:size])
1837
1850
  size -= n
1838
1851
  return n
1839
1852
  return 0
@@ -1,9 +1,9 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: python-filewrap
3
- Version: 0.2.9
3
+ Version: 0.3.0
4
4
  Summary: Python file wrappers.
5
- Home-page: https://github.com/ChenyangGao/python-modules/tree/main/python-filewrap
6
5
  License: MIT
6
+ License-File: LICENSE
7
7
  Keywords: file,wrapper
8
8
  Author: ChenyangGao
9
9
  Author-email: wosiwujm@gmail.com
@@ -16,12 +16,14 @@ Classifier: Programming Language :: Python
16
16
  Classifier: Programming Language :: Python :: 3
17
17
  Classifier: Programming Language :: Python :: 3.12
18
18
  Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
19
20
  Classifier: Programming Language :: Python :: 3 :: Only
20
21
  Classifier: Topic :: Software Development
21
22
  Classifier: Topic :: Software Development :: Libraries
22
23
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
24
  Requires-Dist: python-asynctools (>=0.1.3)
24
25
  Requires-Dist: python-property (>=0.0.3)
26
+ Project-URL: Homepage, https://github.com/ChenyangGao/python-modules/tree/main/python-filewrap
25
27
  Project-URL: Repository, https://github.com/ChenyangGao/python-modules/tree/main/python-filewrap
26
28
  Description-Content-Type: text/markdown
27
29
 
@@ -0,0 +1,6 @@
1
+ filewrap/__init__.py,sha256=39yU6QyabFchtrykF_4uiL4y4Ytm2MzeuCd7CCUuhH8,61018
2
+ filewrap/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ python_filewrap-0.3.0.dist-info/METADATA,sha256=X36-8X7woDyEu1LJHgjuDSe99qPm2Suf0Ta7Itl3HIQ,1417
4
+ python_filewrap-0.3.0.dist-info/WHEEL,sha256=EGEvSphFYqXKs23-kQBeyNoJP1nrT8ZJKQoi5p5DYL8,88
5
+ python_filewrap-0.3.0.dist-info/licenses/LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
6
+ python_filewrap-0.3.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.9.1
2
+ Generator: poetry-core 2.4.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2024 ChenyangGao <https://github.com/ChenyangGao>
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
@@ -1,7 +0,0 @@
1
- LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
2
- filewrap/__init__.py,sha256=5NZu2cdLJ9n12S9baxgvkfItnMDeHvSgfNr7kqXOqaw,60483
3
- filewrap/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- python_filewrap-0.2.9.dist-info/LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
5
- python_filewrap-0.2.9.dist-info/METADATA,sha256=NsWZxGEw5vJADKKNJkGL-XSQEXEea3BxUCMQYC4Grfg,1332
6
- python_filewrap-0.2.9.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
7
- python_filewrap-0.2.9.dist-info/RECORD,,