From 8dfac2edb2146d87b25543c70e25723f3d4dbd60 Mon Sep 17 00:00:00 2001 From: John Snow Date: Thu, 28 May 2020 18:21:29 -0400 Subject: python/qemu: delint; add flake8 config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mostly, ignore the "no bare except" rule, because flake8 is not contextual and cannot determine if we re-raise. Pylint can, though, so always prefer pylint for that. Signed-off-by: John Snow Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20200528222129.23826-5-jsnow@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- python/qemu/qmp.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'python/qemu/qmp.py') diff --git a/python/qemu/qmp.py b/python/qemu/qmp.py index d6c9b2f4b1..6ae7693965 100644 --- a/python/qemu/qmp.py +++ b/python/qemu/qmp.py @@ -168,8 +168,8 @@ class QEMUMonitorProtocol: @param timeout: timeout in seconds (nonnegative float number, or None). The value passed will set the behavior of the - underneath QMP socket as described in [1]. Default value - is set to 15.0. + underneath QMP socket as described in [1]. + Default value is set to 15.0. @return QMP greeting dict @raise OSError on socket connection errors @raise QMPConnectError if the greeting is not received -- cgit 1.4.1 From 0add048fbd9992151e4c592977df9cff8558ca60 Mon Sep 17 00:00:00 2001 From: John Snow Date: Thu, 14 May 2020 01:53:43 -0400 Subject: python/qemu: fix socket.makefile() typing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Note: A bug in typeshed (https://github.com/python/typeshed/issues/3977) misinterprets the type of makefile(). Work around this by explicitly stating that we are opening a text-mode file. Signed-off-by: John Snow Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20200514055403.18902-13-jsnow@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- python/qemu/qmp.py | 10 +++++++--- python/qemu/qtest.py | 12 ++++++++---- 2 files changed, 15 insertions(+), 7 deletions(-) (limited to 'python/qemu/qmp.py') diff --git a/python/qemu/qmp.py b/python/qemu/qmp.py index 6ae7693965..73d49050ed 100644 --- a/python/qemu/qmp.py +++ b/python/qemu/qmp.py @@ -11,6 +11,10 @@ import json import errno import socket import logging +from typing import ( + Optional, + TextIO, +) class QMPError(Exception): @@ -61,7 +65,7 @@ class QEMUMonitorProtocol: self.__events = [] self.__address = address self.__sock = self.__get_sock() - self.__sockfile = None + self.__sockfile: Optional[TextIO] = None self._nickname = nickname if self._nickname: self.logger = logging.getLogger('QMP').getChild(self._nickname) @@ -157,7 +161,7 @@ class QEMUMonitorProtocol: @raise QMPCapabilitiesError if fails to negotiate capabilities """ self.__sock.connect(self.__address) - self.__sockfile = self.__sock.makefile() + self.__sockfile = self.__sock.makefile(mode='r') if negotiate: return self.__negotiate_capabilities() return None @@ -180,7 +184,7 @@ class QEMUMonitorProtocol: """ self.__sock.settimeout(timeout) self.__sock, _ = self.__sock.accept() - self.__sockfile = self.__sock.makefile() + self.__sockfile = self.__sock.makefile(mode='r') return self.__negotiate_capabilities() def cmd_obj(self, qmp_cmd): diff --git a/python/qemu/qtest.py b/python/qemu/qtest.py index 7943487c2b..4c88590eb0 100644 --- a/python/qemu/qtest.py +++ b/python/qemu/qtest.py @@ -19,6 +19,7 @@ subclass of QEMUMachine, respectively. import socket import os +from typing import Optional, TextIO from .machine import QEMUMachine @@ -40,7 +41,7 @@ class QEMUQtestProtocol: def __init__(self, address, server=False): self._address = address self._sock = self._get_sock() - self._sockfile = None + self._sockfile: Optional[TextIO] = None if server: self._sock.bind(self._address) self._sock.listen(1) @@ -59,7 +60,7 @@ class QEMUQtestProtocol: @raise socket.error on socket connection errors """ self._sock.connect(self._address) - self._sockfile = self._sock.makefile() + self._sockfile = self._sock.makefile(mode='r') def accept(self): """ @@ -68,7 +69,7 @@ class QEMUQtestProtocol: @raise socket.error on socket connection errors """ self._sock, _ = self._sock.accept() - self._sockfile = self._sock.makefile() + self._sockfile = self._sock.makefile(mode='r') def cmd(self, qtest_cmd): """ @@ -76,6 +77,7 @@ class QEMUQtestProtocol: @param qtest_cmd: qtest command text to be sent """ + assert self._sockfile is not None self._sock.sendall((qtest_cmd + "\n").encode('utf-8')) resp = self._sockfile.readline() return resp @@ -83,7 +85,9 @@ class QEMUQtestProtocol: def close(self): """Close this socket.""" self._sock.close() - self._sockfile.close() + if self._sockfile: + self._sockfile.close() + self._sockfile = None def settimeout(self, timeout): """Set a timeout, in seconds.""" -- cgit 1.4.1 From 1dda0404d8afeb0ed45fbeae85e380e1ff57da35 Mon Sep 17 00:00:00 2001 From: John Snow Date: Thu, 14 May 2020 01:53:44 -0400 Subject: python/qemu: Adjust traceback typing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mypy considers it incorrect to use `bool` to statically return false, because it will assume that it could conceivably return True, and gives different analysis in that case. Use a None return to achieve the same effect, but make mypy happy. Note: Pylint considers function signatures as code that might trip the duplicate-code checker. I'd rather not disable this as it does not trigger often in practice, so I'm disabling it as a one-off and filed a change request; see https://github.com/PyCQA/pylint/issues/3619 Signed-off-by: John Snow Acked-by: Philippe Mathieu-Daudé Message-Id: <20200514055403.18902-14-jsnow@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- python/qemu/machine.py | 8 ++++++-- python/qemu/qmp.py | 10 ++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) (limited to 'python/qemu/qmp.py') diff --git a/python/qemu/machine.py b/python/qemu/machine.py index 95a20a17f9..041c615052 100644 --- a/python/qemu/machine.py +++ b/python/qemu/machine.py @@ -24,6 +24,8 @@ import subprocess import shutil import socket import tempfile +from typing import Optional, Type +from types import TracebackType from . import qmp @@ -124,9 +126,11 @@ class QEMUMachine: def __enter__(self): return self - def __exit__(self, exc_type, exc_val, exc_tb): + def __exit__(self, + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType]) -> None: self.shutdown() - return False def add_monitor_null(self): """ diff --git a/python/qemu/qmp.py b/python/qemu/qmp.py index 73d49050ed..b91c9d5c1c 100644 --- a/python/qemu/qmp.py +++ b/python/qemu/qmp.py @@ -14,7 +14,9 @@ import logging from typing import ( Optional, TextIO, + Type, ) +from types import TracebackType class QMPError(Exception): @@ -146,10 +148,14 @@ class QEMUMonitorProtocol: # Implement context manager enter function. return self - def __exit__(self, exc_type, exc_value, exc_traceback): + def __exit__(self, + # pylint: disable=duplicate-code + # see https://github.com/PyCQA/pylint/issues/3619 + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType]) -> None: # Implement context manager exit function. self.close() - return False def connect(self, negotiate=True): """ -- cgit 1.4.1 From 7af67d694e289ab116c7abeca8a5bd752fbd46d7 Mon Sep 17 00:00:00 2001 From: John Snow Date: Thu, 14 May 2020 01:53:45 -0400 Subject: python/qemu/qmp: use True/False for non/blocking modes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The type system doesn't want integers. Signed-off-by: John Snow Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20200514055403.18902-15-jsnow@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- python/qemu/qmp.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'python/qemu/qmp.py') diff --git a/python/qemu/qmp.py b/python/qemu/qmp.py index b91c9d5c1c..a634c4e26c 100644 --- a/python/qemu/qmp.py +++ b/python/qemu/qmp.py @@ -120,14 +120,14 @@ class QEMUMonitorProtocol: """ # Check for new events regardless and pull them into the cache: - self.__sock.setblocking(0) + self.__sock.setblocking(False) try: self.__json_read() except OSError as err: if err.errno == errno.EAGAIN: # No data available pass - self.__sock.setblocking(1) + self.__sock.setblocking(True) # Wait for new events, if needed. # if wait is 0.0, this means "no wait" and is also implicitly false. -- cgit 1.4.1 From de210ec53c842fa67aa10110a7a351d64f91c487 Mon Sep 17 00:00:00 2001 From: John Snow Date: Thu, 14 May 2020 01:53:51 -0400 Subject: python/qemu/qmp: assert sockfile is not None MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In truth, if you don't do this, you'll just get a TypeError exception. Now, you'll get an AssertionError. Is this tangibly better? No. Does mypy complain less? Yes. Signed-off-by: John Snow Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20200514055403.18902-21-jsnow@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- python/qemu/qmp.py | 1 + 1 file changed, 1 insertion(+) (limited to 'python/qemu/qmp.py') diff --git a/python/qemu/qmp.py b/python/qemu/qmp.py index a634c4e26c..e64b6b5faa 100644 --- a/python/qemu/qmp.py +++ b/python/qemu/qmp.py @@ -94,6 +94,7 @@ class QEMUMonitorProtocol: raise QMPCapabilitiesError def __json_read(self, only_event=False): + assert self.__sockfile is not None while True: data = self.__sockfile.readline() if not data: -- cgit 1.4.1