From 9223fda464690b83a2b1f1487163f50602454c2e Mon Sep 17 00:00:00 2001 From: John Snow Date: Tue, 6 Oct 2020 19:58:05 -0400 Subject: [PATCH] python/machine.py: fix _popen access As always, Optional[T] causes problems with unchecked access. Add a helper that asserts the pipe is present before we attempt to talk with it. Signed-off-by: John Snow Reviewed-by: Kevin Wolf Message-id: 20201006235817.3280413-9-jsnow@redhat.com Signed-off-by: John Snow --- python/qemu/machine.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/python/qemu/machine.py b/python/qemu/machine.py index 3e9cf09fd2..4e762fcd52 100644 --- a/python/qemu/machine.py +++ b/python/qemu/machine.py @@ -131,7 +131,7 @@ class QEMUMachine: # Runstate self._qemu_log_path = None self._qemu_log_file = None - self._popen = None + self._popen: Optional['subprocess.Popen[bytes]'] = None self._events = [] self._iolog = None self._qmp_set = True # Enable QMP monitor by default. @@ -244,6 +244,12 @@ class QEMUMachine: """Returns true if the VM is running.""" return self._popen is not None and self._popen.poll() is None + @property + def _subp(self) -> 'subprocess.Popen[bytes]': + if self._popen is None: + raise QEMUMachineError('Subprocess pipe not present') + return self._popen + def exitcode(self): """Returns the exit code if possible, or None.""" if self._popen is None: @@ -254,7 +260,7 @@ class QEMUMachine: """Returns the PID of the running process, or None.""" if not self.is_running(): return None - return self._popen.pid + return self._subp.pid def _load_io_log(self): if self._qemu_log_path is not None: @@ -415,8 +421,8 @@ class QEMUMachine: waiting for the QEMU process to terminate. """ self._early_cleanup() - self._popen.kill() - self._popen.wait(timeout=60) + self._subp.kill() + self._subp.wait(timeout=60) def _soft_shutdown(self, timeout: Optional[int], has_quit: bool = False) -> None: @@ -440,7 +446,7 @@ class QEMUMachine: self._qmp.cmd('quit') # May raise subprocess.TimeoutExpired - self._popen.wait(timeout=timeout) + self._subp.wait(timeout=timeout) def _do_shutdown(self, timeout: Optional[int], has_quit: bool = False) -> None: