[ovs-dev] [PATCH 36/55] python: Deal with str and byte differences.

Russell Bryant russell at ovn.org
Mon Dec 21 20:47:36 UTC 2015


Python 3 has separate types for strings and bytes.  Python 2 used the
same type for both.  We need to convert strings to bytes before writing
them out to a socket.  We also need to convert data read from the socket
to a string.

Signed-off-by: Russell Bryant <russell at ovn.org>
---
 python/ovs/jsonrpc.py     | 10 ++++++++++
 python/ovs/socket_util.py |  3 +++
 python/ovs/stream.py      |  6 ++++++
 3 files changed, 19 insertions(+)

diff --git a/python/ovs/jsonrpc.py b/python/ovs/jsonrpc.py
index efe0f6c..5177980 100644
--- a/python/ovs/jsonrpc.py
+++ b/python/ovs/jsonrpc.py
@@ -264,6 +264,16 @@ class Connection(object):
         while True:
             if not self.input:
                 error, data = self.stream.recv(4096)
+                # Python 3 has separate types for strings and bytes.  We
+                # received bytes from a socket.  We expect it to be string
+                # data, so we convert it here as soon as possible.
+                if (data and not error
+                        and not isinstance(data, six.string_types)):
+                    try:
+                        data = data.decode('utf-8')
+                    except UnicodeError:
+                        # XXX Illegal byte sequence. Is there a better errno?
+                        error = errno.EILSEQ
                 if error:
                     if error == errno.EAGAIN:
                         return error, None
diff --git a/python/ovs/socket_util.py b/python/ovs/socket_util.py
index 071d67b..27c17c4 100644
--- a/python/ovs/socket_util.py
+++ b/python/ovs/socket_util.py
@@ -19,6 +19,7 @@ import random
 import socket
 import sys
 
+import six
 from six.moves import range
 
 import ovs.fatal_signal
@@ -275,6 +276,8 @@ def write_fully(fd, buf):
     bytes_written = 0
     if len(buf) == 0:
         return 0, 0
+    if sys.version_info[0] >= 3 and not isinstance(buf, six.binary_type):
+        buf = six.binary_type(buf, 'utf-8')
     while True:
         try:
             retval = os.write(fd, buf)
diff --git a/python/ovs/stream.py b/python/ovs/stream.py
index a555a76..bc14836 100644
--- a/python/ovs/stream.py
+++ b/python/ovs/stream.py
@@ -15,6 +15,7 @@
 import errno
 import os
 import socket
+import sys
 
 import six
 
@@ -223,6 +224,11 @@ class Stream(object):
             return 0
 
         try:
+            # Python 3 has separate types for strings and bytes.  We must have
+            # bytes here.
+            if (sys.version_info[0] >= 3
+                    and not isinstance(buf, six.binary_type)):
+                buf = six.binary_type(buf, 'utf-8')
             return self.socket.send(buf)
         except socket.error as e:
             return -ovs.socket_util.get_exception_errno(e)
-- 
2.5.0




More information about the dev mailing list