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 <js...@redhat.com> --- python/qemu/lib/machine.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/python/qemu/lib/machine.py b/python/qemu/lib/machine.py index dfa8449b62..fb1a02b53c 100644 --- a/python/qemu/lib/machine.py +++ b/python/qemu/lib/machine.py @@ -113,7 +113,7 @@ def __init__(self, binary, args=None, wrapper=None, name=None, # 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. @@ -225,6 +225,12 @@ def is_running(self): """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: @@ -235,7 +241,7 @@ def get_pid(self): """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: @@ -352,7 +358,7 @@ def wait(self): """ Wait for the VM to power off """ - self._popen.wait() + self._subp.wait() if self._qmp: self._qmp.close() self._load_io_log() @@ -371,11 +377,11 @@ def _issue_shutdown(self, has_quit: bool = False) -> None: self._qmp.close() try: - self._popen.wait(timeout=3) + self._subp.wait(timeout=3) except subprocess.TimeoutExpired: - self._popen.kill() + self._subp.kill() - self._popen.wait() + self._subp.wait() def shutdown(self, has_quit: bool = False) -> None: """ -- 2.21.1