diff options
Diffstat (limited to 'python/google/protobuf/proto_builder.py')
-rw-r--r-- | python/google/protobuf/proto_builder.py | 20 |
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 |