aboutsummaryrefslogtreecommitdiffhomepage
path: root/python/google/protobuf/proto_builder.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/google/protobuf/proto_builder.py')
-rw-r--r--python/google/protobuf/proto_builder.py20
1 files changed, 15 insertions, 5 deletions
diff --git a/python/google/protobuf/proto_builder.py b/python/google/protobuf/proto_builder.py
index 1fa28f1a..7489cf63 100644
--- a/python/google/protobuf/proto_builder.py
+++ b/python/google/protobuf/proto_builder.py
@@ -30,6 +30,7 @@
"""Dynamic Protobuf class creator."""
+import collections
import hashlib
import os
@@ -59,7 +60,9 @@ def MakeSimpleProtoClass(fields, full_name, pool=None):
Note: this doesn't validate field names!
Args:
- fields: dict of {name: field_type} mappings for each field in the proto.
+ fields: dict of {name: field_type} mappings for each field in the proto. If
+ this is an OrderedDict the order will be maintained, otherwise the
+ fields will be sorted by name.
full_name: str, the fully-qualified name of the proto type.
pool: optional DescriptorPool instance.
Returns:
@@ -73,12 +76,19 @@ def MakeSimpleProtoClass(fields, full_name, pool=None):
# The factory's DescriptorPool doesn't know about this class yet.
pass
+ # Get a list of (name, field_type) tuples from the fields dict. If fields was
+ # an OrderedDict we keep the order, but otherwise we sort the field to ensure
+ # consistent ordering.
+ field_items = fields.items()
+ if not isinstance(fields, collections.OrderedDict):
+ field_items = sorted(field_items)
+
# Use a consistent file name that is unlikely to conflict with any imported
# proto files.
fields_hash = hashlib.sha1()
- for f_name, f_type in sorted(fields.items()):
- fields_hash.update(f_name.encode('utf8'))
- fields_hash.update(str(f_type).encode('utf8'))
+ for f_name, f_type in field_items:
+ fields_hash.update(f_name.encode('utf-8'))
+ fields_hash.update(str(f_type).encode('utf-8'))
proto_file_name = fields_hash.hexdigest() + '.proto'
package, name = full_name.rsplit('.', 1)
@@ -87,7 +97,7 @@ def MakeSimpleProtoClass(fields, full_name, pool=None):
file_proto.package = package
desc_proto = file_proto.message_type.add()
desc_proto.name = name
- for f_number, (f_name, f_type) in enumerate(sorted(fields.items()), 1):
+ for f_number, (f_name, f_type) in enumerate(field_items, 1):
field_proto = desc_proto.field.add()
field_proto.name = f_name
field_proto.number = f_number