python: Deal with str and byte differences.
authorRussell Bryant <russell@ovn.org>
Thu, 17 Dec 2015 14:45:58 +0000 (09:45 -0500)
committerRussell Bryant <russell@ovn.org>
Tue, 2 Feb 2016 21:43:35 +0000 (16:43 -0500)
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@ovn.org>
Acked-by: Ben Pfaff <blp@ovn.org>
python/ovs/jsonrpc.py
python/ovs/socket_util.py
python/ovs/stream.py

index efe0f6c..e3ef6db 100644 (file)
@@ -264,6 +264,15 @@ 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:
+                        error = errno.EILSEQ
                 if error:
                     if error == errno.EAGAIN:
                         return error, None
index 22ac3f9..9f46a55 100644 (file)
@@ -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)
index a555a76..bc14836 100644 (file)
@@ -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)