python-filewrap 0.0.7.2__tar.gz → 0.1__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.
- {python_filewrap-0.0.7.2 → python_filewrap-0.1}/PKG-INFO +1 -1
- {python_filewrap-0.0.7.2 → python_filewrap-0.1}/filewrap/__init__.py +134 -36
- {python_filewrap-0.0.7.2 → python_filewrap-0.1}/pyproject.toml +1 -1
- {python_filewrap-0.0.7.2 → python_filewrap-0.1}/LICENSE +0 -0
- {python_filewrap-0.0.7.2 → python_filewrap-0.1}/filewrap/py.typed +0 -0
- {python_filewrap-0.0.7.2 → python_filewrap-0.1}/readme.md +0 -0
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
# encoding: utf-8
|
|
3
3
|
|
|
4
4
|
__author__ = "ChenyangGao <https://chenyanggao.github.io>"
|
|
5
|
-
__version__ = (0,
|
|
5
|
+
__version__ = (0, 1)
|
|
6
6
|
__all__ = [
|
|
7
|
-
"
|
|
7
|
+
"Buffer", "SupportsRead", "SupportsReadinto",
|
|
8
|
+
"SupportsWrite", "SupportsSeek",
|
|
8
9
|
"bio_chunk_iter", "bio_chunk_async_iter",
|
|
9
10
|
"bio_skip_iter", "bio_skip_async_iter",
|
|
10
11
|
"bytes_iter_skip", "bytes_async_iter_skip",
|
|
@@ -25,7 +26,39 @@ from typing import runtime_checkable, Any, Protocol, TypeVar
|
|
|
25
26
|
try:
|
|
26
27
|
from collections.abc import Buffer # type: ignore
|
|
27
28
|
except ImportError:
|
|
28
|
-
|
|
29
|
+
from abc import ABC, abstractmethod
|
|
30
|
+
from array import array
|
|
31
|
+
|
|
32
|
+
def _check_methods(C, *methods):
|
|
33
|
+
mro = C.__mro__
|
|
34
|
+
for method in methods:
|
|
35
|
+
for B in mro:
|
|
36
|
+
if method in B.__dict__:
|
|
37
|
+
if B.__dict__[method] is None:
|
|
38
|
+
return NotImplemented
|
|
39
|
+
break
|
|
40
|
+
else:
|
|
41
|
+
return NotImplemented
|
|
42
|
+
return True
|
|
43
|
+
|
|
44
|
+
class Buffer(ABC): # type: ignore
|
|
45
|
+
__slots__ = ()
|
|
46
|
+
|
|
47
|
+
@abstractmethod
|
|
48
|
+
def __buffer__(self, flags: int, /) -> memoryview:
|
|
49
|
+
raise NotImplementedError
|
|
50
|
+
|
|
51
|
+
@classmethod
|
|
52
|
+
def __subclasshook__(cls, C):
|
|
53
|
+
if cls is Buffer:
|
|
54
|
+
return _check_methods(C, "__buffer__")
|
|
55
|
+
return NotImplemented
|
|
56
|
+
|
|
57
|
+
Buffer.register(bytes)
|
|
58
|
+
Buffer.register(bytearray)
|
|
59
|
+
Buffer.register(memoryview)
|
|
60
|
+
Buffer.register(array)
|
|
61
|
+
|
|
29
62
|
|
|
30
63
|
from asynctools import async_chain, ensure_async, ensure_aiter
|
|
31
64
|
|
|
@@ -39,13 +72,18 @@ class SupportsRead(Protocol[_T_co]):
|
|
|
39
72
|
def read(self, /, __length: int = ...) -> _T_co: ...
|
|
40
73
|
|
|
41
74
|
|
|
75
|
+
@runtime_checkable
|
|
76
|
+
class SupportsReadinto(Protocol):
|
|
77
|
+
def readinto(self, /, buf: Buffer = ...) -> int: ...
|
|
78
|
+
|
|
79
|
+
|
|
42
80
|
@runtime_checkable
|
|
43
81
|
class SupportsWrite(Protocol[_T_contra]):
|
|
44
82
|
def write(self, /, __s: _T_contra) -> object: ...
|
|
45
83
|
|
|
46
84
|
|
|
47
85
|
@runtime_checkable
|
|
48
|
-
class SupportsSeek(Protocol
|
|
86
|
+
class SupportsSeek(Protocol):
|
|
49
87
|
def seek(self, /, __offset: int, __whence: int = 0) -> int: ...
|
|
50
88
|
|
|
51
89
|
|
|
@@ -54,30 +92,60 @@ def bio_chunk_iter(
|
|
|
54
92
|
/,
|
|
55
93
|
size: int = -1,
|
|
56
94
|
chunksize: int = COPY_BUFSIZE,
|
|
95
|
+
can_buffer: bool = False,
|
|
57
96
|
callback: None | Callable[[int], Any] = None,
|
|
58
97
|
) -> Iterator[Buffer]:
|
|
98
|
+
use_readinto = False
|
|
59
99
|
if callable(bio):
|
|
60
100
|
read = bio
|
|
101
|
+
elif can_buffer and hasattr(bio, "readinto"):
|
|
102
|
+
readinto = bio.readinto
|
|
103
|
+
use_readinto = True
|
|
61
104
|
else:
|
|
62
105
|
read = bio.read
|
|
63
106
|
if not callable(callback):
|
|
64
107
|
callback = None
|
|
65
|
-
if
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
108
|
+
if use_readinto:
|
|
109
|
+
buf = bytearray(chunksize)
|
|
110
|
+
if size > 0:
|
|
111
|
+
while size:
|
|
112
|
+
if size < chunksize:
|
|
113
|
+
del buf[size:]
|
|
114
|
+
length = readinto(buf)
|
|
115
|
+
if callback:
|
|
116
|
+
callback(length)
|
|
117
|
+
if length < len(buf):
|
|
118
|
+
del buf[length:]
|
|
119
|
+
yield buf
|
|
120
|
+
break
|
|
121
|
+
yield buf
|
|
122
|
+
size -= length
|
|
123
|
+
else:
|
|
124
|
+
while (length := readinto(buf)):
|
|
125
|
+
if callback:
|
|
126
|
+
callback(length)
|
|
127
|
+
if length < chunksize:
|
|
128
|
+
del buf[length:]
|
|
129
|
+
yield buf
|
|
130
|
+
break
|
|
131
|
+
yield buf
|
|
132
|
+
else:
|
|
133
|
+
if size > 0:
|
|
134
|
+
while size:
|
|
135
|
+
readsize = min(chunksize, size)
|
|
136
|
+
chunk = read(readsize)
|
|
137
|
+
length = len(chunk)
|
|
138
|
+
if callback:
|
|
139
|
+
callback(length)
|
|
140
|
+
yield chunk
|
|
141
|
+
if length < readsize:
|
|
142
|
+
break
|
|
143
|
+
size -= length
|
|
144
|
+
elif size < 0:
|
|
145
|
+
while (chunk := read(chunksize)):
|
|
146
|
+
if callback:
|
|
147
|
+
callback(len(chunk))
|
|
148
|
+
yield chunk
|
|
81
149
|
|
|
82
150
|
|
|
83
151
|
async def bio_chunk_async_iter(
|
|
@@ -85,29 +153,59 @@ async def bio_chunk_async_iter(
|
|
|
85
153
|
/,
|
|
86
154
|
size: int = -1,
|
|
87
155
|
chunksize: int = COPY_BUFSIZE,
|
|
156
|
+
can_buffer: bool = False,
|
|
88
157
|
callback: None | Callable[[int], Any] = None,
|
|
89
158
|
) -> AsyncIterator[Buffer]:
|
|
159
|
+
use_readinto = False
|
|
90
160
|
if callable(bio):
|
|
91
161
|
read = ensure_async(bio)
|
|
162
|
+
elif can_buffer and hasattr(bio, "readinto"):
|
|
163
|
+
readinto = ensure_async(bio.readinto)
|
|
164
|
+
use_readinto = True
|
|
92
165
|
else:
|
|
93
166
|
read = ensure_async(bio.read)
|
|
94
167
|
callback = ensure_async(callback) if callable(callback) else None
|
|
95
|
-
if
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
await
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
168
|
+
if use_readinto:
|
|
169
|
+
buf = bytearray(chunksize)
|
|
170
|
+
if size > 0:
|
|
171
|
+
while size:
|
|
172
|
+
if size < chunksize:
|
|
173
|
+
del buf[size:]
|
|
174
|
+
length = await readinto(buf)
|
|
175
|
+
if callback:
|
|
176
|
+
await callback(length)
|
|
177
|
+
if length < len(buf):
|
|
178
|
+
del buf[length:]
|
|
179
|
+
yield buf
|
|
180
|
+
break
|
|
181
|
+
yield buf
|
|
182
|
+
size -= length
|
|
183
|
+
else:
|
|
184
|
+
while (length := (await readinto(buf))):
|
|
185
|
+
if callback:
|
|
186
|
+
await callback(length)
|
|
187
|
+
if length < chunksize:
|
|
188
|
+
del buf[length:]
|
|
189
|
+
yield buf
|
|
190
|
+
break
|
|
191
|
+
yield buf
|
|
192
|
+
else:
|
|
193
|
+
if size > 0:
|
|
194
|
+
while size:
|
|
195
|
+
readsize = min(chunksize, size)
|
|
196
|
+
chunk = await read(readsize)
|
|
197
|
+
length = len(chunk)
|
|
198
|
+
if callback:
|
|
199
|
+
await callback(length)
|
|
200
|
+
yield chunk
|
|
201
|
+
if length < readsize:
|
|
202
|
+
break
|
|
203
|
+
size -= readsize
|
|
204
|
+
elif size < 0:
|
|
205
|
+
while (chunk := (await read(chunksize))):
|
|
206
|
+
if callback:
|
|
207
|
+
await callback(len(chunk))
|
|
208
|
+
yield chunk
|
|
111
209
|
|
|
112
210
|
|
|
113
211
|
def bio_skip_iter(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|