diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2021-06-21 16:11:33 +0100 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2021-06-21 16:11:33 +0100 |
| commit | 0add99ea3ea91af8230e3933ad7826b2da25a44d (patch) | |
| tree | 8ee70c67b5e9024eebe8ee0d592c0f6c9f926e62 /python/qemu/qmp/__init__.py | |
| parent | 53f306f316549d20c76886903181413d20842423 (diff) | |
| parent | d08caefe6648fc0713af5361e2b88bee53b67ebb (diff) | |
| download | focaccia-qemu-0add99ea3ea91af8230e3933ad7826b2da25a44d.tar.gz focaccia-qemu-0add99ea3ea91af8230e3933ad7826b2da25a44d.zip | |
Merge remote-tracking branch 'remotes/jsnow-gitlab/tags/python-pull-request' into staging
Python Pull request Moves QMP-related tools not used for build or automatic testing from scripts/ to python/qemu/qmp/ where they will be protected from bitrot by the check-python-* CI jobs. stub forwarders are left in the old locations for now. # gpg: Signature made Sat 19 Jun 2021 00:02:40 BST # gpg: using RSA key F9B7ABDBBCACDF95BE76CBD07DEF8106AAFC390E # gpg: Good signature from "John Snow (John Huston) <jsnow@redhat.com>" [full] # Primary key fingerprint: FAEB 9711 A12C F475 812F 18F2 88A9 064D 1835 61EB # Subkey fingerprint: F9B7 ABDB BCAC DF95 BE76 CBD0 7DEF 8106 AAFC 390E * remotes/jsnow-gitlab/tags/python-pull-request: (72 commits) scripts/qmp-shell: add redirection shim python: add qmp-shell entry point scripts/qmp-shell: move to python/qemu/qmp/qmp_shell.py scripts/qmp-shell: add docstrings scripts/qmp-shell: make QMPShellError inherit QMPError scripts/qmp-shell: remove double-underscores scripts/qmp-shell: convert usage comment to docstring scripts/qmp-shell: Remove too-broad-exception scripts/qmp-shell: Fix empty-transaction invocation scripts/qmp-shell: remove TODO scripts/qmp-shell: use logging to show warnings scripts/qmp-shell: Use context manager instead of atexit python/qmp: return generic type from context manager scripts/qmp-shell: unprivatize 'pretty' property scripts/qmp-shell: Accept SocketAddrT instead of string scripts/qmp-shell: add mypy types python/qmp: add QMPObject type alias scripts/qmp-shell: initialize completer early scripts/qmp-shell: refactor QMPCompleter scripts/qmp-shell: Fix "FuzzyJSON" parser ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'python/qemu/qmp/__init__.py')
| -rw-r--r-- | python/qemu/qmp/__init__.py | 59 |
1 files changed, 48 insertions, 11 deletions
diff --git a/python/qemu/qmp/__init__.py b/python/qemu/qmp/__init__.py index 9606248a3d..376954cb6d 100644 --- a/python/qemu/qmp/__init__.py +++ b/python/qemu/qmp/__init__.py @@ -30,21 +30,30 @@ from typing import ( TextIO, Tuple, Type, + TypeVar, Union, cast, ) -# QMPMessage is a QMP Message of any kind. -# e.g. {'yee': 'haw'} +#: QMPMessage is an entire QMP message of any kind. +QMPMessage = Dict[str, Any] + +#: QMPReturnValue is the 'return' value of a command. +QMPReturnValue = object + +#: QMPObject is any object in a QMP message. +QMPObject = Dict[str, object] + +# QMPMessage can be outgoing commands or incoming events/returns. +# QMPReturnValue is usually a dict/json object, but due to QAPI's +# 'returns-whitelist', it can actually be anything. # -# QMPReturnValue is the inner value of return values only. -# {'return': {}} is the QMPMessage, +# {'return': {}} is a QMPMessage, # {} is the QMPReturnValue. -QMPMessage = Dict[str, Any] -QMPReturnValue = Dict[str, Any] -InternetAddrT = Tuple[str, str] + +InternetAddrT = Tuple[str, int] UnixAddrT = str SocketAddrT = Union[InternetAddrT, UnixAddrT] @@ -92,6 +101,12 @@ class QMPResponseError(QMPError): self.reply = reply +class QMPBadPortError(QMPError): + """ + Unable to parse socket address: Port was non-numerical. + """ + + class QEMUMonitorProtocol: """ Provide an API to connect to QEMU via QEMU Monitor Protocol (QMP) and then @@ -206,7 +221,9 @@ class QEMUMonitorProtocol: if ret is None: raise QMPConnectError("Error while reading from socket") - def __enter__(self) -> 'QEMUMonitorProtocol': + T = TypeVar('T') + + def __enter__(self: T) -> T: # Implement context manager enter function. return self @@ -219,6 +236,26 @@ class QEMUMonitorProtocol: # Implement context manager exit function. self.close() + @classmethod + def parse_address(cls, address: str) -> SocketAddrT: + """ + Parse a string into a QMP address. + + Figure out if the argument is in the port:host form. + If it's not, it's probably a file path. + """ + components = address.split(':') + if len(components) == 2: + try: + port = int(components[1]) + except ValueError: + msg = f"Bad port: '{components[1]}' in '{address}'." + raise QMPBadPortError(msg) from None + return (components[0], port) + + # Treat as filepath. + return address + def connect(self, negotiate: bool = True) -> Optional[QMPMessage]: """ Connect to the QMP Monitor and perform capabilities negotiation. @@ -271,8 +308,8 @@ class QEMUMonitorProtocol: return resp def cmd(self, name: str, - args: Optional[Dict[str, Any]] = None, - cmd_id: Optional[Any] = None) -> QMPMessage: + args: Optional[Dict[str, object]] = None, + cmd_id: Optional[object] = None) -> QMPMessage: """ Build a QMP command and send it to the QMP Monitor. @@ -287,7 +324,7 @@ class QEMUMonitorProtocol: qmp_cmd['id'] = cmd_id return self.cmd_obj(qmp_cmd) - def command(self, cmd: str, **kwds: Any) -> QMPReturnValue: + def command(self, cmd: str, **kwds: object) -> QMPReturnValue: """ Build and send a QMP command to the monitor, report errors if any """ |