[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2] Python3 Support for qmp.py
From: |
Ishani Chugh |
Subject: |
[Qemu-devel] [PATCH v2] Python3 Support for qmp.py |
Date: |
Fri, 7 Jul 2017 00:38:47 +0530 |
This patch intends to make qmp.py compatible with both python2 and python3.
* Python 3 does not have dict.has_key(key), use key in dict instead
* Avoid line-based I/O since Python 2/3 have different character
encoding behavior. Explicitly encode/decode JSON UTF-8.
* Replace print by print function.
Signed-off-by: Ishani Chugh <address@hidden>
---
scripts/qmp/qmp.py | 58 ++++++++++++++++++++++++++++++++++--------------------
1 file changed, 37 insertions(+), 21 deletions(-)
diff --git a/scripts/qmp/qmp.py b/scripts/qmp/qmp.py
index 62d3651..58fb7d1 100644
--- a/scripts/qmp/qmp.py
+++ b/scripts/qmp/qmp.py
@@ -42,6 +42,7 @@ class QEMUMonitorProtocol:
self.__address = address
self._debug = debug
self.__sock = self.__get_sock()
+ self.__data = b""
if server:
self.__sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.__sock.bind(self.__address)
@@ -56,7 +57,7 @@ class QEMUMonitorProtocol:
def __negotiate_capabilities(self):
greeting = self.__json_read()
- if greeting is None or not greeting.has_key('QMP'):
+ if greeting is None or 'QMP' not in greeting:
raise QMPConnectError
# Greeting seems ok, negotiate capabilities
resp = self.cmd('qmp_capabilities')
@@ -64,15 +65,28 @@ class QEMUMonitorProtocol:
return greeting
raise QMPCapabilitiesError
+ def __sock_readline(self):
+ while True:
+ ch = self.__sock.recv(1)
+ if ch is None:
+ if self.__data:
+ raise ValueError('socket closed mid-line')
+ return None
+ self.__data += ch
+ if ch == b'\n':
+ line = self.__data.decode('utf-8')
+ self.__data = b""
+ return line
+
def __json_read(self, only_event=False):
while True:
- data = self.__sockfile.readline()
+ data = self.__sock_readline()
if not data:
return
resp = json.loads(data)
if 'event' in resp:
if self._debug:
- print >>sys.stderr, "QMP:<<< %s" % resp
+ print("QMP:<<< %s" % resp)
self.__events.append(resp)
if not only_event:
continue
@@ -87,10 +101,10 @@ class QEMUMonitorProtocol:
@param wait (bool): block until an event is available.
@param wait (float): If wait is a float, treat it as a timeout value.
- @raise QMPTimeoutError: If a timeout float is provided and the timeout
- period elapses.
- @raise QMPConnectError: If wait is True but no events could be
retrieved
- or if some other error occurred.
+ @raise QMPTimeoutError: If a timeout float is provided and the
+ timeout period elapses.
+ @raise QMPConnectError: If wait is True but no events could be
+ retrieved or if some other error occurred.
"""
# Check for new events regardless and pull them into the cache:
@@ -98,9 +112,11 @@ class QEMUMonitorProtocol:
try:
self.__json_read()
except socket.error as err:
- if err[0] == errno.EAGAIN:
+ if err.errno == errno.EAGAIN:
# No data available
pass
+ else:
+ raise
self.__sock.setblocking(1)
# Wait for new events, if needed.
@@ -128,7 +144,6 @@ class QEMUMonitorProtocol:
@raise QMPCapabilitiesError if fails to negotiate capabilities
"""
self.__sock.connect(self.__address)
- self.__sockfile = self.__sock.makefile()
if negotiate:
return self.__negotiate_capabilities()
@@ -143,7 +158,6 @@ class QEMUMonitorProtocol:
"""
self.__sock.settimeout(15)
self.__sock, _ = self.__sock.accept()
- self.__sockfile = self.__sock.makefile()
return self.__negotiate_capabilities()
def cmd_obj(self, qmp_cmd):
@@ -155,16 +169,17 @@ class QEMUMonitorProtocol:
been closed
"""
if self._debug:
- print >>sys.stderr, "QMP:>>> %s" % qmp_cmd
+ print("QMP:>>> %s" % qmp_cmd)
try:
- self.__sock.sendall(json.dumps(qmp_cmd))
+ command = json.dumps(qmp_cmd)
+ self.__sock.sendall(command.encode('UTF-8'))
except socket.error as err:
- if err[0] == errno.EPIPE:
+ if err.errno == errno.EPIPE:
return
- raise socket.error(err)
+ raise
resp = self.__json_read()
if self._debug:
- print >>sys.stderr, "QMP:<<< %s" % resp
+ print("QMP:<<< %s" % resp)
return resp
def cmd(self, name, args=None, id=None):
@@ -175,7 +190,7 @@ class QEMUMonitorProtocol:
@param args: command arguments (dict)
@param id: command id (dict, list, string or int)
"""
- qmp_cmd = { 'execute': name }
+ qmp_cmd = {'execute': name}
if args:
qmp_cmd['arguments'] = args
if id:
@@ -184,7 +199,7 @@ class QEMUMonitorProtocol:
def command(self, cmd, **kwds):
ret = self.cmd(cmd, kwds)
- if ret.has_key('error'):
+ if 'error' in ret:
raise Exception(ret['error']['desc'])
return ret['return']
@@ -197,8 +212,8 @@ class QEMUMonitorProtocol:
@raise QMPTimeoutError: If a timeout float is provided and the timeout
period elapses.
- @raise QMPConnectError: If wait is True but no events could be
retrieved
- or if some other error occurred.
+ @raise QMPConnectError: If wait is True but no events could be
+ retrieved or if some other error occurred.
@return The first available QMP event, or None.
"""
@@ -217,8 +232,8 @@ class QEMUMonitorProtocol:
@raise QMPTimeoutError: If a timeout float is provided and the timeout
period elapses.
- @raise QMPConnectError: If wait is True but no events could be
retrieved
- or if some other error occurred.
+ @raise QMPConnectError: If wait is True but no events could be
+ retrieved or if some other error occurred.
@return The list of available QMP events.
"""
@@ -245,3 +260,4 @@ class QEMUMonitorProtocol:
def is_scm_available(self):
return self.__sock.family == socket.AF_UNIX
+
--
2.7.4
- [Qemu-devel] [PATCH v2] Python3 Support for qmp.py,
Ishani Chugh <=