Commit 441460d8 authored by Damien George's avatar Damien George

extmod/uasyncio: Add StreamReader.readexactly(n) method.

It raises on EOFError instead of an IncompleteReadError (which is what
CPython does).  But the latter is derived from EOFError so code compatible
with MicroPython and CPython can be written by catching EOFError (eg see
included test).

Fixes issue #6156.
Signed-off-by: default avatarDamien George <damien@micropython.org>
parent fd2ff867
......@@ -30,6 +30,18 @@ class Stream:
yield core._io_queue.queue_read(self.s)
return self.s.read(n)
async def readexactly(self, n):
r = b""
while n:
yield core._io_queue.queue_read(self.s)
r2 = self.s.read(n)
if r2 is not None:
if not len(r2):
raise EOFError
r += r2
n -= len(r2)
return r
async def readline(self):
l = b""
while True:
......
# Test uasyncio stream readexactly() method using TCP server/client
try:
import uasyncio as asyncio
except ImportError:
try:
import asyncio
except ImportError:
print("SKIP")
raise SystemExit
PORT = 8000
async def handle_connection(reader, writer):
writer.write(b"a")
await writer.drain()
# Split the first 2 bytes up so the client must wait for the second one
await asyncio.sleep(0.1)
writer.write(b"b")
await writer.drain()
writer.write(b"c")
await writer.drain()
writer.write(b"d")
await writer.drain()
print("close")
writer.close()
await writer.wait_closed()
print("done")
ev.set()
async def tcp_server():
global ev
ev = asyncio.Event()
server = await asyncio.start_server(handle_connection, "0.0.0.0", PORT)
print("server running")
multitest.next()
async with server:
await asyncio.wait_for(ev.wait(), 10)
async def tcp_client():
reader, writer = await asyncio.open_connection(IP, PORT)
print(await reader.readexactly(2))
print(await reader.readexactly(0))
print(await reader.readexactly(1))
try:
print(await reader.readexactly(2))
except EOFError as er:
print("EOFError")
print(await reader.readexactly(0))
def instance0():
multitest.globals(IP=multitest.get_network_ip())
asyncio.run(tcp_server())
def instance1():
multitest.next()
asyncio.run(tcp_client())
--- instance0 ---
server running
close
done
--- instance1 ---
b'ab'
b''
b'c'
EOFError
b''
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment