summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Teachman <mike.teachman@gmail.com>2021-06-03 09:43:56 -0700
committerDamien George <damien@micropython.org>2021-06-15 13:13:35 +1000
commitb0b8ebc4f6e337e18c79367ccc5f379dfa8681d9 (patch)
treea38455b2c272cad252490335e2151081eea9878f
parent95048129b1d93854c25f501c02801929aeeb23f0 (diff)
extmod/uasyncio: Add readinto() method to Stream class.
With docs and a multi-test using TCP server/client. This method is a MicroPython extension, although there is discussion of adding it to CPython: https://bugs.python.org/issue41305 Signed-off-by: Mike Teachman <mike.teachman@gmail.com>
-rw-r--r--docs/library/uasyncio.rst8
-rw-r--r--extmod/uasyncio/stream.py4
-rw-r--r--tests/multi_net/uasyncio_tcp_readinto.py80
-rw-r--r--tests/multi_net/uasyncio_tcp_readinto.py.exp11
4 files changed, 103 insertions, 0 deletions
diff --git a/docs/library/uasyncio.rst b/docs/library/uasyncio.rst
index 1efee56e9..0be328829 100644
--- a/docs/library/uasyncio.rst
+++ b/docs/library/uasyncio.rst
@@ -240,6 +240,14 @@ TCP stream connections
This is a coroutine.
+.. method:: Stream.readinto(buf)
+
+ Read up to n bytes into *buf* with n being equal to the length of *buf*.
+
+ Return the number of bytes read into *buf*.
+
+ This is a coroutine, and a MicroPython extension.
+
.. method:: Stream.readline()
Read a line and return it.
diff --git a/extmod/uasyncio/stream.py b/extmod/uasyncio/stream.py
index 2a259e618..3a68881da 100644
--- a/extmod/uasyncio/stream.py
+++ b/extmod/uasyncio/stream.py
@@ -30,6 +30,10 @@ class Stream:
yield core._io_queue.queue_read(self.s)
return self.s.read(n)
+ async def readinto(self, buf):
+ yield core._io_queue.queue_read(self.s)
+ return self.s.readinto(buf)
+
async def readexactly(self, n):
r = b""
while n:
diff --git a/tests/multi_net/uasyncio_tcp_readinto.py b/tests/multi_net/uasyncio_tcp_readinto.py
new file mode 100644
index 000000000..631997652
--- /dev/null
+++ b/tests/multi_net/uasyncio_tcp_readinto.py
@@ -0,0 +1,80 @@
+# Test uasyncio stream readinto() method using TCP server/client
+
+try:
+ import uasyncio as asyncio
+except ImportError:
+ try:
+ import asyncio
+ except ImportError:
+ print("SKIP")
+ raise SystemExit
+
+try:
+ import uarray as array
+except ImportError:
+ try:
+ import array
+ except ImportError:
+ print("SKIP")
+ raise SystemExit
+
+PORT = 8000
+
+
+async def handle_connection(reader, writer):
+ writer.write(b"ab")
+ await writer.drain()
+
+ writer.write(b"c")
+ 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)
+
+ ba = bytearray(2)
+ n = await reader.readinto(ba)
+ print(n)
+ print(ba[:n])
+
+ a = array.array("b", [0, 0])
+ n = await reader.readinto(a)
+ print(n)
+ print(a[:n])
+
+ try:
+ n = await reader.readinto(5)
+ except TypeError as er:
+ print("TypeError")
+
+ try:
+ n = await reader.readinto()
+ except TypeError as er:
+ print("TypeError")
+
+
+def instance0():
+ multitest.globals(IP=multitest.get_network_ip())
+ asyncio.run(tcp_server())
+
+
+def instance1():
+ multitest.next()
+ asyncio.run(tcp_client())
diff --git a/tests/multi_net/uasyncio_tcp_readinto.py.exp b/tests/multi_net/uasyncio_tcp_readinto.py.exp
new file mode 100644
index 000000000..2d40ba1e6
--- /dev/null
+++ b/tests/multi_net/uasyncio_tcp_readinto.py.exp
@@ -0,0 +1,11 @@
+--- instance0 ---
+server running
+close
+done
+--- instance1 ---
+2
+bytearray(b'ab')
+1
+array('b', [99])
+TypeError
+TypeError