فهرست منبع

Merge pull request #728 from dano/py3_str_compat

Get all tests passing on Python3 (except Python3.4 cpp implementation)
Joshua Haberman 10 سال پیش
والد
کامیت
c7a1f8ec3b
3فایلهای تغییر یافته به همراه27 افزوده شده و 11 حذف شده
  1. 3 2
      python/google/protobuf/descriptor.py
  2. 21 6
      python/google/protobuf/text_format.py
  3. 3 3
      python/tox.ini

+ 3 - 2
python/google/protobuf/descriptor.py

@@ -36,6 +36,8 @@ file, in types that make this information accessible in Python.
 
 __author__ = 'robinson@google.com (Will Robinson)'
 
+import six
+
 from google.protobuf.internal import api_implementation
 
 
@@ -73,7 +75,7 @@ else:
   DescriptorMetaclass = type
 
 
-class DescriptorBase(object):
+class DescriptorBase(six.with_metaclass(DescriptorMetaclass)):
 
   """Descriptors base class.
 
@@ -88,7 +90,6 @@ class DescriptorBase(object):
         avoid some bootstrapping issues.
   """
 
-  __metaclass__ = DescriptorMetaclass
   if _USE_C_DESCRIPTORS:
     # The class, or tuple of classes, that are considered as "virtual
     # subclasses" of this descriptor class.

+ 21 - 6
python/google/protobuf/text_format.py

@@ -67,6 +67,25 @@ class Error(Exception):
 class ParseError(Error):
   """Thrown in case of ASCII parsing error."""
 
+class TextWriter(object):
+  def __init__(self, as_utf8):
+    if six.PY2:
+      self._writer = io.BytesIO()
+    else:
+      self._writer = io.StringIO()
+
+  def write(self, val):
+    if six.PY2:
+      if isinstance(val, six.text_type):
+        val = val.encode('utf-8')
+    return self._writer.write(val)
+
+  def close(self):
+    return self._writer.close()
+
+  def getvalue(self):
+    return self._writer.getvalue()
+
 
 def MessageToString(message, as_utf8=False, as_one_line=False,
                     pointy_brackets=False, use_index_order=False,
@@ -92,7 +111,7 @@ def MessageToString(message, as_utf8=False, as_one_line=False,
   Returns:
     A string of the text formatted protocol buffer message.
   """
-  out = io.BytesIO()
+  out = TextWriter(as_utf8)
   PrintMessage(message, out, as_utf8=as_utf8, as_one_line=as_one_line,
                pointy_brackets=pointy_brackets,
                use_index_order=use_index_order,
@@ -159,11 +178,7 @@ def PrintField(field, value, out, indent=0, as_utf8=False, as_one_line=False,
     # For groups, use the capitalized name.
     out.write(field.message_type.name)
   else:
-    if isinstance(field.name, six.text_type):
-      name = field.name.encode('utf-8')
-    else:
-      name = field.name
-    out.write(name)
+    out.write(field.name)
 
   if field.cpp_type != descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
     # The colon is optional in this case, but our cross-language golden files

+ 3 - 3
python/tox.ini

@@ -1,9 +1,9 @@
 [tox]
 envlist =
-    # Py3 tests currently fail because of text handling issues,
-    # So only test py26/py27 for now.
+    # cpp implementation on py34 is currently broken due to
+    # changes introduced by http://bugs.python.org/issue22079.
     #py{26,27,33,34}-{cpp,python}
-    py{26,27}-{cpp,python}
+    py{26,27,33}-{cpp,python}, py34-{python}
 
 [testenv]
 usedevelop=true