python/aqmp: add AsyncProtocol._readline() method

This is added as a courtesy: many protocols are line-based, including
QMP. Putting it in AsyncProtocol lets us keep the QMP class
implementation just a pinch more abstract.

(And, if we decide to add a QTEST implementation later, it will need
this, too. (Yes, I have a QTEST implementation.))

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 20210915162955.333025-13-jsnow@redhat.com
Signed-off-by: John Snow <jsnow@redhat.com>
This commit is contained in:
John Snow 2021-09-15 12:29:40 -04:00
parent 12c7a57f5b
commit 762bd4d7a7

View File

@ -794,6 +794,35 @@ class AsyncProtocol(Generic[T]):
self.logger.debug("<-- %s", str(msg))
return msg
@upper_half
@bottom_half
async def _readline(self) -> bytes:
"""
Wait for a newline from the incoming reader.
This method is provided as a convenience for upper-layer
protocols, as many are line-based.
This method *may* return a sequence of bytes without a trailing
newline if EOF occurs, but *some* bytes were received. In this
case, the next call will raise `EOFError`. It is assumed that
the layer 5 protocol will decide if there is anything meaningful
to be done with a partial message.
:raise OSError: For stream-related errors.
:raise EOFError:
If the reader stream is at EOF and there are no bytes to return.
:return: bytes, including the newline.
"""
assert self._reader is not None
msg_bytes = await self._reader.readline()
if not msg_bytes:
if self._reader.at_eof():
raise EOFError
return msg_bytes
@upper_half
@bottom_half
async def _do_recv(self) -> T: