]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
pybind: Don't encode str on Python 2
authorDavid Coles <dcoles@gaikai.com>
Tue, 20 Oct 2015 02:42:18 +0000 (19:42 -0700)
committerDavid Coles <dcoles@gaikai.com>
Fri, 13 Nov 2015 01:26:01 +0000 (17:26 -0800)
If you attempt to call encode on a non-ASCII string, then a UnicodeDecodeError
will be raised.

Since str on Python 2 is an 8-bit string, it's possible that it's already UTF-8
encoded. As such we should just pass it through to the C API unmodified.

On Python 3 or if the user explicitly uses unicode, then we'll encode it to
UTF-8 for them.

Signed-off-by: David Coles <dcoles@gaikai.com>
src/pybind/rados.py
src/pybind/rbd.py

index 684fd5e46321b52a09a8b6b4cb45d6a3fc32e769..69431d229a4536fa6fe5d60c0684c00a315f99ac 100644 (file)
@@ -29,7 +29,11 @@ LIBRADOS_OP_FLAG_FADVISE_DONTNEED = 0x20
 LIBRADOS_OP_FLAG_FADVISE_NOCACHE = 0x40
 
 
-if sys.hexversion < 0x03000000:
+# Are we running Python 2.x
+_python2 = sys.hexversion < 0x03000000
+
+
+if _python2:
     str_type = basestring
 else:
     str_type = str
@@ -279,7 +283,11 @@ def cstr(val, encoding="utf-8"):
     if val is None:
         return c_char_p(None)
 
-    return c_char_p(val.encode(encoding))
+    if _python2 and isinstance(val, str):
+        # Don't encode str on Python 2, as it's already an 8-bit string
+        return c_char_p(val)
+    else:
+        return c_char_p(val.encode(encoding))
 
 
 class Rados(object):
index f8c66cd1f56180809139973aa507fc47d03a2966..c15a943be769d31783f68c24e89293b1f0433468 100644 (file)
@@ -9,10 +9,6 @@ Error codes from librbd are turned into exceptions that subclass
 (the base class of all rbd exceptions), :class:`PermissionError`
 and :class:`IOError`, in addition to those documented for the
 method.
-
-A number of methods have string arguments, which must not be unicode
-to interact correctly with librbd. If unicode is passed to these
-methods, a :class:`TypeError` will be raised.
 """
 # Copyright 2011 Josh Durgin
 from collections import Iterable
@@ -68,7 +64,11 @@ RBD_FEATURES_SINGLE_CLIENT = (RBD_FEATURE_EXCLUSIVE_LOCK |
 RBD_FLAG_OBJECT_MAP_INVALID = 1
 
 
-if sys.hexversion < 0x03000000:
+# Are we running Python 2.x
+_python2 = sys.hexversion < 0x03000000
+
+
+if _python2:
     str_type = basestring
 else:
     str_type = str
@@ -212,7 +212,11 @@ def cstr(val, encoding="utf-8"):
     if val is None:
         return c_char_p(None)
 
-    return c_char_p(val.encode(encoding))
+    if _python2 and isinstance(val, str):
+        # Don't encode str on Python 2, as it's already an 8-bit string
+        return c_char_p(val)
+    else:
+        return c_char_p(val.encode(encoding))
 
 
 class RBD(object):