Make body_iter async generator compatible with MicroPython

This commit is contained in:
Miguel Grinberg
2022-05-26 10:48:18 +01:00
parent 7e8ecb1997
commit 35c72125a0
3 changed files with 35 additions and 20 deletions

View File

@@ -88,7 +88,7 @@ class Microdot(BaseMicrodot):
'status': res.status_code,
'headers': [(name, value)
for name, value in res.headers.items()]})
body_iter = res.body_iter()
body_iter = res.body_iter().__aiter__()
body = b''
try:
body += await body_iter.__anext__()

View File

@@ -136,24 +136,38 @@ class Response(BaseResponse):
async for body in self.body_iter():
await stream.awrite(body)
async def body_iter(self):
if self.body:
if hasattr(self.body, 'read'):
while True:
buf = self.body.read(self.send_file_buffer_size)
if _iscoroutine(buf): # pragma: no cover
buf = await buf
if len(buf):
print('*', buf, self.send_file_buffer_size)
yield buf
if len(buf) < self.send_file_buffer_size:
break
if hasattr(self.body, 'close'): # pragma: no cover
result = self.body.close()
if _iscoroutine(result):
await result
else:
yield self.body
def body_iter(self):
response = self
class iter:
def __aiter__(self):
if response.body:
self.i = 0
else:
self.i = -1
return self
async def __anext__(self):
if self.i == -1:
raise StopAsyncIteration
if self.i == 0:
if not hasattr(response.body, 'read'):
self.i = -1
return response.body
else:
self.i = 1
buf = response.body.read(response.send_file_buffer_size)
if _iscoroutine(buf): # pragma: no cover
buf = await buf
if len(buf) < response.send_file_buffer_size:
self.i = -1
if hasattr(response.body, 'close'): # pragma: no cover
result = response.body.close()
if _iscoroutine(result):
await result
return buf
return iter()
class Microdot(BaseMicrodot):

View File

@@ -65,7 +65,8 @@ class TestMicrodotASGI(unittest.TestCase):
packet['headers'],
[('Content-Length', '8'), ('Content-Type', 'text/plain')])
elif packet['type'] == 'http.response.body':
self.assertIn(packet['body'], [b're', b'sp', b'on', b'se'])
self.assertIn(packet['body'],
[b're', b'sp', b'on', b'se', b''])
original_buffer_size = Response.send_file_buffer_size
Response.send_file_buffer_size = 2