Bladeren bron

fix json_format for python2.6:
1, objcect_pair_hook is not supported in python2.6, so duplicated key check is removed in 2.6
2, total_seconds is not suppoted in python2.6, changed to compute seconds directly

Jie Luo 10 jaren geleden
bovenliggende
commit
2850a98275
4 gewijzigde bestanden met toevoegingen van 27 en 11 verwijderingen
  1. 9 4
      python/google/protobuf/internal/json_format_test.py
  2. 16 3
      python/google/protobuf/json_format.py
  3. 1 2
      python/tox.ini
  4. 1 2
      travis.sh

+ 9 - 4
python/google/protobuf/internal/json_format_test.py

@@ -410,6 +410,9 @@ class JsonFormatTest(JsonFormatBase):
                     '"unknownName".')
                     '"unknownName".')
 
 
   def testDuplicateField(self):
   def testDuplicateField(self):
+    # Duplicate key check is not supported for python2.6
+    if sys.version_info < (2, 7):
+      return
     self.CheckError('{"int32Value": 1,\n"int32Value":2}',
     self.CheckError('{"int32Value": 1,\n"int32Value":2}',
                     'Failed to load JSON: duplicate key int32Value')
                     'Failed to load JSON: duplicate key int32Value')
 
 
@@ -468,15 +471,17 @@ class JsonFormatTest(JsonFormatBase):
         (r'Failed to load JSON: Expecting property name'
         (r'Failed to load JSON: Expecting property name'
          r'( enclosed in double quotes)?: line 1'),
          r'( enclosed in double quotes)?: line 1'),
         json_format.Parse, text, message)
         json_format.Parse, text, message)
-    text = r'{"stringMap": {"a": 3, "\u0061": 2}}'
+    text = '{"boolMap": {"null": 1}}'
     self.assertRaisesRegexp(
     self.assertRaisesRegexp(
         json_format.ParseError,
         json_format.ParseError,
-        'Failed to load JSON: duplicate key a',
+        'Failed to parse boolMap field: Expect "true" or "false", not null.',
         json_format.Parse, text, message)
         json_format.Parse, text, message)
-    text = '{"boolMap": {"null": 1}}'
+    if sys.version_info < (2, 7):
+      return
+    text = r'{"stringMap": {"a": 3, "\u0061": 2}}'
     self.assertRaisesRegexp(
     self.assertRaisesRegexp(
         json_format.ParseError,
         json_format.ParseError,
-        'Failed to parse boolMap field: Expect "true" or "false", not null.',
+        'Failed to load JSON: duplicate key a',
         json_format.Parse, text, message)
         json_format.Parse, text, message)
 
 
   def testInvalidTimestamp(self):
   def testInvalidTimestamp(self):

+ 16 - 3
python/google/protobuf/json_format.py

@@ -37,6 +37,7 @@ from datetime import datetime
 import json
 import json
 import math
 import math
 import re
 import re
+import sys
 
 
 from google.protobuf import descriptor
 from google.protobuf import descriptor
 
 
@@ -114,7 +115,14 @@ def _RegularMessageToJsonObject(message, including_default_value_fields):
         # Convert a map field.
         # Convert a map field.
         js_map = {}
         js_map = {}
         for key in value:
         for key in value:
-          js_map[key] = _ConvertFieldToJsonObject(
+          if isinstance(key, bool):
+            if key:
+              recorded_key = 'true'
+            else:
+              recorded_key = 'false'
+          else:
+            recorded_key = key
+          js_map[recorded_key] = _ConvertFieldToJsonObject(
               field.message_type.fields_by_name['value'],
               field.message_type.fields_by_name['value'],
               value[key], including_default_value_fields)
               value[key], including_default_value_fields)
         js[name] = js_map
         js[name] = js_map
@@ -297,7 +305,11 @@ def Parse(text, message):
   """
   """
   if not isinstance(text, _UNICODETYPE): text = text.decode('utf-8')
   if not isinstance(text, _UNICODETYPE): text = text.decode('utf-8')
   try:
   try:
-    js = json.loads(text, object_pairs_hook=_DuplicateChecker)
+    if sys.version_info < (2, 7):
+      # object_pair_hook is not supported before python2.7
+      js = json.loads(text)
+    else:
+      js = json.loads(text, object_pairs_hook=_DuplicateChecker)
   except ValueError as e:
   except ValueError as e:
     raise ParseError('Failed to load JSON: ' + str(e))
     raise ParseError('Failed to load JSON: ' + str(e))
   _ConvertFieldValuePair(js, message)
   _ConvertFieldValuePair(js, message)
@@ -419,7 +431,8 @@ def _ConvertTimestampMessage(value, message):
     second_value = time_value[:point_position]
     second_value = time_value[:point_position]
     nano_value = time_value[point_position + 1:]
     nano_value = time_value[point_position + 1:]
   date_object = datetime.strptime(second_value, _TIMESTAMPFOMAT)
   date_object = datetime.strptime(second_value, _TIMESTAMPFOMAT)
-  seconds = (date_object - datetime(1970, 1, 1)).total_seconds()
+  td = date_object - datetime(1970, 1, 1)
+  seconds = td.seconds + td.days * 24 * 3600
   if len(nano_value) > 9:
   if len(nano_value) > 9:
     raise ParseError(
     raise ParseError(
         'Failed to parse Timestamp: nanos {0} more than '
         'Failed to parse Timestamp: nanos {0} more than '

+ 1 - 2
python/tox.ini

@@ -2,8 +2,7 @@
 envlist =
 envlist =
     # cpp implementation on py34 is currently broken due to
     # cpp implementation on py34 is currently broken due to
     # changes introduced by http://bugs.python.org/issue22079.
     # changes introduced by http://bugs.python.org/issue22079.
-    # py26 is currently broken due to the json_format
-    py{27,33,34}-{cpp,python}
+    py{26,27,33,34}-{cpp,python}
 
 
 [testenv]
 [testenv]
 usedevelop=true
 usedevelop=true

+ 1 - 2
travis.sh

@@ -131,8 +131,7 @@ build_python() {
   cd python
   cd python
   # Only test Python 2.6/3.x on Linux
   # Only test Python 2.6/3.x on Linux
   if [ $(uname -s) == "Linux" ]; then
   if [ $(uname -s) == "Linux" ]; then
-    # py26 is currently disabled due to json_format
-    envlist=py\{27,33,34\}-python
+    envlist=py\{26,27,33,34\}-python
   else
   else
     envlist=py27-python
     envlist=py27-python
   fi
   fi