-
federicodotta committed 3 years ago1 parent d2fe6cc0
Revision indexing in progress... (symbol navigation in revisions will be accurate after indexed)
Showing first 21 files as there are too many
-
-
-
-
-
-
skipped 33 lines 34 34 35 35 __author__ = '[email protected] (Will Robinson)' 36 36 37 + import threading 38 + import warnings 37 39 import six 38 40 39 41 from google.protobuf.internal import api_implementation skipped 1 lines 41 43 _USE_C_DESCRIPTORS = False 42 44 if api_implementation.Type() == 'cpp': 43 45 # Used by MakeDescriptor in cpp mode 46 + import binascii 44 47 import os 45 - import uuid 46 48 from google.protobuf.pyext import _message 47 - _USE_C_DESCRIPTORS = getattr(_message, '_USE_C_DESCRIPTORS', False) 49 + _USE_C_DESCRIPTORS = True 48 50 49 51 50 52 class Error(Exception): skipped 21 lines 72 74 DescriptorMetaclass = type 73 75 74 76 77 + class _Lock(object): 78 + """Wrapper class of threading.Lock(), which is allowed by 'with'.""" 79 + 80 + def __new__(cls): 81 + self = object.__new__(cls) 82 + self._lock = threading.Lock() # pylint: disable=protected-access 83 + return self 84 + 85 + def __enter__(self): 86 + self._lock.acquire() 87 + 88 + def __exit__(self, exc_type, exc_value, exc_tb): 89 + self._lock.release() 90 + 91 + 92 + _lock = threading.Lock() 93 + 94 + 95 + def _Deprecated(name): 96 + if _Deprecated.count > 0: 97 + _Deprecated.count -= 1 98 + warnings.warn( 99 + 'Call to deprecated create function %s(). Note: Create unlinked ' 100 + 'descriptors is going to go away. Please use get/find descriptors from ' 101 + 'generated code or query the descriptor_pool.' 102 + % name, 103 + category=DeprecationWarning, stacklevel=3) 104 + 105 + 106 + # Deprecated warnings will print 100 times at most which should be enough for 107 + # users to notice and do not cause timeout. 108 + _Deprecated.count = 100 109 + 110 + 111 + _internal_create_key = object() 112 + 113 + 75 114 class DescriptorBase(six.with_metaclass(DescriptorMetaclass)): 76 115 77 116 """Descriptors base class. skipped 14 lines 92 131 # subclasses" of this descriptor class. 93 132 _C_DESCRIPTOR_CLASS = () 94 133 95 - def __init__(self, options, options_class_name): 134 + def __init__(self, options, serialized_options, options_class_name): 96 135 """Initialize the descriptor given its options message and the name of the 97 136 class of the options message. The name of the class is required in case 98 137 the options message is None and has to be created. 99 138 """ 100 139 self._options = options 101 140 self._options_class_name = options_class_name 141 + self._serialized_options = serialized_options 102 142 103 143 # Does this descriptor have non-default options? 104 - self.has_options = options is not None 144 + self.has_options = (options is not None) or (serialized_options is not None) 105 145 106 146 def _SetOptions(self, options, options_class_name): 107 147 """Sets the descriptor's options skipped 15 lines 123 163 """ 124 164 if self._options: 125 165 return self._options 166 + 126 167 from google.protobuf import descriptor_pb2 127 168 try: 128 - options_class = getattr(descriptor_pb2, self._options_class_name) 169 + options_class = getattr(descriptor_pb2, 170 + self._options_class_name) 129 171 except AttributeError: 130 172 raise RuntimeError('Unknown options class name %s!' % 131 173 (self._options_class_name)) 132 - self._options = options_class() 133 - return self._options 174 + 175 + with _lock: 176 + if self._serialized_options is None: 177 + self._options = options_class() 178 + else: 179 + self._options = _ParseOptions(options_class(), 180 + self._serialized_options) 181 + 182 + return self._options 134 183 135 184 136 185 class _NestedDescriptorBase(DescriptorBase): skipped 1 lines 138 187 139 188 def __init__(self, options, options_class_name, name, full_name, 140 189 file, containing_type, serialized_start=None, 141 - serialized_end=None): 190 + serialized_end=None, serialized_options=None): 142 191 """Constructor. 143 192 144 193 Args: 145 194 options: Protocol message options or None 146 195 to use default message options. 147 - options_class_name: (str) The class name of the above options. 148 - 149 - name: (str) Name of this protocol message type. 150 - full_name: (str) Fully-qualified name of this protocol message type, 196 + options_class_name (str): The class name of the above options. 197 + name (str): Name of this protocol message type. 198 + full_name (str): Fully-qualified name of this protocol message type, 151 199 which will include protocol "package" name and the name of any 152 200 enclosing types. 153 - file: (FileDescriptor) Reference to file info. 201 + file (FileDescriptor): Reference to file info. 154 202 containing_type: if provided, this is a nested descriptor, with this 155 203 descriptor as parent, otherwise None. 156 204 serialized_start: The start index (inclusive) in block in the 157 205 file.serialized_pb that describes this descriptor. 158 206 serialized_end: The end index (exclusive) in block in the 159 207 file.serialized_pb that describes this descriptor. 208 + serialized_options: Protocol message serialized options or None. 160 209 """ 161 210 super(_NestedDescriptorBase, self).__init__( 162 - options, options_class_name) 211 + options, serialized_options, options_class_name) 163 212 164 213 self.name = name 165 214 # TODO(falk): Add function to calculate full_name instead of having it in skipped 12 lines 178 227 proto: An empty proto instance from descriptor_pb2. 179 228 180 229 Raises: 181 - Error: If self couldnt be serialized, due to to few constructor arguments. 230 + Error: If self couldn't be serialized, due to to few constructor 231 + arguments. 182 232 """ 183 233 if (self.file is not None and 184 234 self._serialized_start is not None and skipped 8 lines 193 243 194 244 """Descriptor for a protocol message type. 195 245 196 - A Descriptor instance has the following attributes: 197 - 198 - name: (str) Name of this protocol message type. 199 - full_name: (str) Fully-qualified name of this protocol message type, 200 - which will include protocol "package" name and the name of any 201 - enclosing types. 202 - 203 - containing_type: (Descriptor) Reference to the descriptor of the 204 - type containing us, or None if this is top-level. 205 - 206 - fields: (list of FieldDescriptors) Field descriptors for all 207 - fields in this type. 208 - fields_by_number: (dict int -> FieldDescriptor) Same FieldDescriptor 209 - objects as in |fields|, but indexed by "number" attribute in each 210 - FieldDescriptor. 211 - fields_by_name: (dict str -> FieldDescriptor) Same FieldDescriptor 212 - objects as in |fields|, but indexed by "name" attribute in each 213 - FieldDescriptor. 214 - fields_by_camelcase_name: (dict str -> FieldDescriptor) Same 215 - FieldDescriptor objects as in |fields|, but indexed by 216 - "camelcase_name" attribute in each FieldDescriptor. 217 - 218 - nested_types: (list of Descriptors) Descriptor references 219 - for all protocol message types nested within this one. 220 - nested_types_by_name: (dict str -> Descriptor) Same Descriptor 221 - objects as in |nested_types|, but indexed by "name" attribute 222 - in each Descriptor. 223 - 224 - enum_types: (list of EnumDescriptors) EnumDescriptor references 225 - for all enums contained within this type. 226 - enum_types_by_name: (dict str ->EnumDescriptor) Same EnumDescriptor 227 - objects as in |enum_types|, but indexed by "name" attribute 228 - in each EnumDescriptor. 229 - enum_values_by_name: (dict str -> EnumValueDescriptor) Dict mapping 230 - from enum value name to EnumValueDescriptor for that value. 231 - 232 - extensions: (list of FieldDescriptor) All extensions defined directly 233 - within this message type (NOT within a nested type). 234 - extensions_by_name: (dict, string -> FieldDescriptor) Same FieldDescriptor 235 - objects as |extensions|, but indexed by "name" attribute of each 236 - FieldDescriptor. 237 - 238 - is_extendable: Does this type define any extension ranges? 239 - 240 - oneofs: (list of OneofDescriptor) The list of descriptors for oneof fields 241 - in this message. 242 - oneofs_by_name: (dict str -> OneofDescriptor) Same objects as in |oneofs|, 243 - but indexed by "name" attribute. 246 + Attributes: 247 + name (str): Name of this protocol message type. 248 + full_name (str): Fully-qualified name of this protocol message type, 249 + which will include protocol "package" name and the name of any 250 + enclosing types. 251 + containing_type (Descriptor): Reference to the descriptor of the type 252 + containing us, or None if this is top-level. 253 + fields (list[FieldDescriptor]): Field descriptors for all fields in 254 + this type. 255 + fields_by_number (dict(int, FieldDescriptor)): Same 256 + :class:`FieldDescriptor` objects as in :attr:`fields`, but indexed 257 + by "number" attribute in each FieldDescriptor. 258 + fields_by_name (dict(str, FieldDescriptor)): Same 259 + :class:`FieldDescriptor` objects as in :attr:`fields`, but indexed by 260 + "name" attribute in each :class:`FieldDescriptor`. 261 + nested_types (list[Descriptor]): Descriptor references 262 + for all protocol message types nested within this one. 263 + nested_types_by_name (dict(str, Descriptor)): Same Descriptor 264 + objects as in :attr:`nested_types`, but indexed by "name" attribute 265 + in each Descriptor. 266 + enum_types (list[EnumDescriptor]): :class:`EnumDescriptor` references 267 + for all enums contained within this type. 268 + enum_types_by_name (dict(str, EnumDescriptor)): Same 269 + :class:`EnumDescriptor` objects as in :attr:`enum_types`, but 270 + indexed by "name" attribute in each EnumDescriptor. 271 + enum_values_by_name (dict(str, EnumValueDescriptor)): Dict mapping 272 + from enum value name to :class:`EnumValueDescriptor` for that value. 273 + extensions (list[FieldDescriptor]): All extensions defined directly 274 + within this message type (NOT within a nested type). 275 + extensions_by_name (dict(str, FieldDescriptor)): Same FieldDescriptor 276 + objects as :attr:`extensions`, but indexed by "name" attribute of each 277 + FieldDescriptor. 278 + is_extendable (bool): Does this type define any extension ranges? 279 + oneofs (list[OneofDescriptor]): The list of descriptors for oneof fields 280 + in this message. 281 + oneofs_by_name (dict(str, OneofDescriptor)): Same objects as in 282 + :attr:`oneofs`, but indexed by "name" attribute. 283 + file (FileDescriptor): Reference to file descriptor. 244 284 245 - file: (FileDescriptor) Reference to file descriptor. 246 285 """ 247 286 248 287 if _USE_C_DESCRIPTORS: 249 288 _C_DESCRIPTOR_CLASS = _message.Descriptor 250 289 251 - def __new__(cls, name, full_name, filename, containing_type, fields, 252 - nested_types, enum_types, extensions, options=None, 253 - is_extendable=True, extension_ranges=None, oneofs=None, 254 - file=None, serialized_start=None, serialized_end=None, # pylint: disable=redefined-builtin 255 - syntax=None): 290 + def __new__( 291 + cls, 292 + name=None, 293 + full_name=None, 294 + filename=None, 295 + containing_type=None, 296 + fields=None, 297 + nested_types=None, 298 + enum_types=None, 299 + extensions=None, 300 + options=None, 301 + serialized_options=None, 302 + is_extendable=True, 303 + extension_ranges=None, 304 + oneofs=None, 305 + file=None, # pylint: disable=redefined-builtin 306 + serialized_start=None, 307 + serialized_end=None, 308 + syntax=None, 309 + create_key=None): 256 310 _message.Message._CheckCalledFromGeneratedFile() 257 311 return _message.default_pool.FindMessageTypeByName(full_name) 258 312 skipped 2 lines 261 315 # name of the argument. 262 316 def __init__(self, name, full_name, filename, containing_type, fields, 263 317 nested_types, enum_types, extensions, options=None, 318 + serialized_options=None, 264 319 is_extendable=True, extension_ranges=None, oneofs=None, 265 320 file=None, serialized_start=None, serialized_end=None, # pylint: disable=redefined-builtin 266 - syntax=None): 321 + syntax=None, create_key=None): 267 322 """Arguments to __init__() are as described in the description 268 323 of Descriptor fields above. 269 324 270 325 Note that filename is an obsolete argument, that is not used anymore. 271 326 Please use file.name to access this as an attribute. 272 327 """ 328 + if create_key is not _internal_create_key: 329 + _Deprecated('Descriptor') 330 + 273 331 super(Descriptor, self).__init__( 274 332 options, 'MessageOptions', name, full_name, file, 275 333 containing_type, serialized_start=serialized_start, 276 - serialized_end=serialized_end) 334 + serialized_end=serialized_end, serialized_options=serialized_options) 277 335 278 336 # We have fields in addition to fields_by_name and fields_by_number, 279 337 # so that: skipped 33 lines 313 371 314 372 @property 315 373 def fields_by_camelcase_name(self): 374 + """Same FieldDescriptor objects as in :attr:`fields`, but indexed by 375 + :attr:`FieldDescriptor.camelcase_name`. 376 + """ 316 377 if self._fields_by_camelcase_name is None: 317 378 self._fields_by_camelcase_name = dict( 318 379 (f.camelcase_name, f) for f in self.fields) skipped 42 lines 361 422 362 423 """Descriptor for a single field in a .proto file. 363 424 364 - A FieldDescriptor instance has the following attributes: 365 - 366 - name: (str) Name of this field, exactly as it appears in .proto. 367 - full_name: (str) Name of this field, including containing scope. This is 425 + Attributes: 426 + name (str): Name of this field, exactly as it appears in .proto. 427 + full_name (str): Name of this field, including containing scope. This is 368 428 particularly relevant for extensions. 369 - camelcase_name: (str) Camelcase name of this field. 370 - index: (int) Dense, 0-indexed index giving the order that this 429 + index (int): Dense, 0-indexed index giving the order that this 371 430 field textually appears within its message in the .proto file. 372 - number: (int) Tag number declared for this field in the .proto file. 431 + number (int): Tag number declared for this field in the .proto file. 373 432 374 - type: (One of the TYPE_* constants below) Declared type. 375 - cpp_type: (One of the CPPTYPE_* constants below) C++ type used to 433 + type (int): (One of the TYPE_* constants below) Declared type. 434 + cpp_type (int): (One of the CPPTYPE_* constants below) C++ type used to 376 435 represent this field. 377 436 378 - label: (One of the LABEL_* constants below) Tells whether this 437 + label (int): (One of the LABEL_* constants below) Tells whether this 379 438 field is optional, required, or repeated. 380 - has_default_value: (bool) True if this field has a default value defined, 439 + has_default_value (bool): True if this field has a default value defined, 381 440 otherwise false. 382 - default_value: (Varies) Default value of this field. Only 441 + default_value (Varies): Default value of this field. Only 383 442 meaningful for non-repeated scalar fields. Repeated fields 384 443 should always set this to [], and non-repeated composite 385 444 fields should always set this to None. 386 445 387 - containing_type: (Descriptor) Descriptor of the protocol message 446 + containing_type (Descriptor): Descriptor of the protocol message 388 447 type that contains this field. Set by the Descriptor constructor 389 448 if we're passed into one. 390 449 Somewhat confusingly, for extension fields, this is the 391 450 descriptor of the EXTENDED message, not the descriptor 392 451 of the message containing this field. (See is_extension and 393 452 extension_scope below). 394 - message_type: (Descriptor) If a composite field, a descriptor 453 + message_type (Descriptor): If a composite field, a descriptor 395 454 of the message type contained in this field. Otherwise, this is None. 396 - enum_type: (EnumDescriptor) If this field contains an enum, a 455 + enum_type (EnumDescriptor): If this field contains an enum, a 397 456 descriptor of that enum. Otherwise, this is None. 398 457 399 458 is_extension: True iff this describes an extension field. 400 - extension_scope: (Descriptor) Only meaningful if is_extension is True. 459 + extension_scope (Descriptor): Only meaningful if is_extension is True. 401 460 Gives the message that immediately contains this extension field. 402 461 Will be None iff we're a top-level (file-level) extension field. 403 462 404 - options: (descriptor_pb2.FieldOptions) Protocol message field options or 463 + options (descriptor_pb2.FieldOptions): Protocol message field options or 405 464 None to use default field options. 406 465 407 - containing_oneof: (OneofDescriptor) If the field is a member of a oneof 466 + containing_oneof (OneofDescriptor): If the field is a member of a oneof 408 467 union, contains its descriptor. Otherwise, None. 468 + 469 + file (FileDescriptor): Reference to file descriptor. 409 470 """ 410 471 411 472 # Must be consistent with C++ FieldDescriptor::Type enum in skipped 78 lines 490 551 def __new__(cls, name, full_name, index, number, type, cpp_type, label, 491 552 default_value, message_type, enum_type, containing_type, 492 553 is_extension, extension_scope, options=None, 493 - has_default_value=True, containing_oneof=None, json_name=None): 554 + serialized_options=None, 555 + has_default_value=True, containing_oneof=None, json_name=None, 556 + file=None, create_key=None): # pylint: disable=redefined-builtin 494 557 _message.Message._CheckCalledFromGeneratedFile() 495 558 if is_extension: 496 559 return _message.default_pool.FindExtensionByName(full_name) skipped 3 lines 500 563 def __init__(self, name, full_name, index, number, type, cpp_type, label, 501 564 default_value, message_type, enum_type, containing_type, 502 565 is_extension, extension_scope, options=None, 503 - has_default_value=True, containing_oneof=None, json_name=None): 566 + serialized_options=None, 567 + has_default_value=True, containing_oneof=None, json_name=None, 568 + file=None, create_key=None): # pylint: disable=redefined-builtin 504 569 """The arguments are as described in the description of FieldDescriptor 505 570 attributes above. 506 571 skipped 1 lines 508 573 (to deal with circular references between message types, for example). 509 574 Likewise for extension_scope. 510 575 """ 511 - super(FieldDescriptor, self).__init__(options, 'FieldOptions') 576 + if create_key is not _internal_create_key: 577 + _Deprecated('FieldDescriptor') 578 + 579 + super(FieldDescriptor, self).__init__( 580 + options, serialized_options, 'FieldOptions') 512 581 self.name = name 513 582 self.full_name = full_name 583 + self.file = file 514 584 self._camelcase_name = None 515 585 if json_name is None: 516 586 self.json_name = _ToJsonName(name) skipped 22 lines 539 609 540 610 @property 541 611 def camelcase_name(self): 612 + """Camelcase name of this field. 613 + 614 + Returns: 615 + str: the name in CamelCase. 616 + """ 542 617 if self._camelcase_name is None: 543 618 self._camelcase_name = _ToCamelCase(self.name) 544 619 return self._camelcase_name skipped 9 lines 554 629 Args: 555 630 proto_type: the Python proto type (descriptor.FieldDescriptor.TYPE_*) 556 631 Returns: 557 - descriptor.FieldDescriptor.CPPTYPE_*, the C++ type. 632 + int: descriptor.FieldDescriptor.CPPTYPE_*, the C++ type. 558 633 Raises: 559 634 TypeTransformationError: when the Python proto type isn't known. 560 635 """ skipped 7 lines 568 643 569 644 """Descriptor for an enum defined in a .proto file. 570 645 571 - An EnumDescriptor instance has the following attributes: 572 - 573 - name: (str) Name of the enum type. 574 - full_name: (str) Full name of the type, including package name 646 + Attributes: 647 + name (str): Name of the enum type. 648 + full_name (str): Full name of the type, including package name 575 649 and any enclosing type(s). 576 650 577 - values: (list of EnumValueDescriptors) List of the values 651 + values (list[EnumValueDescriptors]): List of the values 578 652 in this enum. 579 - values_by_name: (dict str -> EnumValueDescriptor) Same as |values|, 653 + values_by_name (dict(str, EnumValueDescriptor)): Same as :attr:`values`, 580 654 but indexed by the "name" field of each EnumValueDescriptor. 581 - values_by_number: (dict int -> EnumValueDescriptor) Same as |values|, 655 + values_by_number (dict(int, EnumValueDescriptor)): Same as :attr:`values`, 582 656 but indexed by the "number" field of each EnumValueDescriptor. 583 - containing_type: (Descriptor) Descriptor of the immediate containing 657 + containing_type (Descriptor): Descriptor of the immediate containing 584 658 type of this enum, or None if this is an enum defined at the 585 659 top level in a .proto file. Set by Descriptor's constructor 586 660 if we're passed into one. 587 - file: (FileDescriptor) Reference to file descriptor. 588 - options: (descriptor_pb2.EnumOptions) Enum options message or 661 + file (FileDescriptor): Reference to file descriptor. 662 + options (descriptor_pb2.EnumOptions): Enum options message or 589 663 None to use default enum options. 590 664 """ 591 665 skipped 1 lines 593 667 _C_DESCRIPTOR_CLASS = _message.EnumDescriptor 594 668 595 669 def __new__(cls, name, full_name, filename, values, 596 - containing_type=None, options=None, file=None, 597 - serialized_start=None, serialized_end=None): 670 + containing_type=None, options=None, 671 + serialized_options=None, file=None, # pylint: disable=redefined-builtin 672 + serialized_start=None, serialized_end=None, create_key=None): 598 673 _message.Message._CheckCalledFromGeneratedFile() 599 674 return _message.default_pool.FindEnumTypeByName(full_name) 600 675 601 676 def __init__(self, name, full_name, filename, values, 602 - containing_type=None, options=None, file=None, 603 - serialized_start=None, serialized_end=None): 677 + containing_type=None, options=None, 678 + serialized_options=None, file=None, # pylint: disable=redefined-builtin 679 + serialized_start=None, serialized_end=None, create_key=None): 604 680 """Arguments are as described in the attribute description above. 605 681 606 682 Note that filename is an obsolete argument, that is not used anymore. 607 683 Please use file.name to access this as an attribute. 608 684 """ 685 + if create_key is not _internal_create_key: 686 + _Deprecated('EnumDescriptor') 687 + 609 688 super(EnumDescriptor, self).__init__( 610 689 options, 'EnumOptions', name, full_name, file, 611 690 containing_type, serialized_start=serialized_start, 612 - serialized_end=serialized_end) 691 + serialized_end=serialized_end, serialized_options=serialized_options) 613 692 614 693 self.values = values 615 694 for value in self.values: 616 695 value.type = self 617 696 self.values_by_name = dict((v.name, v) for v in values) 618 - self.values_by_number = dict((v.number, v) for v in values) 697 + # Values are reversed to ensure that the first alias is retained. 698 + self.values_by_number = dict((v.number, v) for v in reversed(values)) 619 699 620 700 def CopyToProto(self, proto): 621 701 """Copies this to a descriptor_pb2.EnumDescriptorProto. 622 702 623 703 Args: 624 - proto: An empty descriptor_pb2.EnumDescriptorProto. 704 + proto (descriptor_pb2.EnumDescriptorProto): An empty descriptor proto. 625 705 """ 626 706 # This function is overridden to give a better doc comment. 627 707 super(EnumDescriptor, self).CopyToProto(proto) skipped 3 lines 631 711 632 712 """Descriptor for a single value within an enum. 633 713 634 - name: (str) Name of this value. 635 - index: (int) Dense, 0-indexed index giving the order that this 714 + Attributes: 715 + name (str): Name of this value. 716 + index (int): Dense, 0-indexed index giving the order that this 636 717 value appears textually within its enum in the .proto file. 637 - number: (int) Actual number assigned to this enum value. 638 - type: (EnumDescriptor) EnumDescriptor to which this value 639 - belongs. Set by EnumDescriptor's constructor if we're 718 + number (int): Actual number assigned to this enum value. 719 + type (EnumDescriptor): :class:`EnumDescriptor` to which this value 720 + belongs. Set by :class:`EnumDescriptor`'s constructor if we're 640 721 passed into one. 641 - options: (descriptor_pb2.EnumValueOptions) Enum value options message or 722 + options (descriptor_pb2.EnumValueOptions): Enum value options message or 642 723 None to use default enum value options options. 643 724 """ 644 725 645 726 if _USE_C_DESCRIPTORS: 646 727 _C_DESCRIPTOR_CLASS = _message.EnumValueDescriptor 647 728 648 - def __new__(cls, name, index, number, type=None, options=None): 729 + def __new__(cls, name, index, number, 730 + type=None, # pylint: disable=redefined-builtin 731 + options=None, serialized_options=None, create_key=None): 649 732 _message.Message._CheckCalledFromGeneratedFile() 650 733 # There is no way we can build a complete EnumValueDescriptor with the 651 734 # given parameters (the name of the Enum is not known, for example). skipped 1 lines 653 736 # constructor, which will ignore it, so returning None is good enough. 654 737 return None 655 738 656 - def __init__(self, name, index, number, type=None, options=None): 739 + def __init__(self, name, index, number, 740 + type=None, # pylint: disable=redefined-builtin 741 + options=None, serialized_options=None, create_key=None): 657 742 """Arguments are as described in the attribute description above.""" 658 - super(EnumValueDescriptor, self).__init__(options, 'EnumValueOptions') 743 + if create_key is not _internal_create_key: 744 + _Deprecated('EnumValueDescriptor') 745 + 746 + super(EnumValueDescriptor, self).__init__( 747 + options, serialized_options, 'EnumValueOptions') 659 748 self.name = name 660 749 self.index = index 661 750 self.number = number skipped 3 lines 665 754 class OneofDescriptor(DescriptorBase): 666 755 """Descriptor for a oneof field. 667 756 668 - name: (str) Name of the oneof field. 669 - full_name: (str) Full name of the oneof field, including package name. 670 - index: (int) 0-based index giving the order of the oneof field inside 757 + Attributes: 758 + name (str): Name of the oneof field. 759 + full_name (str): Full name of the oneof field, including package name. 760 + index (int): 0-based index giving the order of the oneof field inside 671 761 its containing type. 672 - containing_type: (Descriptor) Descriptor of the protocol message 673 - type that contains this field. Set by the Descriptor constructor 762 + containing_type (Descriptor): :class:`Descriptor` of the protocol message 763 + type that contains this field. Set by the :class:`Descriptor` constructor 674 764 if we're passed into one. 675 - fields: (list of FieldDescriptor) The list of field descriptors this 765 + fields (list[FieldDescriptor]): The list of field descriptors this 676 766 oneof can contain. 677 767 """ 678 768 skipped 1 lines 680 770 _C_DESCRIPTOR_CLASS = _message.OneofDescriptor 681 771 682 772 def __new__( 683 - cls, name, full_name, index, containing_type, fields, options=None): 773 + cls, name, full_name, index, containing_type, fields, options=None, 774 + serialized_options=None, create_key=None): 684 775 _message.Message._CheckCalledFromGeneratedFile() 685 776 return _message.default_pool.FindOneofByName(full_name) 686 777 687 778 def __init__( 688 - self, name, full_name, index, containing_type, fields, options=None): 779 + self, name, full_name, index, containing_type, fields, options=None, 780 + serialized_options=None, create_key=None): 689 781 """Arguments are as described in the attribute description above.""" 690 - super(OneofDescriptor, self).__init__(options, 'OneofOptions') 782 + if create_key is not _internal_create_key: 783 + _Deprecated('OneofDescriptor') 784 + 785 + super(OneofDescriptor, self).__init__( 786 + options, serialized_options, 'OneofOptions') 691 787 self.name = name 692 788 self.full_name = full_name 693 789 self.index = index skipped 5 lines 699 795 700 796 """Descriptor for a service. 701 797 702 - name: (str) Name of the service. 703 - full_name: (str) Full name of the service, including package name. 704 - index: (int) 0-indexed index giving the order that this services 705 - definition appears withing the .proto file. 706 - methods: (list of MethodDescriptor) List of methods provided by this 798 + Attributes: 799 + name (str): Name of the service. 800 + full_name (str): Full name of the service, including package name. 801 + index (int): 0-indexed index giving the order that this services 802 + definition appears within the .proto file. 803 + methods (list[MethodDescriptor]): List of methods provided by this 707 804 service. 708 - methods_by_name: (dict str -> MethodDescriptor) Same MethodDescriptor 709 - objects as in |methods_by_name|, but indexed by "name" attribute in each 710 - MethodDescriptor. 711 - options: (descriptor_pb2.ServiceOptions) Service options message or 805 + methods_by_name (dict(str, MethodDescriptor)): Same 806 + :class:`MethodDescriptor` objects as in :attr:`methods_by_name`, but 807 + indexed by "name" attribute in each :class:`MethodDescriptor`. 808 + options (descriptor_pb2.ServiceOptions): Service options message or 712 809 None to use default service options. 713 - file: (FileDescriptor) Reference to file info. 810 + file (FileDescriptor): Reference to file info. 714 811 """ 715 812 716 813 if _USE_C_DESCRIPTORS: 717 814 _C_DESCRIPTOR_CLASS = _message.ServiceDescriptor 718 815 719 - def __new__(cls, name, full_name, index, methods, options=None, file=None, # pylint: disable=redefined-builtin 720 - serialized_start=None, serialized_end=None): 816 + def __new__( 817 + cls, 818 + name=None, 819 + full_name=None, 820 + index=None, 821 + methods=None, 822 + options=None, 823 + serialized_options=None, 824 + file=None, # pylint: disable=redefined-builtin 825 + serialized_start=None, 826 + serialized_end=None, 827 + create_key=None): 721 828 _message.Message._CheckCalledFromGeneratedFile() # pylint: disable=protected-access 722 829 return _message.default_pool.FindServiceByName(full_name) 723 830 724 - def __init__(self, name, full_name, index, methods, options=None, file=None, 725 - serialized_start=None, serialized_end=None): 831 + def __init__(self, name, full_name, index, methods, options=None, 832 + serialized_options=None, file=None, # pylint: disable=redefined-builtin 833 + serialized_start=None, serialized_end=None, create_key=None): 834 + if create_key is not _internal_create_key: 835 + _Deprecated('ServiceDescriptor') 836 + 726 837 super(ServiceDescriptor, self).__init__( 727 838 options, 'ServiceOptions', name, full_name, file, 728 839 None, serialized_start=serialized_start, 729 - serialized_end=serialized_end) 840 + serialized_end=serialized_end, serialized_options=serialized_options) 730 841 self.index = index 731 842 self.methods = methods 732 843 self.methods_by_name = dict((m.name, m) for m in methods) skipped 2 lines 735 846 method.containing_service = self 736 847 737 848 def FindMethodByName(self, name): 738 - """Searches for the specified method, and returns its descriptor.""" 849 + """Searches for the specified method, and returns its descriptor. 850 + 851 + Args: 852 + name (str): Name of the method. 853 + Returns: 854 + MethodDescriptor or None: the descriptor for the requested method, if 855 + found. 856 + """ 739 857 return self.methods_by_name.get(name, None) 740 858 741 859 def CopyToProto(self, proto): 742 860 """Copies this to a descriptor_pb2.ServiceDescriptorProto. 743 861 744 862 Args: 745 - proto: An empty descriptor_pb2.ServiceDescriptorProto. 863 + proto (descriptor_pb2.ServiceDescriptorProto): An empty descriptor proto. 746 864 """ 747 865 # This function is overridden to give a better doc comment. 748 866 super(ServiceDescriptor, self).CopyToProto(proto) skipped 3 lines 752 870 753 871 """Descriptor for a method in a service. 754 872 755 - name: (str) Name of the method within the service. 756 - full_name: (str) Full name of method. 757 - index: (int) 0-indexed index of the method inside the service. 758 - containing_service: (ServiceDescriptor) The service that contains this 759 - method. 760 - input_type: The descriptor of the message that this method accepts. 761 - output_type: The descriptor of the message that this method returns. 762 - options: (descriptor_pb2.MethodOptions) Method options message or 763 - None to use default method options. 873 + Attributes: 874 + name (str): Name of the method within the service. 875 + full_name (str): Full name of method. 876 + index (int): 0-indexed index of the method inside the service. 877 + containing_service (ServiceDescriptor): The service that contains this 878 + method. 879 + input_type (Descriptor): The descriptor of the message that this method 880 + accepts. 881 + output_type (Descriptor): The descriptor of the message that this method 882 + returns. 883 + options (descriptor_pb2.MethodOptions or None): Method options message, or 884 + None to use default method options. 764 885 """ 765 886 766 887 if _USE_C_DESCRIPTORS: 767 888 _C_DESCRIPTOR_CLASS = _message.MethodDescriptor 768 889 769 890 def __new__(cls, name, full_name, index, containing_service, 770 - input_type, output_type, options=None): 891 + input_type, output_type, options=None, serialized_options=None, 892 + create_key=None): 771 893 _message.Message._CheckCalledFromGeneratedFile() # pylint: disable=protected-access 772 894 return _message.default_pool.FindMethodByName(full_name) 773 895 774 896 def __init__(self, name, full_name, index, containing_service, 775 - input_type, output_type, options=None): 897 + input_type, output_type, options=None, serialized_options=None, 898 + create_key=None): 776 899 """The arguments are as described in the description of MethodDescriptor 777 900 attributes above. 778 901 779 902 Note that containing_service may be None, and may be set later if necessary. 780 903 """ 781 - super(MethodDescriptor, self).__init__(options, 'MethodOptions') 904 + if create_key is not _internal_create_key: 905 + _Deprecated('MethodDescriptor') 906 + 907 + super(MethodDescriptor, self).__init__( 908 + options, serialized_options, 'MethodOptions') 782 909 self.name = name 783 910 self.full_name = full_name 784 911 self.index = index skipped 1 lines 786 913 self.input_type = input_type 787 914 self.output_type = output_type 788 915 916 + def CopyToProto(self, proto): 917 + """Copies this to a descriptor_pb2.MethodDescriptorProto. 918 + 919 + Args: 920 + proto (descriptor_pb2.MethodDescriptorProto): An empty descriptor proto. 921 + 922 + Raises: 923 + Error: If self couldn't be serialized, due to too few constructor 924 + arguments. 925 + """ 926 + if self.containing_service is not None: 927 + from google.protobuf import descriptor_pb2 928 + service_proto = descriptor_pb2.ServiceDescriptorProto() 929 + self.containing_service.CopyToProto(service_proto) 930 + proto.CopyFrom(service_proto.method[self.index]) 931 + else: 932 + raise Error('Descriptor does not contain a service.') 933 + 789 934 790 935 class FileDescriptor(DescriptorBase): 791 936 """Descriptor for a file. Mimics the descriptor_pb2.FileDescriptorProto. 792 937 793 - Note that enum_types_by_name, extensions_by_name, and dependencies 794 - fields are only set by the message_factory module, and not by the 795 - generated proto code. 938 + Note that :attr:`enum_types_by_name`, :attr:`extensions_by_name`, and 939 + :attr:`dependencies` fields are only set by the 940 + :py:mod:`google.protobuf.message_factory` module, and not by the generated 941 + proto code. 796 942 797 - name: name of file, relative to root of source tree. 798 - package: name of the package 799 - syntax: string indicating syntax of the file (can be "proto2" or "proto3") 800 - serialized_pb: (str) Byte string of serialized 801 - descriptor_pb2.FileDescriptorProto. 802 - dependencies: List of other FileDescriptors this FileDescriptor depends on. 803 - public_dependencies: A list of FileDescriptors, subset of the dependencies 804 - above, which were declared as "public". 805 - message_types_by_name: Dict of message names of their descriptors. 806 - enum_types_by_name: Dict of enum names and their descriptors. 807 - extensions_by_name: Dict of extension names and their descriptors. 808 - services_by_name: Dict of services names and their descriptors. 809 - pool: the DescriptorPool this descriptor belongs to. When not passed to the 810 - constructor, the global default pool is used. 943 + Attributes: 944 + name (str): Name of file, relative to root of source tree. 945 + package (str): Name of the package 946 + syntax (str): string indicating syntax of the file (can be "proto2" or 947 + "proto3") 948 + serialized_pb (bytes): Byte string of serialized 949 + :class:`descriptor_pb2.FileDescriptorProto`. 950 + dependencies (list[FileDescriptor]): List of other :class:`FileDescriptor` 951 + objects this :class:`FileDescriptor` depends on. 952 + public_dependencies (list[FileDescriptor]): A subset of 953 + :attr:`dependencies`, which were declared as "public". 954 + message_types_by_name (dict(str, Descriptor)): Mapping from message names 955 + to their :class:`Desctiptor`. 956 + enum_types_by_name (dict(str, EnumDescriptor)): Mapping from enum names to 957 + their :class:`EnumDescriptor`. 958 + extensions_by_name (dict(str, FieldDescriptor)): Mapping from extension 959 + names declared at file scope to their :class:`FieldDescriptor`. 960 + services_by_name (dict(str, ServiceDescriptor)): Mapping from services' 961 + names to their :class:`ServiceDescriptor`. 962 + pool (DescriptorPool): The pool this descriptor belongs to. When not 963 + passed to the constructor, the global default pool is used. 811 964 """ 812 965 813 966 if _USE_C_DESCRIPTORS: 814 967 _C_DESCRIPTOR_CLASS = _message.FileDescriptor 815 968 816 - def __new__(cls, name, package, options=None, serialized_pb=None, 969 + def __new__(cls, name, package, options=None, 970 + serialized_options=None, serialized_pb=None, 817 971 dependencies=None, public_dependencies=None, 818 - syntax=None, pool=None): 972 + syntax=None, pool=None, create_key=None): 819 973 # FileDescriptor() is called from various places, not only from generated 820 974 # files, to register dynamic proto files and messages. 821 - if serialized_pb: 822 - # TODO(amauryfa): use the pool passed as argument. This will work only 823 - # for C++-implemented DescriptorPools. 975 + # pylint: disable=g-explicit-bool-comparison 976 + if serialized_pb == b'': 977 + # Cpp generated code must be linked in if serialized_pb is '' 978 + try: 979 + return _message.default_pool.FindFileByName(name) 980 + except KeyError: 981 + raise RuntimeError('Please link in cpp generated lib for %s' % (name)) 982 + elif serialized_pb: 824 983 return _message.default_pool.AddSerializedFile(serialized_pb) 825 984 else: 826 985 return super(FileDescriptor, cls).__new__(cls) 827 986 828 - def __init__(self, name, package, options=None, serialized_pb=None, 987 + def __init__(self, name, package, options=None, 988 + serialized_options=None, serialized_pb=None, 829 989 dependencies=None, public_dependencies=None, 830 - syntax=None, pool=None): 990 + syntax=None, pool=None, create_key=None): 831 991 """Constructor.""" 832 - super(FileDescriptor, self).__init__(options, 'FileOptions') 992 + if create_key is not _internal_create_key: 993 + _Deprecated('FileDescriptor') 994 + 995 + super(FileDescriptor, self).__init__( 996 + options, serialized_options, 'FileOptions') 833 997 834 998 if pool is None: 835 999 from google.protobuf import descriptor_pool skipped 11 lines 847 1011 self.dependencies = (dependencies or []) 848 1012 self.public_dependencies = (public_dependencies or []) 849 1013 850 - if (api_implementation.Type() == 'cpp' and 851 - self.serialized_pb is not None): 852 - _message.default_pool.AddSerializedFile(self.serialized_pb) 853 - 854 1014 def CopyToProto(self, proto): 855 1015 """Copies this to a descriptor_pb2.FileDescriptorProto. 856 1016 skipped 90 lines 947 1107 # imported ones. We need to specify a file name so the descriptor pool 948 1108 # accepts our FileDescriptorProto, but it is not important what that file 949 1109 # name is actually set to. 950 - proto_name = str(uuid.uuid4()) 1110 + proto_name = binascii.hexlify(os.urandom(16)).decode('ascii') 951 1111 952 1112 if package: 953 1113 file_descriptor_proto.name = os.path.join(package.replace('.', '/'), skipped 16 lines 970 1130 for enum_proto in desc_proto.enum_type: 971 1131 full_name = '.'.join(full_message_name + [enum_proto.name]) 972 1132 enum_desc = EnumDescriptor( 973 - enum_proto.name, full_name, None, [ 974 - EnumValueDescriptor(enum_val.name, ii, enum_val.number) 975 - for ii, enum_val in enumerate(enum_proto.value)]) 1133 + enum_proto.name, full_name, None, [ 1134 + EnumValueDescriptor(enum_val.name, ii, enum_val.number, 1135 + create_key=_internal_create_key) 1136 + for ii, enum_val in enumerate(enum_proto.value)], 1137 + create_key=_internal_create_key) 976 1138 enum_types[full_name] = enum_desc 977 1139 978 1140 # Create Descriptors for nested types skipped 32 lines 1011 1173 FieldDescriptor.ProtoTypeToCppProtoType(field_proto.type), 1012 1174 field_proto.label, None, nested_desc, enum_desc, None, False, None, 1013 1175 options=_OptionsOrNone(field_proto), has_default_value=False, 1014 - json_name=json_name) 1176 + json_name=json_name, create_key=_internal_create_key) 1015 1177 fields.append(field) 1016 1178 1017 1179 desc_name = '.'.join(full_message_name) 1018 1180 return Descriptor(desc_proto.name, desc_name, None, None, fields, 1019 1181 list(nested_types.values()), list(enum_types.values()), [], 1020 - options=_OptionsOrNone(desc_proto)) 1182 + options=_OptionsOrNone(desc_proto), 1183 + create_key=_internal_create_key) 1021 1184 -
skipped 31 lines 32 32 33 33 __author__ = '[email protected] (Matt Toia)' 34 34 35 + import warnings 36 + 35 37 36 38 class Error(Exception): 37 39 pass skipped 16 lines 54 56 Args: 55 57 file_desc_proto: The FileDescriptorProto to add. 56 58 Raises: 57 - DescriptorDatabaseException: if an attempt is made to add a proto 58 - with the same name but different definition than an exisiting 59 - proto in the database. 59 + DescriptorDatabaseConflictingDefinitionError: if an attempt is made to 60 + add a proto with the same name but different definition than an 61 + existing proto in the database. 60 62 """ 61 63 proto_name = file_desc_proto.name 62 64 if proto_name not in self._file_desc_protos_by_file: skipped 1 lines 64 66 elif self._file_desc_protos_by_file[proto_name] != file_desc_proto: 65 67 raise DescriptorDatabaseConflictingDefinitionError( 66 68 '%s already added, but with different descriptor.' % proto_name) 69 + else: 70 + return 67 71 68 - # Add the top-level Message, Enum and Extension descriptors to the index. 72 + # Add all the top-level descriptors to the index. 69 73 package = file_desc_proto.package 70 74 for message in file_desc_proto.message_type: 71 - self._file_desc_protos_by_symbol.update( 72 - (name, file_desc_proto) for name in _ExtractSymbols(message, package)) 75 + for name in _ExtractSymbols(message, package): 76 + self._AddSymbol(name, file_desc_proto) 73 77 for enum in file_desc_proto.enum_type: 74 - self._file_desc_protos_by_symbol[ 75 - '.'.join((package, enum.name))] = file_desc_proto 78 + self._AddSymbol(('.'.join((package, enum.name))), file_desc_proto) 79 + for enum_value in enum.value: 80 + self._file_desc_protos_by_symbol[ 81 + '.'.join((package, enum_value.name))] = file_desc_proto 76 82 for extension in file_desc_proto.extension: 77 - self._file_desc_protos_by_symbol[ 78 - '.'.join((package, extension.name))] = file_desc_proto 83 + self._AddSymbol(('.'.join((package, extension.name))), file_desc_proto) 84 + for service in file_desc_proto.service: 85 + self._AddSymbol(('.'.join((package, service.name))), file_desc_proto) 79 86 80 87 def FindFileByName(self, name): 81 88 """Finds the file descriptor proto by file name. skipped 22 lines 104 111 105 112 'some.package.name.Message' 106 113 'some.package.name.Message.NestedEnum' 114 + 'some.package.name.Message.some_field' 107 115 108 116 The file descriptor proto containing the specified symbol must be added to 109 117 this database using the Add method or else an error will be raised. skipped 7 lines 117 125 Raises: 118 126 KeyError if no file contains the specified symbol. 119 127 """ 128 + try: 129 + return self._file_desc_protos_by_symbol[symbol] 130 + except KeyError: 131 + # Fields, enum values, and nested extensions are not in 132 + # _file_desc_protos_by_symbol. Try to find the top level 133 + # descriptor. Non-existent nested symbol under a valid top level 134 + # descriptor can also be found. The behavior is the same with 135 + # protobuf C++. 136 + top_level, _, _ = symbol.rpartition('.') 137 + try: 138 + return self._file_desc_protos_by_symbol[top_level] 139 + except KeyError: 140 + # Raise the original symbol as a KeyError for better diagnostics. 141 + raise KeyError(symbol) 120 142 121 - return self._file_desc_protos_by_symbol[symbol] 143 + def FindFileContainingExtension(self, extendee_name, extension_number): 144 + # TODO(jieluo): implement this API. 145 + return None 146 + 147 + def FindAllExtensionNumbers(self, extendee_name): 148 + # TODO(jieluo): implement this API. 149 + return [] 150 + 151 + def _AddSymbol(self, name, file_desc_proto): 152 + if name in self._file_desc_protos_by_symbol: 153 + warn_msg = ('Conflict register for file "' + file_desc_proto.name + 154 + '": ' + name + 155 + ' is already defined in file "' + 156 + self._file_desc_protos_by_symbol[name].name + '"') 157 + warnings.warn(warn_msg, RuntimeWarning) 158 + self._file_desc_protos_by_symbol[name] = file_desc_proto 122 159 123 160 124 161 def _ExtractSymbols(desc_proto, package): skipped 6 lines 131 168 Yields: 132 169 The fully qualified name found in the descriptor. 133 170 """ 134 - 135 - message_name = '.'.join((package, desc_proto.name)) 171 + message_name = package + '.' + desc_proto.name if package else desc_proto.name 136 172 yield message_name 137 173 for nested_type in desc_proto.nested_type: 138 174 for symbol in _ExtractSymbols(nested_type, message_name): skipped 4 lines -
-
skipped 37 lines 38 38 the protocol buffer compiler tool. This should only be used when the type of 39 39 protocol buffers used in an application or library cannot be predetermined. 40 40 41 - Below is a straightforward example on how to use this class: 41 + Below is a straightforward example on how to use this class:: 42 42 43 43 pool = DescriptorPool() 44 44 file_descriptor_protos = [ ... ] skipped 13 lines 58 58 __author__ = '[email protected] (Matt Toia)' 59 59 60 60 import collections 61 + import warnings 61 62 62 63 from google.protobuf import descriptor 63 64 from google.protobuf import descriptor_database skipped 3 lines 67 68 _USE_C_DESCRIPTORS = descriptor._USE_C_DESCRIPTORS # pylint: disable=protected-access 68 69 69 70 71 + def _Deprecated(func): 72 + """Mark functions as deprecated.""" 73 + 74 + def NewFunc(*args, **kwargs): 75 + warnings.warn( 76 + 'Call to deprecated function %s(). Note: Do add unlinked descriptors ' 77 + 'to descriptor_pool is wrong. Use Add() or AddSerializedFile() ' 78 + 'instead.' % func.__name__, 79 + category=DeprecationWarning) 80 + return func(*args, **kwargs) 81 + NewFunc.__name__ = func.__name__ 82 + NewFunc.__doc__ = func.__doc__ 83 + NewFunc.__dict__.update(func.__dict__) 84 + return NewFunc 85 + 86 + 70 87 def _NormalizeFullyQualifiedName(name): 71 88 """Remove leading period from fully-qualified type name. 72 89 skipped 1 lines 74 91 generated with a leading period. This function removes that prefix. 75 92 76 93 Args: 77 - name: A str, the fully-qualified symbol name. 94 + name (str): The fully-qualified symbol name. 78 95 79 96 Returns: 80 - A str, the normalized fully-qualified symbol name. 97 + str: The normalized fully-qualified symbol name. 81 98 """ 82 99 return name.lstrip('.') 83 100 skipped 40 lines 124 141 self._descriptor_db = descriptor_db 125 142 self._descriptors = {} 126 143 self._enum_descriptors = {} 144 + self._service_descriptors = {} 127 145 self._file_descriptors = {} 128 146 self._toplevel_extensions = {} 147 + # TODO(jieluo): Remove _file_desc_by_toplevel_extension after 148 + # maybe year 2020 for compatibility issue (with 3.4.1 only). 149 + self._file_desc_by_toplevel_extension = {} 150 + self._top_enum_values = {} 129 151 # We store extensions in two two-level mappings: The first key is the 130 152 # descriptor of the message being extended, the second key is the extension 131 153 # full name or its tag number. 132 154 self._extensions_by_name = collections.defaultdict(dict) 133 155 self._extensions_by_number = collections.defaultdict(dict) 134 156 157 + def _CheckConflictRegister(self, desc, desc_name, file_name): 158 + """Check if the descriptor name conflicts with another of the same name. 159 + 160 + Args: 161 + desc: Descriptor of a message, enum, service, extension or enum value. 162 + desc_name (str): the full name of desc. 163 + file_name (str): The file name of descriptor. 164 + """ 165 + for register, descriptor_type in [ 166 + (self._descriptors, descriptor.Descriptor), 167 + (self._enum_descriptors, descriptor.EnumDescriptor), 168 + (self._service_descriptors, descriptor.ServiceDescriptor), 169 + (self._toplevel_extensions, descriptor.FieldDescriptor), 170 + (self._top_enum_values, descriptor.EnumValueDescriptor)]: 171 + if desc_name in register: 172 + old_desc = register[desc_name] 173 + if isinstance(old_desc, descriptor.EnumValueDescriptor): 174 + old_file = old_desc.type.file.name 175 + else: 176 + old_file = old_desc.file.name 177 + 178 + if not isinstance(desc, descriptor_type) or ( 179 + old_file != file_name): 180 + error_msg = ('Conflict register for file "' + file_name + 181 + '": ' + desc_name + 182 + ' is already defined in file "' + 183 + old_file + '". Please fix the conflict by adding ' 184 + 'package name on the proto file, or use different ' 185 + 'name for the duplication.') 186 + if isinstance(desc, descriptor.EnumValueDescriptor): 187 + error_msg += ('\nNote: enum values appear as ' 188 + 'siblings of the enum type instead of ' 189 + 'children of it.') 190 + 191 + raise TypeError(error_msg) 192 + 193 + return 194 + 135 195 def Add(self, file_desc_proto): 136 196 """Adds the FileDescriptorProto and its types to this pool. 137 197 138 198 Args: 139 - file_desc_proto: The FileDescriptorProto to add. 199 + file_desc_proto (FileDescriptorProto): The file descriptor to add. 140 200 """ 141 201 142 202 self._internal_db.Add(file_desc_proto) skipped 2 lines 145 205 """Adds the FileDescriptorProto and its types to this pool. 146 206 147 207 Args: 148 - serialized_file_desc_proto: A bytes string, serialization of the 149 - FileDescriptorProto to add. 208 + serialized_file_desc_proto (bytes): A bytes string, serialization of the 209 + :class:`FileDescriptorProto` to add. 150 210 """ 151 211 152 212 # pylint: disable=g-import-not-at-top skipped 2 lines 155 215 serialized_file_desc_proto) 156 216 self.Add(file_desc_proto) 157 217 218 + # Add Descriptor to descriptor pool is dreprecated. Please use Add() 219 + # or AddSerializedFile() to add a FileDescriptorProto instead. 220 + @_Deprecated 158 221 def AddDescriptor(self, desc): 222 + self._AddDescriptor(desc) 223 + 224 + # Never call this method. It is for internal usage only. 225 + def _AddDescriptor(self, desc): 159 226 """Adds a Descriptor to the pool, non-recursively. 160 227 161 228 If the Descriptor contains nested messages or enums, the caller must skipped 5 lines 167 234 """ 168 235 if not isinstance(desc, descriptor.Descriptor): 169 236 raise TypeError('Expected instance of descriptor.Descriptor.') 237 + 238 + self._CheckConflictRegister(desc, desc.full_name, desc.file.name) 170 239 171 240 self._descriptors[desc.full_name] = desc 172 - self.AddFileDescriptor(desc.file) 241 + self._AddFileDescriptor(desc.file) 173 242 243 + # Add EnumDescriptor to descriptor pool is dreprecated. Please use Add() 244 + # or AddSerializedFile() to add a FileDescriptorProto instead. 245 + @_Deprecated 174 246 def AddEnumDescriptor(self, enum_desc): 247 + self._AddEnumDescriptor(enum_desc) 248 + 249 + # Never call this method. It is for internal usage only. 250 + def _AddEnumDescriptor(self, enum_desc): 175 251 """Adds an EnumDescriptor to the pool. 176 252 177 - This method also registers the FileDescriptor associated with the message. 253 + This method also registers the FileDescriptor associated with the enum. 178 254 179 255 Args: 180 256 enum_desc: An EnumDescriptor. skipped 2 lines 183 259 if not isinstance(enum_desc, descriptor.EnumDescriptor): 184 260 raise TypeError('Expected instance of descriptor.EnumDescriptor.') 185 261 262 + file_name = enum_desc.file.name 263 + self._CheckConflictRegister(enum_desc, enum_desc.full_name, file_name) 186 264 self._enum_descriptors[enum_desc.full_name] = enum_desc 187 - self.AddFileDescriptor(enum_desc.file) 188 265 266 + # Top enum values need to be indexed. 267 + # Count the number of dots to see whether the enum is toplevel or nested 268 + # in a message. We cannot use enum_desc.containing_type at this stage. 269 + if enum_desc.file.package: 270 + top_level = (enum_desc.full_name.count('.') 271 + - enum_desc.file.package.count('.') == 1) 272 + else: 273 + top_level = enum_desc.full_name.count('.') == 0 274 + if top_level: 275 + file_name = enum_desc.file.name 276 + package = enum_desc.file.package 277 + for enum_value in enum_desc.values: 278 + full_name = _NormalizeFullyQualifiedName( 279 + '.'.join((package, enum_value.name))) 280 + self._CheckConflictRegister(enum_value, full_name, file_name) 281 + self._top_enum_values[full_name] = enum_value 282 + self._AddFileDescriptor(enum_desc.file) 283 + 284 + # Add ServiceDescriptor to descriptor pool is dreprecated. Please use Add() 285 + # or AddSerializedFile() to add a FileDescriptorProto instead. 286 + @_Deprecated 287 + def AddServiceDescriptor(self, service_desc): 288 + self._AddServiceDescriptor(service_desc) 289 + 290 + # Never call this method. It is for internal usage only. 291 + def _AddServiceDescriptor(self, service_desc): 292 + """Adds a ServiceDescriptor to the pool. 293 + 294 + Args: 295 + service_desc: A ServiceDescriptor. 296 + """ 297 + 298 + if not isinstance(service_desc, descriptor.ServiceDescriptor): 299 + raise TypeError('Expected instance of descriptor.ServiceDescriptor.') 300 + 301 + self._CheckConflictRegister(service_desc, service_desc.full_name, 302 + service_desc.file.name) 303 + self._service_descriptors[service_desc.full_name] = service_desc 304 + 305 + # Add ExtensionDescriptor to descriptor pool is dreprecated. Please use Add() 306 + # or AddSerializedFile() to add a FileDescriptorProto instead. 307 + @_Deprecated 189 308 def AddExtensionDescriptor(self, extension): 309 + self._AddExtensionDescriptor(extension) 310 + 311 + # Never call this method. It is for internal usage only. 312 + def _AddExtensionDescriptor(self, extension): 190 313 """Adds a FieldDescriptor describing an extension to the pool. 191 314 192 315 Args: skipped 35 lines 228 351 self._extensions_by_name[extension.containing_type][ 229 352 extension.message_type.full_name] = extension 230 353 354 + @_Deprecated 231 355 def AddFileDescriptor(self, file_desc): 356 + self._InternalAddFileDescriptor(file_desc) 357 + 358 + # Never call this method. It is for internal usage only. 359 + def _InternalAddFileDescriptor(self, file_desc): 360 + """Adds a FileDescriptor to the pool, non-recursively. 361 + 362 + If the FileDescriptor contains messages or enums, the caller must explicitly 363 + register them. 364 + 365 + Args: 366 + file_desc: A FileDescriptor. 367 + """ 368 + 369 + self._AddFileDescriptor(file_desc) 370 + # TODO(jieluo): This is a temporary solution for FieldDescriptor.file. 371 + # FieldDescriptor.file is added in code gen. Remove this solution after 372 + # maybe 2020 for compatibility reason (with 3.4.1 only). 373 + for extension in file_desc.extensions_by_name.values(): 374 + self._file_desc_by_toplevel_extension[ 375 + extension.full_name] = file_desc 376 + 377 + def _AddFileDescriptor(self, file_desc): 232 378 """Adds a FileDescriptor to the pool, non-recursively. 233 379 234 380 If the FileDescriptor contains messages or enums, the caller must explicitly skipped 11 lines 246 392 """Gets a FileDescriptor by file name. 247 393 248 394 Args: 249 - file_name: The path to the file to get a descriptor for. 395 + file_name (str): The path to the file to get a descriptor for. 250 396 251 397 Returns: 252 - A FileDescriptor for the named file. 398 + FileDescriptor: The descriptor for the named file. 253 399 254 400 Raises: 255 - KeyError: if the file can not be found in the pool. 401 + KeyError: if the file cannot be found in the pool. 256 402 """ 257 403 258 404 try: skipped 16 lines 275 421 """Gets the FileDescriptor for the file containing the specified symbol. 276 422 277 423 Args: 278 - symbol: The name of the symbol to search for. 424 + symbol (str): The name of the symbol to search for. 279 425 280 426 Returns: 281 - A FileDescriptor that contains the specified symbol. 427 + FileDescriptor: Descriptor for the file that contains the specified 428 + symbol. 282 429 283 430 Raises: 284 - KeyError: if the file can not be found in the pool. 431 + KeyError: if the file cannot be found in the pool. 285 432 """ 286 433 287 434 symbol = _NormalizeFullyQualifiedName(symbol) 288 435 try: 436 + return self._InternalFindFileContainingSymbol(symbol) 437 + except KeyError: 438 + pass 439 + 440 + try: 441 + # Try fallback database. Build and find again if possible. 442 + self._FindFileContainingSymbolInDb(symbol) 443 + return self._InternalFindFileContainingSymbol(symbol) 444 + except KeyError: 445 + raise KeyError('Cannot find a file containing %s' % symbol) 446 + 447 + def _InternalFindFileContainingSymbol(self, symbol): 448 + """Gets the already built FileDescriptor containing the specified symbol. 449 + 450 + Args: 451 + symbol (str): The name of the symbol to search for. 452 + 453 + Returns: 454 + FileDescriptor: Descriptor for the file that contains the specified 455 + symbol. 456 + 457 + Raises: 458 + KeyError: if the file cannot be found in the pool. 459 + """ 460 + try: 289 461 return self._descriptors[symbol].file 290 462 except KeyError: 291 463 pass skipped 4 lines 296 468 pass 297 469 298 470 try: 299 - file_proto = self._internal_db.FindFileContainingSymbol(symbol) 300 - except KeyError as error: 301 - if self._descriptor_db: 302 - file_proto = self._descriptor_db.FindFileContainingSymbol(symbol) 303 - else: 304 - raise error 305 - if not file_proto: 471 + return self._service_descriptors[symbol].file 472 + except KeyError: 473 + pass 474 + 475 + try: 476 + return self._top_enum_values[symbol].type.file 477 + except KeyError: 478 + pass 479 + 480 + try: 481 + return self._file_desc_by_toplevel_extension[symbol] 482 + except KeyError: 483 + pass 484 + 485 + # Try fields, enum values and nested extensions inside a message. 486 + top_name, _, sub_name = symbol.rpartition('.') 487 + try: 488 + message = self.FindMessageTypeByName(top_name) 489 + assert (sub_name in message.extensions_by_name or 490 + sub_name in message.fields_by_name or 491 + sub_name in message.enum_values_by_name) 492 + return message.file 493 + except (KeyError, AssertionError): 306 494 raise KeyError('Cannot find a file containing %s' % symbol) 307 - return self._ConvertFileProtoToFileDescriptor(file_proto) 308 495 309 496 def FindMessageTypeByName(self, full_name): 310 497 """Loads the named descriptor from the pool. 311 498 312 499 Args: 313 - full_name: The full name of the descriptor to load. 500 + full_name (str): The full name of the descriptor to load. 314 501 315 502 Returns: 316 - The descriptor for the named type. 503 + Descriptor: The descriptor for the named type. 504 + 505 + Raises: 506 + KeyError: if the message cannot be found in the pool. 317 507 """ 318 508 319 509 full_name = _NormalizeFullyQualifiedName(full_name) 320 510 if full_name not in self._descriptors: 321 - self.FindFileContainingSymbol(full_name) 511 + self._FindFileContainingSymbolInDb(full_name) 322 512 return self._descriptors[full_name] 323 513 324 514 def FindEnumTypeByName(self, full_name): 325 515 """Loads the named enum descriptor from the pool. 326 516 327 517 Args: 328 - full_name: The full name of the enum descriptor to load. 518 + full_name (str): The full name of the enum descriptor to load. 329 519 330 520 Returns: 331 - The enum descriptor for the named type. 521 + EnumDescriptor: The enum descriptor for the named type. 522 + 523 + Raises: 524 + KeyError: if the enum cannot be found in the pool. 332 525 """ 333 526 334 527 full_name = _NormalizeFullyQualifiedName(full_name) 335 528 if full_name not in self._enum_descriptors: 336 - self.FindFileContainingSymbol(full_name) 529 + self._FindFileContainingSymbolInDb(full_name) 337 530 return self._enum_descriptors[full_name] 338 531 339 532 def FindFieldByName(self, full_name): 340 533 """Loads the named field descriptor from the pool. 341 534 342 535 Args: 343 - full_name: The full name of the field descriptor to load. 536 + full_name (str): The full name of the field descriptor to load. 344 537 345 538 Returns: 346 - The field descriptor for the named field. 539 + FieldDescriptor: The field descriptor for the named field. 540 + 541 + Raises: 542 + KeyError: if the field cannot be found in the pool. 347 543 """ 348 544 full_name = _NormalizeFullyQualifiedName(full_name) 349 545 message_name, _, field_name = full_name.rpartition('.') 350 546 message_descriptor = self.FindMessageTypeByName(message_name) 351 547 return message_descriptor.fields_by_name[field_name] 352 548 549 + def FindOneofByName(self, full_name): 550 + """Loads the named oneof descriptor from the pool. 551 + 552 + Args: 553 + full_name (str): The full name of the oneof descriptor to load. 554 + 555 + Returns: 556 + OneofDescriptor: The oneof descriptor for the named oneof. 557 + 558 + Raises: 559 + KeyError: if the oneof cannot be found in the pool. 560 + """ 561 + full_name = _NormalizeFullyQualifiedName(full_name) 562 + message_name, _, oneof_name = full_name.rpartition('.') 563 + message_descriptor = self.FindMessageTypeByName(message_name) 564 + return message_descriptor.oneofs_by_name[oneof_name] 565 + 353 566 def FindExtensionByName(self, full_name): 354 567 """Loads the named extension descriptor from the pool. 355 568 356 569 Args: 357 - full_name: The full name of the extension descriptor to load. 570 + full_name (str): The full name of the extension descriptor to load. 358 571 359 572 Returns: 360 - A FieldDescriptor, describing the named extension. 573 + FieldDescriptor: The field descriptor for the named extension. 574 + 575 + Raises: 576 + KeyError: if the extension cannot be found in the pool. 361 577 """ 362 578 full_name = _NormalizeFullyQualifiedName(full_name) 363 579 try: skipped 10 lines 374 590 scope = self.FindMessageTypeByName(message_name) 375 591 except KeyError: 376 592 # Some extensions are defined at file scope. 377 - scope = self.FindFileContainingSymbol(full_name) 593 + scope = self._FindFileContainingSymbolInDb(full_name) 378 594 return scope.extensions_by_name[extension_name] 379 595 380 596 def FindExtensionByNumber(self, message_descriptor, number): 381 597 """Gets the extension of the specified message with the specified number. 382 598 383 - Extensions have to be registered to this pool by calling 384 - AddExtensionDescriptor. 599 + Extensions have to be registered to this pool by calling :func:`Add` or 600 + :func:`AddExtensionDescriptor`. 385 601 386 602 Args: 387 - message_descriptor: descriptor of the extended message. 388 - number: integer, number of the extension field. 603 + message_descriptor (Descriptor): descriptor of the extended message. 604 + number (int): Number of the extension field. 389 605 390 606 Returns: 391 - A FieldDescriptor describing the extension. 607 + FieldDescriptor: The descriptor for the extension. 392 608 393 - Raise: 609 + Raises: 394 610 KeyError: when no extension with the given number is known for the 395 611 specified message. 396 612 """ 397 - return self._extensions_by_number[message_descriptor][number] 613 + try: 614 + return self._extensions_by_number[message_descriptor][number] 615 + except KeyError: 616 + self._TryLoadExtensionFromDB(message_descriptor, number) 617 + return self._extensions_by_number[message_descriptor][number] 398 618 399 619 def FindAllExtensions(self, message_descriptor): 400 - """Gets all the known extension of a given message. 620 + """Gets all the known extensions of a given message. 621 + 622 + Extensions have to be registered to this pool by build related 623 + :func:`Add` or :func:`AddExtensionDescriptor`. 624 + 625 + Args: 626 + message_descriptor (Descriptor): Descriptor of the extended message. 627 + 628 + Returns: 629 + list[FieldDescriptor]: Field descriptors describing the extensions. 630 + """ 631 + # Fallback to descriptor db if FindAllExtensionNumbers is provided. 632 + if self._descriptor_db and hasattr( 633 + self._descriptor_db, 'FindAllExtensionNumbers'): 634 + full_name = message_descriptor.full_name 635 + all_numbers = self._descriptor_db.FindAllExtensionNumbers(full_name) 636 + for number in all_numbers: 637 + if number in self._extensions_by_number[message_descriptor]: 638 + continue 639 + self._TryLoadExtensionFromDB(message_descriptor, number) 640 + 641 + return list(self._extensions_by_number[message_descriptor].values()) 401 642 402 - Extensions have to be registered to this pool by calling 403 - AddExtensionDescriptor. 643 + def _TryLoadExtensionFromDB(self, message_descriptor, number): 644 + """Try to Load extensions from descriptor db. 404 645 405 646 Args: 406 647 message_descriptor: descriptor of the extended message. 648 + number: the extension number that needs to be loaded. 649 + """ 650 + if not self._descriptor_db: 651 + return 652 + # Only supported when FindFileContainingExtension is provided. 653 + if not hasattr( 654 + self._descriptor_db, 'FindFileContainingExtension'): 655 + return 656 + 657 + full_name = message_descriptor.full_name 658 + file_proto = self._descriptor_db.FindFileContainingExtension( 659 + full_name, number) 660 + 661 + if file_proto is None: 662 + return 663 + 664 + try: 665 + self._ConvertFileProtoToFileDescriptor(file_proto) 666 + except: 667 + warn_msg = ('Unable to load proto file %s for extension number %d.' % 668 + (file_proto.name, number)) 669 + warnings.warn(warn_msg, RuntimeWarning) 670 + 671 + def FindServiceByName(self, full_name): 672 + """Loads the named service descriptor from the pool. 673 + 674 + Args: 675 + full_name (str): The full name of the service descriptor to load. 407 676 408 677 Returns: 409 - A list of FieldDescriptor describing the extensions. 678 + ServiceDescriptor: The service descriptor for the named service. 679 + 680 + Raises: 681 + KeyError: if the service cannot be found in the pool. 410 682 """ 411 - return list(self._extensions_by_number[message_descriptor].values()) 683 + full_name = _NormalizeFullyQualifiedName(full_name) 684 + if full_name not in self._service_descriptors: 685 + self._FindFileContainingSymbolInDb(full_name) 686 + return self._service_descriptors[full_name] 687 + 688 + def FindMethodByName(self, full_name): 689 + """Loads the named service method descriptor from the pool. 690 + 691 + Args: 692 + full_name (str): The full name of the method descriptor to load. 693 + 694 + Returns: 695 + MethodDescriptor: The method descriptor for the service method. 696 + 697 + Raises: 698 + KeyError: if the method cannot be found in the pool. 699 + """ 700 + full_name = _NormalizeFullyQualifiedName(full_name) 701 + service_name, _, method_name = full_name.rpartition('.') 702 + service_descriptor = self.FindServiceByName(service_name) 703 + return service_descriptor.methods_by_name[method_name] 704 + 705 + def _FindFileContainingSymbolInDb(self, symbol): 706 + """Finds the file in descriptor DB containing the specified symbol. 707 + 708 + Args: 709 + symbol (str): The name of the symbol to search for. 710 + 711 + Returns: 712 + FileDescriptor: The file that contains the specified symbol. 713 + 714 + Raises: 715 + KeyError: if the file cannot be found in the descriptor database. 716 + """ 717 + try: 718 + file_proto = self._internal_db.FindFileContainingSymbol(symbol) 719 + except KeyError as error: 720 + if self._descriptor_db: 721 + file_proto = self._descriptor_db.FindFileContainingSymbol(symbol) 722 + else: 723 + raise error 724 + if not file_proto: 725 + raise KeyError('Cannot find a file containing %s' % symbol) 726 + return self._ConvertFileProtoToFileDescriptor(file_proto) 412 727 413 728 def _ConvertFileProtoToFileDescriptor(self, file_proto): 414 729 """Creates a FileDescriptor from a proto or returns a cached copy. skipped 7 lines 422 737 Returns: 423 738 A FileDescriptor matching the passed in proto. 424 739 """ 425 - 426 740 if file_proto.name not in self._file_descriptors: 427 741 built_deps = list(self._GetDeps(file_proto.dependency)) 428 742 direct_deps = [self.FindFileByName(n) for n in file_proto.dependency] skipped 7 lines 436 750 options=_OptionsOrNone(file_proto), 437 751 serialized_pb=file_proto.SerializeToString(), 438 752 dependencies=direct_deps, 439 - public_dependencies=public_deps) 753 + public_dependencies=public_deps, 754 + # pylint: disable=protected-access 755 + create_key=descriptor._internal_create_key) 440 756 scope = {} 441 757 442 758 # This loop extracts all the message and enum types from all the skipped 16 lines 459 775 for enum_type in file_proto.enum_type: 460 776 file_descriptor.enum_types_by_name[enum_type.name] = ( 461 777 self._ConvertEnumDescriptor(enum_type, file_proto.package, 462 - file_descriptor, None, scope)) 778 + file_descriptor, None, scope, True)) 463 779 464 780 for index, extension_proto in enumerate(file_proto.extension): 465 781 extension_desc = self._MakeFieldDescriptor( 466 - extension_proto, file_proto.package, index, is_extension=True) 782 + extension_proto, file_proto.package, index, file_descriptor, 783 + is_extension=True) 467 784 extension_desc.containing_type = self._GetTypeFromScope( 468 785 file_descriptor.package, extension_proto.extendee, scope) 469 786 self._SetFieldType(extension_proto, extension_desc, 470 787 file_descriptor.package, scope) 471 788 file_descriptor.extensions_by_name[extension_desc.name] = ( 472 789 extension_desc) 790 + self._file_desc_by_toplevel_extension[extension_desc.full_name] = ( 791 + file_descriptor) 473 792 474 793 for desc_proto in file_proto.message_type: 475 794 self._SetAllFieldTypes(file_proto.package, desc_proto, scope) skipped 16 lines 492 811 self.Add(file_proto) 493 812 self._file_descriptors[file_proto.name] = file_descriptor 494 813 495 - return self._file_descriptors[file_proto.name] 814 + # Add extensions to the pool 815 + file_desc = self._file_descriptors[file_proto.name] 816 + for extension in file_desc.extensions_by_name.values(): 817 + self._AddExtensionDescriptor(extension) 818 + for message_type in file_desc.message_types_by_name.values(): 819 + for extension in message_type.extensions: 820 + self._AddExtensionDescriptor(extension) 821 + 822 + return file_desc 496 823 497 824 def _ConvertMessageDescriptor(self, desc_proto, package=None, file_desc=None, 498 825 scope=None, syntax=None): skipped 28 lines 527 854 nested, desc_name, file_desc, scope, syntax) 528 855 for nested in desc_proto.nested_type] 529 856 enums = [ 530 - self._ConvertEnumDescriptor(enum, desc_name, file_desc, None, scope) 857 + self._ConvertEnumDescriptor(enum, desc_name, file_desc, None, 858 + scope, False) 531 859 for enum in desc_proto.enum_type] 532 - fields = [self._MakeFieldDescriptor(field, desc_name, index) 860 + fields = [self._MakeFieldDescriptor(field, desc_name, index, file_desc) 533 861 for index, field in enumerate(desc_proto.field)] 534 862 extensions = [ 535 - self._MakeFieldDescriptor(extension, desc_name, index, 863 + self._MakeFieldDescriptor(extension, desc_name, index, file_desc, 536 864 is_extension=True) 537 865 for index, extension in enumerate(desc_proto.extension)] 538 866 oneofs = [ 867 + # pylint: disable=g-complex-comprehension 539 868 descriptor.OneofDescriptor(desc.name, '.'.join((desc_name, desc.name)), 540 - index, None, [], desc.options) 869 + index, None, [], desc.options, 870 + # pylint: disable=protected-access 871 + create_key=descriptor._internal_create_key) 541 872 for index, desc in enumerate(desc_proto.oneof_decl)] 542 873 extension_ranges = [(r.start, r.end) for r in desc_proto.extension_range] 543 874 if extension_ranges: skipped 16 lines 560 891 file=file_desc, 561 892 serialized_start=None, 562 893 serialized_end=None, 563 - syntax=syntax) 894 + syntax=syntax, 895 + # pylint: disable=protected-access 896 + create_key=descriptor._internal_create_key) 564 897 for nested in desc.nested_types: 565 898 nested.containing_type = desc 566 899 for enum in desc.enum_types: skipped 5 lines 572 905 fields[field_index].containing_oneof = oneofs[oneof_index] 573 906 574 907 scope[_PrefixWithDot(desc_name)] = desc 908 + self._CheckConflictRegister(desc, desc.full_name, desc.file.name) 575 909 self._descriptors[desc_name] = desc 576 910 return desc 577 911 578 912 def _ConvertEnumDescriptor(self, enum_proto, package=None, file_desc=None, 579 - containing_type=None, scope=None): 913 + containing_type=None, scope=None, top_level=False): 580 914 """Make a protobuf EnumDescriptor given an EnumDescriptorProto protobuf. 581 915 582 916 Args: skipped 2 lines 585 919 file_desc: The file containing the enum descriptor. 586 920 containing_type: The type containing this enum. 587 921 scope: Scope containing available types. 922 + top_level: If True, the enum is a top level symbol. If False, the enum 923 + is defined inside a message. 588 924 589 925 Returns: 590 926 The added descriptor skipped 17 lines 608 944 file=file_desc, 609 945 values=values, 610 946 containing_type=containing_type, 611 - options=_OptionsOrNone(enum_proto)) 947 + options=_OptionsOrNone(enum_proto), 948 + # pylint: disable=protected-access 949 + create_key=descriptor._internal_create_key) 612 950 scope['.%s' % enum_name] = desc 951 + self._CheckConflictRegister(desc, desc.full_name, desc.file.name) 613 952 self._enum_descriptors[enum_name] = desc 953 + 954 + # Add top level enum values. 955 + if top_level: 956 + for value in values: 957 + full_name = _NormalizeFullyQualifiedName( 958 + '.'.join((package, value.name))) 959 + self._CheckConflictRegister(value, full_name, file_name) 960 + self._top_enum_values[full_name] = value 961 + 614 962 return desc 615 963 616 964 def _MakeFieldDescriptor(self, field_proto, message_name, index, 617 - is_extension=False): 965 + file_desc, is_extension=False): 618 966 """Creates a field descriptor from a FieldDescriptorProto. 619 967 620 968 For message and enum type fields, this method will do a look up skipped 6 lines 627 975 field_proto: The proto describing the field. 628 976 message_name: The name of the containing message. 629 977 index: Index of the field 978 + file_desc: The file containing the field descriptor. 630 979 is_extension: Indication that this field is for an extension. 631 980 632 981 Returns: skipped 20 lines 653 1002 default_value=None, 654 1003 is_extension=is_extension, 655 1004 extension_scope=None, 656 - options=_OptionsOrNone(field_proto)) 1005 + options=_OptionsOrNone(field_proto), 1006 + file=file_desc, 1007 + # pylint: disable=protected-access 1008 + create_key=descriptor._internal_create_key) 657 1009 658 1010 def _SetAllFieldTypes(self, package, desc_proto, scope): 659 1011 """Sets all the descriptor's fields's types. skipped 32 lines 692 1044 693 1045 Args: 694 1046 field_proto: Data about the field in proto format. 695 - field_desc: The descriptor to modiy. 1047 + field_desc: The descriptor to modify. 696 1048 package: The package the field's container is in. 697 1049 scope: Enclosing scope of available types. 698 1050 """ skipped 36 lines 735 1087 elif field_proto.type == descriptor.FieldDescriptor.TYPE_BYTES: 736 1088 field_desc.default_value = text_encoding.CUnescape( 737 1089 field_proto.default_value) 1090 + elif field_proto.type == descriptor.FieldDescriptor.TYPE_MESSAGE: 1091 + field_desc.default_value = None 738 1092 else: 739 1093 # All other types are of the "int" type. 740 1094 field_desc.default_value = int(field_proto.default_value) skipped 10 lines 751 1105 field_desc.default_value = field_desc.enum_type.values[0].number 752 1106 elif field_proto.type == descriptor.FieldDescriptor.TYPE_BYTES: 753 1107 field_desc.default_value = b'' 1108 + elif field_proto.type == descriptor.FieldDescriptor.TYPE_MESSAGE: 1109 + field_desc.default_value = None 754 1110 else: 755 1111 # All other types are of the "int" type. 756 1112 field_desc.default_value = 0 skipped 16 lines 773 1129 index=index, 774 1130 number=value_proto.number, 775 1131 options=_OptionsOrNone(value_proto), 776 - type=None) 1132 + type=None, 1133 + # pylint: disable=protected-access 1134 + create_key=descriptor._internal_create_key) 777 1135 778 1136 def _MakeServiceDescriptor(self, service_proto, service_index, scope, 779 1137 package, file_desc): skipped 18 lines 798 1156 methods = [self._MakeMethodDescriptor(method_proto, service_name, package, 799 1157 scope, index) 800 1158 for index, method_proto in enumerate(service_proto.method)] 801 - desc = descriptor.ServiceDescriptor(name=service_proto.name, 802 - full_name=service_name, 803 - index=service_index, 804 - methods=methods, 805 - options=_OptionsOrNone(service_proto), 806 - file=file_desc) 1159 + desc = descriptor.ServiceDescriptor( 1160 + name=service_proto.name, 1161 + full_name=service_name, 1162 + index=service_index, 1163 + methods=methods, 1164 + options=_OptionsOrNone(service_proto), 1165 + file=file_desc, 1166 + # pylint: disable=protected-access 1167 + create_key=descriptor._internal_create_key) 1168 + self._CheckConflictRegister(desc, desc.full_name, desc.file.name) 1169 + self._service_descriptors[service_name] = desc 807 1170 return desc 808 1171 809 1172 def _MakeMethodDescriptor(self, method_proto, service_name, package, scope, skipped 15 lines 825 1188 package, method_proto.input_type, scope) 826 1189 output_type = self._GetTypeFromScope( 827 1190 package, method_proto.output_type, scope) 828 - return descriptor.MethodDescriptor(name=method_proto.name, 829 - full_name=full_name, 830 - index=index, 831 - containing_service=None, 832 - input_type=input_type, 833 - output_type=output_type, 834 - options=_OptionsOrNone(method_proto)) 1191 + return descriptor.MethodDescriptor( 1192 + name=method_proto.name, 1193 + full_name=full_name, 1194 + index=index, 1195 + containing_service=None, 1196 + input_type=input_type, 1197 + output_type=output_type, 1198 + options=_OptionsOrNone(method_proto), 1199 + # pylint: disable=protected-access 1200 + create_key=descriptor._internal_create_key) 835 1201 836 1202 def _ExtractSymbols(self, descriptors): 837 1203 """Pulls out all the symbols from descriptor protos. skipped 69 lines -
-
-
-
-
1 - #! /usr/bin/env python 2 - # 3 - # Protocol Buffers - Google's data interchange format 4 - # Copyright 2008 Google Inc. All rights reserved. 5 - # https://developers.google.com/protocol-buffers/ 6 - # 7 - # Redistribution and use in source and binary forms, with or without 8 - # modification, are permitted provided that the following conditions are 9 - # met: 10 - # 11 - # * Redistributions of source code must retain the above copyright 12 - # notice, this list of conditions and the following disclaimer. 13 - # * Redistributions in binary form must reproduce the above 14 - # copyright notice, this list of conditions and the following disclaimer 15 - # in the documentation and/or other materials provided with the 16 - # distribution. 17 - # * Neither the name of Google Inc. nor the names of its 18 - # contributors may be used to endorse or promote products derived from 19 - # this software without specific prior written permission. 20 - # 21 - # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 - # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 - # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 - # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 - # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 - # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 - # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 - # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 - # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 - # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 - # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 - 33 - """Adds support for parameterized tests to Python's unittest TestCase class. 34 - 35 - A parameterized test is a method in a test case that is invoked with different 36 - argument tuples. 37 - 38 - A simple example: 39 - 40 - class AdditionExample(parameterized.ParameterizedTestCase): 41 - @parameterized.Parameters( 42 - (1, 2, 3), 43 - (4, 5, 9), 44 - (1, 1, 3)) 45 - def testAddition(self, op1, op2, result): 46 - self.assertEqual(result, op1 + op2) 47 - 48 - 49 - Each invocation is a separate test case and properly isolated just 50 - like a normal test method, with its own setUp/tearDown cycle. In the 51 - example above, there are three separate testcases, one of which will 52 - fail due to an assertion error (1 + 1 != 3). 53 - 54 - Parameters for invididual test cases can be tuples (with positional parameters) 55 - or dictionaries (with named parameters): 56 - 57 - class AdditionExample(parameterized.ParameterizedTestCase): 58 - @parameterized.Parameters( 59 - {'op1': 1, 'op2': 2, 'result': 3}, 60 - {'op1': 4, 'op2': 5, 'result': 9}, 61 - ) 62 - def testAddition(self, op1, op2, result): 63 - self.assertEqual(result, op1 + op2) 64 - 65 - If a parameterized test fails, the error message will show the 66 - original test name (which is modified internally) and the arguments 67 - for the specific invocation, which are part of the string returned by 68 - the shortDescription() method on test cases. 69 - 70 - The id method of the test, used internally by the unittest framework, 71 - is also modified to show the arguments. To make sure that test names 72 - stay the same across several invocations, object representations like 73 - 74 - >>> class Foo(object): 75 - ... pass 76 - >>> repr(Foo()) 77 - '<__main__.Foo object at 0x23d8610>' 78 - 79 - are turned into '<__main__.Foo>'. For even more descriptive names, 80 - especially in test logs, you can use the NamedParameters decorator. In 81 - this case, only tuples are supported, and the first parameters has to 82 - be a string (or an object that returns an apt name when converted via 83 - str()): 84 - 85 - class NamedExample(parameterized.ParameterizedTestCase): 86 - @parameterized.NamedParameters( 87 - ('Normal', 'aa', 'aaa', True), 88 - ('EmptyPrefix', '', 'abc', True), 89 - ('BothEmpty', '', '', True)) 90 - def testStartsWith(self, prefix, string, result): 91 - self.assertEqual(result, strings.startswith(prefix)) 92 - 93 - Named tests also have the benefit that they can be run individually 94 - from the command line: 95 - 96 - $ testmodule.py NamedExample.testStartsWithNormal 97 - . 98 - -------------------------------------------------------------------- 99 - Ran 1 test in 0.000s 100 - 101 - OK 102 - 103 - Parameterized Classes 104 - ===================== 105 - If invocation arguments are shared across test methods in a single 106 - ParameterizedTestCase class, instead of decorating all test methods 107 - individually, the class itself can be decorated: 108 - 109 - @parameterized.Parameters( 110 - (1, 2, 3) 111 - (4, 5, 9)) 112 - class ArithmeticTest(parameterized.ParameterizedTestCase): 113 - def testAdd(self, arg1, arg2, result): 114 - self.assertEqual(arg1 + arg2, result) 115 - 116 - def testSubtract(self, arg2, arg2, result): 117 - self.assertEqual(result - arg1, arg2) 118 - 119 - Inputs from Iterables 120 - ===================== 121 - If parameters should be shared across several test cases, or are dynamically 122 - created from other sources, a single non-tuple iterable can be passed into 123 - the decorator. This iterable will be used to obtain the test cases: 124 - 125 - class AdditionExample(parameterized.ParameterizedTestCase): 126 - @parameterized.Parameters( 127 - c.op1, c.op2, c.result for c in testcases 128 - ) 129 - def testAddition(self, op1, op2, result): 130 - self.assertEqual(result, op1 + op2) 131 - 132 - 133 - Single-Argument Test Methods 134 - ============================ 135 - If a test method takes only one argument, the single argument does not need to 136 - be wrapped into a tuple: 137 - 138 - class NegativeNumberExample(parameterized.ParameterizedTestCase): 139 - @parameterized.Parameters( 140 - -1, -3, -4, -5 141 - ) 142 - def testIsNegative(self, arg): 143 - self.assertTrue(IsNegative(arg)) 144 - """ 145 - 146 - __author__ = '[email protected] (Torsten Marek)' 147 - 148 - import collections 149 - import functools 150 - import re 151 - import types 152 - try: 153 - import unittest2 as unittest 154 - except ImportError: 155 - import unittest 156 - import uuid 157 - 158 - import six 159 - 160 - ADDR_RE = re.compile(r'\<([a-zA-Z0-9_\-\.]+) object at 0x[a-fA-F0-9]+\>') 161 - _SEPARATOR = uuid.uuid1().hex 162 - _FIRST_ARG = object() 163 - _ARGUMENT_REPR = object() 164 - 165 - 166 - def _CleanRepr(obj): 167 - return ADDR_RE.sub(r'<\1>', repr(obj)) 168 - 169 - 170 - # Helper function formerly from the unittest module, removed from it in 171 - # Python 2.7. 172 - def _StrClass(cls): 173 - return '%s.%s' % (cls.__module__, cls.__name__) 174 - 175 - 176 - def _NonStringIterable(obj): 177 - return (isinstance(obj, collections.Iterable) and not 178 - isinstance(obj, six.string_types)) 179 - 180 - 181 - def _FormatParameterList(testcase_params): 182 - if isinstance(testcase_params, collections.Mapping): 183 - return ', '.join('%s=%s' % (argname, _CleanRepr(value)) 184 - for argname, value in testcase_params.items()) 185 - elif _NonStringIterable(testcase_params): 186 - return ', '.join(map(_CleanRepr, testcase_params)) 187 - else: 188 - return _FormatParameterList((testcase_params,)) 189 - 190 - 191 - class _ParameterizedTestIter(object): 192 - """Callable and iterable class for producing new test cases.""" 193 - 194 - def __init__(self, test_method, testcases, naming_type): 195 - """Returns concrete test functions for a test and a list of parameters. 196 - 197 - The naming_type is used to determine the name of the concrete 198 - functions as reported by the unittest framework. If naming_type is 199 - _FIRST_ARG, the testcases must be tuples, and the first element must 200 - have a string representation that is a valid Python identifier. 201 - 202 - Args: 203 - test_method: The decorated test method. 204 - testcases: (list of tuple/dict) A list of parameter 205 - tuples/dicts for individual test invocations. 206 - naming_type: The test naming type, either _NAMED or _ARGUMENT_REPR. 207 - """ 208 - self._test_method = test_method 209 - self.testcases = testcases 210 - self._naming_type = naming_type 211 - 212 - def __call__(self, *args, **kwargs): 213 - raise RuntimeError('You appear to be running a parameterized test case ' 214 - 'without having inherited from parameterized.' 215 - 'ParameterizedTestCase. This is bad because none of ' 216 - 'your test cases are actually being run.') 217 - 218 - def __iter__(self): 219 - test_method = self._test_method 220 - naming_type = self._naming_type 221 - 222 - def MakeBoundParamTest(testcase_params): 223 - @functools.wraps(test_method) 224 - def BoundParamTest(self): 225 - if isinstance(testcase_params, collections.Mapping): 226 - test_method(self, **testcase_params) 227 - elif _NonStringIterable(testcase_params): 228 - test_method(self, *testcase_params) 229 - else: 230 - test_method(self, testcase_params) 231 - 232 - if naming_type is _FIRST_ARG: 233 - # Signal the metaclass that the name of the test function is unique 234 - # and descriptive. 235 - BoundParamTest.__x_use_name__ = True 236 - BoundParamTest.__name__ += str(testcase_params[0]) 237 - testcase_params = testcase_params[1:] 238 - elif naming_type is _ARGUMENT_REPR: 239 - # __x_extra_id__ is used to pass naming information to the __new__ 240 - # method of TestGeneratorMetaclass. 241 - # The metaclass will make sure to create a unique, but nondescriptive 242 - # name for this test. 243 - BoundParamTest.__x_extra_id__ = '(%s)' % ( 244 - _FormatParameterList(testcase_params),) 245 - else: 246 - raise RuntimeError('%s is not a valid naming type.' % (naming_type,)) 247 - 248 - BoundParamTest.__doc__ = '%s(%s)' % ( 249 - BoundParamTest.__name__, _FormatParameterList(testcase_params)) 250 - if test_method.__doc__: 251 - BoundParamTest.__doc__ += '\n%s' % (test_method.__doc__,) 252 - return BoundParamTest 253 - return (MakeBoundParamTest(c) for c in self.testcases) 254 - 255 - 256 - def _IsSingletonList(testcases): 257 - """True iff testcases contains only a single non-tuple element.""" 258 - return len(testcases) == 1 and not isinstance(testcases[0], tuple) 259 - 260 - 261 - def _ModifyClass(class_object, testcases, naming_type): 262 - assert not getattr(class_object, '_id_suffix', None), ( 263 - 'Cannot add parameters to %s,' 264 - ' which already has parameterized methods.' % (class_object,)) 265 - class_object._id_suffix = id_suffix = {} 266 - # We change the size of __dict__ while we iterate over it, 267 - # which Python 3.x will complain about, so use copy(). 268 - for name, obj in class_object.__dict__.copy().items(): 269 - if (name.startswith(unittest.TestLoader.testMethodPrefix) 270 - and isinstance(obj, types.FunctionType)): 271 - delattr(class_object, name) 272 - methods = {} 273 - _UpdateClassDictForParamTestCase( 274 - methods, id_suffix, name, 275 - _ParameterizedTestIter(obj, testcases, naming_type)) 276 - for name, meth in methods.items(): 277 - setattr(class_object, name, meth) 278 - 279 - 280 - def _ParameterDecorator(naming_type, testcases): 281 - """Implementation of the parameterization decorators. 282 - 283 - Args: 284 - naming_type: The naming type. 285 - testcases: Testcase parameters. 286 - 287 - Returns: 288 - A function for modifying the decorated object. 289 - """ 290 - def _Apply(obj): 291 - if isinstance(obj, type): 292 - _ModifyClass( 293 - obj, 294 - list(testcases) if not isinstance(testcases, collections.Sequence) 295 - else testcases, 296 - naming_type) 297 - return obj 298 - else: 299 - return _ParameterizedTestIter(obj, testcases, naming_type) 300 - 301 - if _IsSingletonList(testcases): 302 - assert _NonStringIterable(testcases[0]), ( 303 - 'Single parameter argument must be a non-string iterable') 304 - testcases = testcases[0] 305 - 306 - return _Apply 307 - 308 - 309 - def Parameters(*testcases): 310 - """A decorator for creating parameterized tests. 311 - 312 - See the module docstring for a usage example. 313 - Args: 314 - *testcases: Parameters for the decorated method, either a single 315 - iterable, or a list of tuples/dicts/objects (for tests 316 - with only one argument). 317 - 318 - Returns: 319 - A test generator to be handled by TestGeneratorMetaclass. 320 - """ 321 - return _ParameterDecorator(_ARGUMENT_REPR, testcases) 322 - 323 - 324 - def NamedParameters(*testcases): 325 - """A decorator for creating parameterized tests. 326 - 327 - See the module docstring for a usage example. The first element of 328 - each parameter tuple should be a string and will be appended to the 329 - name of the test method. 330 - 331 - Args: 332 - *testcases: Parameters for the decorated method, either a single 333 - iterable, or a list of tuples. 334 - 335 - Returns: 336 - A test generator to be handled by TestGeneratorMetaclass. 337 - """ 338 - return _ParameterDecorator(_FIRST_ARG, testcases) 339 - 340 - 341 - class TestGeneratorMetaclass(type): 342 - """Metaclass for test cases with test generators. 343 - 344 - A test generator is an iterable in a testcase that produces callables. These 345 - callables must be single-argument methods. These methods are injected into 346 - the class namespace and the original iterable is removed. If the name of the 347 - iterable conforms to the test pattern, the injected methods will be picked 348 - up as tests by the unittest framework. 349 - 350 - In general, it is supposed to be used in conjunction with the 351 - Parameters decorator. 352 - """ 353 - 354 - def __new__(mcs, class_name, bases, dct): 355 - dct['_id_suffix'] = id_suffix = {} 356 - for name, obj in dct.items(): 357 - if (name.startswith(unittest.TestLoader.testMethodPrefix) and 358 - _NonStringIterable(obj)): 359 - iterator = iter(obj) 360 - dct.pop(name) 361 - _UpdateClassDictForParamTestCase(dct, id_suffix, name, iterator) 362 - 363 - return type.__new__(mcs, class_name, bases, dct) 364 - 365 - 366 - def _UpdateClassDictForParamTestCase(dct, id_suffix, name, iterator): 367 - """Adds individual test cases to a dictionary. 368 - 369 - Args: 370 - dct: The target dictionary. 371 - id_suffix: The dictionary for mapping names to test IDs. 372 - name: The original name of the test case. 373 - iterator: The iterator generating the individual test cases. 374 - """ 375 - for idx, func in enumerate(iterator): 376 - assert callable(func), 'Test generators must yield callables, got %r' % ( 377 - func,) 378 - if getattr(func, '__x_use_name__', False): 379 - new_name = func.__name__ 380 - else: 381 - new_name = '%s%s%d' % (name, _SEPARATOR, idx) 382 - assert new_name not in dct, ( 383 - 'Name of parameterized test case "%s" not unique' % (new_name,)) 384 - dct[new_name] = func 385 - id_suffix[new_name] = getattr(func, '__x_extra_id__', '') 386 - 387 - 388 - class ParameterizedTestCase(unittest.TestCase): 389 - """Base class for test cases using the Parameters decorator.""" 390 - __metaclass__ = TestGeneratorMetaclass 391 - 392 - def _OriginalName(self): 393 - return self._testMethodName.split(_SEPARATOR)[0] 394 - 395 - def __str__(self): 396 - return '%s (%s)' % (self._OriginalName(), _StrClass(self.__class__)) 397 - 398 - def id(self): # pylint: disable=invalid-name 399 - """Returns the descriptive ID of the test. 400 - 401 - This is used internally by the unittesting framework to get a name 402 - for the test to be used in reports. 403 - 404 - Returns: 405 - The test id. 406 - """ 407 - return '%s.%s%s' % (_StrClass(self.__class__), 408 - self._OriginalName(), 409 - self._id_suffix.get(self._testMethodName, '')) 410 - 411 - 412 - def CoopParameterizedTestCase(other_base_class): 413 - """Returns a new base class with a cooperative metaclass base. 414 - 415 - This enables the ParameterizedTestCase to be used in combination 416 - with other base classes that have custom metaclasses, such as 417 - mox.MoxTestBase. 418 - 419 - Only works with metaclasses that do not override type.__new__. 420 - 421 - Example: 422 - 423 - import google3 424 - import mox 425 - 426 - from google3.testing.pybase import parameterized 427 - 428 - class ExampleTest(parameterized.CoopParameterizedTestCase(mox.MoxTestBase)): 429 - ... 430 - 431 - Args: 432 - other_base_class: (class) A test case base class. 433 - 434 - Returns: 435 - A new class object. 436 - """ 437 - metaclass = type( 438 - 'CoopMetaclass', 439 - (other_base_class.__metaclass__, 440 - TestGeneratorMetaclass), {}) 441 - return metaclass( 442 - 'CoopParameterizedTestCase', 443 - (other_base_class, ParameterizedTestCase), {}) 444 - -
-
-
skipped 32 lines 33 33 This file defines container classes which represent categories of protocol 34 34 buffer field types which need extra maintenance. Currently these categories 35 35 are: 36 - - Repeated scalar fields - These are all repeated fields which aren't 36 + 37 + - Repeated scalar fields - These are all repeated fields which aren't 37 38 composite (e.g. they are of simple types like int32, string, etc). 38 - - Repeated composite fields - Repeated fields which are composite. This 39 + - Repeated composite fields - Repeated fields which are composite. This 39 40 includes groups and nested messages. 40 41 """ 41 42 42 43 __author__ = '[email protected] (Petar Petrov)' 43 44 44 - import collections 45 45 import sys 46 + try: 47 + # This fallback applies for all versions of Python before 3.3 48 + import collections.abc as collections_abc 49 + except ImportError: 50 + import collections as collections_abc 46 51 47 52 if sys.version_info[0] < 3: 48 - # We would use collections.MutableMapping all the time, but in Python 2 it 49 - # doesn't define __slots__. This causes two significant problems: 53 + # We would use collections_abc.MutableMapping all the time, but in Python 2 54 + # it doesn't define __slots__. This causes two significant problems: 50 55 # 51 56 # 1. we can't disallow arbitrary attribute assignment, even if our derived 52 57 # classes *do* define __slots__. skipped 6 lines 59 64 # verbatim, except that: 60 65 # 1. We declare __slots__. 61 66 # 2. We don't declare this as a virtual base class. The classes defined 62 - # in collections are the interesting base classes, not us. 67 + # in collections_abc are the interesting base classes, not us. 63 68 # 64 69 # Note: deriving from object is critical. It is the only thing that makes 65 70 # this a true type, allowing us to derive from it in C++ cleanly and making skipped 40 lines 106 111 __hash__ = None 107 112 108 113 def __eq__(self, other): 109 - if not isinstance(other, collections.Mapping): 114 + if not isinstance(other, collections_abc.Mapping): 110 115 return NotImplemented 111 116 return dict(self.items()) == dict(other.items()) 112 117 skipped 60 lines 173 178 self[key] = default 174 179 return default 175 180 176 - collections.Mapping.register(Mapping) 177 - collections.MutableMapping.register(MutableMapping) 181 + collections_abc.Mapping.register(Mapping) 182 + collections_abc.MutableMapping.register(MutableMapping) 178 183 179 184 else: 180 185 # In Python 3 we can just use MutableMapping directly, because it defines 181 186 # __slots__. 182 - MutableMapping = collections.MutableMapping 187 + MutableMapping = collections_abc.MutableMapping 183 188 184 189 185 190 class BaseContainer(object): skipped 40 lines 226 231 kwargs['cmp'] = kwargs.pop('sort_function') 227 232 self._values.sort(*args, **kwargs) 228 233 234 + def reverse(self): 235 + self._values.reverse() 236 + 237 + 238 + collections_abc.MutableSequence.register(BaseContainer) 229 239 230 - class RepeatedScalarFieldContainer(BaseContainer): 231 240 241 + class RepeatedScalarFieldContainer(BaseContainer): 232 242 """Simple, type-checked, list-like container for holding repeated scalars.""" 233 243 234 244 # Disallows assignment to other attributes. 235 245 __slots__ = ['_type_checker'] 236 246 237 247 def __init__(self, message_listener, type_checker): 238 - """ 239 - Args: 240 - message_listener: A MessageListener implementation. 241 - The RepeatedScalarFieldContainer will call this object's 242 - Modified() method when it is modified. 248 + """Args: 249 + 250 + message_listener: A MessageListener implementation. The 251 + RepeatedScalarFieldContainer will call this object's Modified() method 252 + when it is modified. 243 253 type_checker: A type_checkers.ValueChecker instance to run on elements 244 - inserted into this container. 254 + inserted into this container. 245 255 """ 246 256 super(RepeatedScalarFieldContainer, self).__init__(message_listener) 247 257 self._type_checker = type_checker skipped 27 lines 275 285 new_values = [self._type_checker.CheckValue(elem) for elem in elem_seq_iter] 276 286 if new_values: 277 287 self._values.extend(new_values) 278 - self._message_listener.Modified() 288 + self._message_listener.Modified() 279 289 280 290 def MergeFrom(self, other): 281 291 """Appends the contents of another repeated field of the same type to this skipped 55 lines 337 347 # We are presumably comparing against some other sequence type. 338 348 return other == self._values 339 349 340 - collections.MutableSequence.register(BaseContainer) 341 - 342 350 343 351 class RepeatedCompositeFieldContainer(BaseContainer): 344 352 skipped 31 lines 376 384 self._message_listener.Modified() 377 385 return new_element 378 386 387 + def append(self, value): 388 + """Appends one element by copying the message.""" 389 + new_element = self._message_descriptor._concrete_class() 390 + new_element._SetListener(self._message_listener) 391 + new_element.CopyFrom(value) 392 + self._values.append(new_element) 393 + if not self._message_listener.dirty: 394 + self._message_listener.Modified() 395 + 396 + def insert(self, key, value): 397 + """Inserts the item at the specified position by copying.""" 398 + new_element = self._message_descriptor._concrete_class() 399 + new_element._SetListener(self._message_listener) 400 + new_element.CopyFrom(value) 401 + self._values.insert(key, new_element) 402 + if not self._message_listener.dirty: 403 + self._message_listener.Modified() 404 + 379 405 def extend(self, elem_seq): 380 406 """Extends by appending the given sequence of elements of the same type 407 + 381 408 as this one, copying each individual message. 382 409 """ 383 410 message_class = self._message_descriptor._concrete_class skipped 165 lines 549 576 self._values = {} 550 577 551 578 def __getitem__(self, key): 579 + key = self._key_checker.CheckValue(key) 552 580 try: 553 581 return self._values[key] 554 582 except KeyError: 555 - key = self._key_checker.CheckValue(key) 556 583 new_element = self._message_descriptor._concrete_class() 557 584 new_element._SetListener(self._message_listener) 558 585 self._values[key] = new_element skipped 25 lines 584 611 return default 585 612 586 613 def __contains__(self, item): 614 + item = self._key_checker.CheckValue(item) 587 615 return item in self._values 588 616 589 617 def __setitem__(self, key, value): 590 618 raise ValueError('May not set values directly, call my_map[key].foo = 5') 591 619 592 620 def __delitem__(self, key): 621 + key = self._key_checker.CheckValue(key) 593 622 del self._values[key] 594 623 self._message_listener.Modified() 595 624 skipped 7 lines 603 632 return repr(self._values) 604 633 605 634 def MergeFrom(self, other): 606 - for key in other: 635 + # pylint: disable=protected-access 636 + for key in other._values: 607 637 # According to documentation: "When parsing from the wire or when merging, 608 638 # if there are duplicate map keys the last key seen is used". 609 639 if key in self: skipped 17 lines 627 657 def GetEntryClass(self): 628 658 return self._entry_descriptor._concrete_class 629 659 660 + 661 + class _UnknownField(object): 662 + 663 + """A parsed unknown field.""" 664 + 665 + # Disallows assignment to other attributes. 666 + __slots__ = ['_field_number', '_wire_type', '_data'] 667 + 668 + def __init__(self, field_number, wire_type, data): 669 + self._field_number = field_number 670 + self._wire_type = wire_type 671 + self._data = data 672 + return 673 + 674 + def __lt__(self, other): 675 + # pylint: disable=protected-access 676 + return self._field_number < other._field_number 677 + 678 + def __eq__(self, other): 679 + if self is other: 680 + return True 681 + # pylint: disable=protected-access 682 + return (self._field_number == other._field_number and 683 + self._wire_type == other._wire_type and 684 + self._data == other._data) 685 + 686 + 687 + class UnknownFieldRef(object): 688 + 689 + def __init__(self, parent, index): 690 + self._parent = parent 691 + self._index = index 692 + return 693 + 694 + def _check_valid(self): 695 + if not self._parent: 696 + raise ValueError('UnknownField does not exist. ' 697 + 'The parent message might be cleared.') 698 + if self._index >= len(self._parent): 699 + raise ValueError('UnknownField does not exist. ' 700 + 'The parent message might be cleared.') 701 + 702 + @property 703 + def field_number(self): 704 + self._check_valid() 705 + # pylint: disable=protected-access 706 + return self._parent._internal_get(self._index)._field_number 707 + 708 + @property 709 + def wire_type(self): 710 + self._check_valid() 711 + # pylint: disable=protected-access 712 + return self._parent._internal_get(self._index)._wire_type 713 + 714 + @property 715 + def data(self): 716 + self._check_valid() 717 + # pylint: disable=protected-access 718 + return self._parent._internal_get(self._index)._data 719 + 720 + 721 + class UnknownFieldSet(object): 722 + 723 + """UnknownField container""" 724 + 725 + # Disallows assignment to other attributes. 726 + __slots__ = ['_values'] 727 + 728 + def __init__(self): 729 + self._values = [] 730 + 731 + def __getitem__(self, index): 732 + if self._values is None: 733 + raise ValueError('UnknownFields does not exist. ' 734 + 'The parent message might be cleared.') 735 + size = len(self._values) 736 + if index < 0: 737 + index += size 738 + if index < 0 or index >= size: 739 + raise IndexError('index %d out of range'.index) 740 + 741 + return UnknownFieldRef(self, index) 742 + 743 + def _internal_get(self, index): 744 + return self._values[index] 745 + 746 + def __len__(self): 747 + if self._values is None: 748 + raise ValueError('UnknownFields does not exist. ' 749 + 'The parent message might be cleared.') 750 + return len(self._values) 751 + 752 + def _add(self, field_number, wire_type, data): 753 + unknown_field = _UnknownField(field_number, wire_type, data) 754 + self._values.append(unknown_field) 755 + return unknown_field 756 + 757 + def __iter__(self): 758 + for i in range(len(self)): 759 + yield UnknownFieldRef(self, i) 760 + 761 + def _extend(self, other): 762 + if other is None: 763 + return 764 + # pylint: disable=protected-access 765 + self._values.extend(other._values) 766 + 767 + def __eq__(self, other): 768 + if self is other: 769 + return True 770 + # Sort unknown fields because their order shouldn't 771 + # affect equality test. 772 + values = list(self._values) 773 + if other is None: 774 + return not values 775 + values.sort() 776 + # pylint: disable=protected-access 777 + other_values = sorted(other._values) 778 + return values == other_values 779 + 780 + def _clear(self): 781 + for value in self._values: 782 + # pylint: disable=protected-access 783 + if isinstance(value._data, UnknownFieldSet): 784 + value._data._clear() # pylint: disable=protected-access 785 + self._values = None 786 + -
skipped 80 lines 81 81 __author__ = '[email protected] (Kenton Varda)' 82 82 83 83 import struct 84 - 84 + import sys 85 85 import six 86 86 87 + _UCS2_MAXUNICODE = 65535 87 88 if six.PY3: 88 89 long = int 90 + else: 91 + import re # pylint: disable=g-import-not-at-top 92 + _SURROGATE_PATTERN = re.compile(six.u(r'[\ud800-\udfff]')) 89 93 94 + from google.protobuf.internal import containers 90 95 from google.protobuf.internal import encoder 91 96 from google.protobuf.internal import wire_format 92 97 from google.protobuf import message skipped 38 lines 131 136 return DecodeVarint 132 137 133 138 134 - def _SignedVarintDecoder(mask, result_type): 139 + def _SignedVarintDecoder(bits, result_type): 135 140 """Like _VarintDecoder() but decodes signed values.""" 141 + 142 + signbit = 1 << (bits - 1) 143 + mask = (1 << bits) - 1 136 144 137 145 def DecodeVarint(buffer, pos): 138 146 result = 0 skipped 3 lines 142 150 result |= ((b & 0x7f) << shift) 143 151 pos += 1 144 152 if not (b & 0x80): 145 - if result > 0x7fffffffffffffff: 146 - result -= (1 << 64) 147 - result |= ~mask 148 - else: 149 - result &= mask 153 + result &= mask 154 + result = (result ^ signbit) - signbit 150 155 result = result_type(result) 151 156 return (result, pos) 152 157 shift += 7 skipped 6 lines 159 164 # (e.g. the C++ implementation) simpler. 160 165 161 166 _DecodeVarint = _VarintDecoder((1 << 64) - 1, long) 162 - _DecodeSignedVarint = _SignedVarintDecoder((1 << 64) - 1, long) 167 + _DecodeSignedVarint = _SignedVarintDecoder(64, long) 163 168 164 169 # Use these versions for values which must be limited to 32 bits. 165 170 _DecodeVarint32 = _VarintDecoder((1 << 32) - 1, int) 166 - _DecodeSignedVarint32 = _SignedVarintDecoder((1 << 32) - 1, int) 171 + _DecodeSignedVarint32 = _SignedVarintDecoder(32, int) 167 172 168 173 169 174 def ReadTag(buffer, pos): 170 - """Read a tag from the buffer, and return a (tag_bytes, new_pos) tuple. 175 + """Read a tag from the memoryview, and return a (tag_bytes, new_pos) tuple. 171 176 172 177 We return the raw bytes of the tag rather than decoding them. The raw 173 178 bytes can then be used to look up the proper decoder. This effectively allows skipped 1 lines 175 180 for work that is done in C (searching for a byte string in a hash table). 176 181 In a low-level language it would be much cheaper to decode the varint and 177 182 use that, but not in Python. 178 - """ 183 + 184 + Args: 185 + buffer: memoryview object of the encoded bytes 186 + pos: int of the current position to start from 179 187 188 + Returns: 189 + Tuple[bytes, int] of the tag data and new position. 190 + """ 180 191 start = pos 181 192 while six.indexbytes(buffer, pos) & 0x80: 182 193 pos += 1 183 194 pos += 1 184 - return (buffer[start:pos], pos) 195 + 196 + tag_bytes = buffer[start:pos].tobytes() 197 + return tag_bytes, pos 185 198 186 199 187 200 # -------------------------------------------------------------------- skipped 8 lines 196 209 _DecodeVarint() 197 210 """ 198 211 199 - def SpecificDecoder(field_number, is_repeated, is_packed, key, new_default): 212 + def SpecificDecoder(field_number, is_repeated, is_packed, key, new_default, 213 + clear_if_default=False): 200 214 if is_packed: 201 215 local_DecodeVarint = _DecodeVarint 202 216 def DecodePackedField(buffer, pos, end, message, field_dict): skipped 33 lines 236 250 return DecodeRepeatedField 237 251 else: 238 252 def DecodeField(buffer, pos, end, message, field_dict): 239 - (field_dict[key], pos) = decode_value(buffer, pos) 253 + (new_value, pos) = decode_value(buffer, pos) 240 254 if pos > end: 241 - del field_dict[key] # Discard corrupt value. 242 255 raise _DecodeError('Truncated message.') 256 + if clear_if_default and not new_value: 257 + field_dict.pop(key, None) 258 + else: 259 + field_dict[key] = new_value 243 260 return pos 244 261 return DecodeField 245 262 skipped 49 lines 295 312 local_unpack = struct.unpack 296 313 297 314 def InnerDecode(buffer, pos): 315 + """Decode serialized float to a float and new position. 316 + 317 + Args: 318 + buffer: memoryview of the serialized bytes 319 + pos: int, position in the memory view to start at. 320 + 321 + Returns: 322 + Tuple[float, int] of the deserialized float value and new position 323 + in the serialized data. 324 + """ 298 325 # We expect a 32-bit value in little-endian byte order. Bit 1 is the sign 299 326 # bit, bits 2-9 represent the exponent, and bits 10-32 are the significand. 300 327 new_pos = pos + 4 301 - float_bytes = buffer[pos:new_pos] 328 + float_bytes = buffer[pos:new_pos].tobytes() 302 329 303 330 # If this value has all its exponent bits set, then it's non-finite. 304 331 # In Python 2.4, struct.unpack will convert it to a finite 64-bit value. skipped 24 lines 329 356 local_unpack = struct.unpack 330 357 331 358 def InnerDecode(buffer, pos): 359 + """Decode serialized double to a double and new position. 360 + 361 + Args: 362 + buffer: memoryview of the serialized bytes. 363 + pos: int, position in the memory view to start at. 364 + 365 + Returns: 366 + Tuple[float, int] of the decoded double value and new position 367 + in the serialized data. 368 + """ 332 369 # We expect a 64-bit value in little-endian byte order. Bit 1 is the sign 333 370 # bit, bits 2-12 represent the exponent, and bits 13-64 are the significand. 334 371 new_pos = pos + 8 335 - double_bytes = buffer[pos:new_pos] 372 + double_bytes = buffer[pos:new_pos].tobytes() 336 373 337 374 # If this value has all its exponent bits set and at least one significand 338 375 # bit set, it's not a number. In Python 2.4, struct.unpack will treat it skipped 11 lines 350 387 return _SimpleDecoder(wire_format.WIRETYPE_FIXED64, InnerDecode) 351 388 352 389 353 - def EnumDecoder(field_number, is_repeated, is_packed, key, new_default): 390 + def EnumDecoder(field_number, is_repeated, is_packed, key, new_default, 391 + clear_if_default=False): 392 + """Returns a decoder for enum field.""" 354 393 enum_type = key.enum_type 355 394 if is_packed: 356 395 local_DecodeVarint = _DecodeVarint 357 396 def DecodePackedField(buffer, pos, end, message, field_dict): 397 + """Decode serialized packed enum to its value and a new position. 398 + 399 + Args: 400 + buffer: memoryview of the serialized bytes. 401 + pos: int, position in the memory view to start at. 402 + end: int, end position of serialized data 403 + message: Message object to store unknown fields in 404 + field_dict: Map[Descriptor, Any] to store decoded values in. 405 + 406 + Returns: 407 + int, new position in serialized data. 408 + """ 358 409 value = field_dict.get(key) 359 410 if value is None: 360 411 value = field_dict.setdefault(key, new_default(message)) skipped 4 lines 365 416 while pos < endpoint: 366 417 value_start_pos = pos 367 418 (element, pos) = _DecodeSignedVarint32(buffer, pos) 419 + # pylint: disable=protected-access 368 420 if element in enum_type.values_by_number: 369 421 value.append(element) 370 422 else: skipped 1 lines 372 424 message._unknown_fields = [] 373 425 tag_bytes = encoder.TagBytes(field_number, 374 426 wire_format.WIRETYPE_VARINT) 427 + 375 428 message._unknown_fields.append( 376 - (tag_bytes, buffer[value_start_pos:pos])) 429 + (tag_bytes, buffer[value_start_pos:pos].tobytes())) 430 + if message._unknown_field_set is None: 431 + message._unknown_field_set = containers.UnknownFieldSet() 432 + message._unknown_field_set._add( 433 + field_number, wire_format.WIRETYPE_VARINT, element) 434 + # pylint: enable=protected-access 377 435 if pos > endpoint: 378 436 if element in enum_type.values_by_number: 379 437 del value[-1] # Discard corrupt value. 380 438 else: 381 439 del message._unknown_fields[-1] 440 + # pylint: disable=protected-access 441 + del message._unknown_field_set._values[-1] 442 + # pylint: enable=protected-access 382 443 raise _DecodeError('Packed element was truncated.') 383 444 return pos 384 445 return DecodePackedField skipped 1 lines 386 447 tag_bytes = encoder.TagBytes(field_number, wire_format.WIRETYPE_VARINT) 387 448 tag_len = len(tag_bytes) 388 449 def DecodeRepeatedField(buffer, pos, end, message, field_dict): 450 + """Decode serialized repeated enum to its value and a new position. 451 + 452 + Args: 453 + buffer: memoryview of the serialized bytes. 454 + pos: int, position in the memory view to start at. 455 + end: int, end position of serialized data 456 + message: Message object to store unknown fields in 457 + field_dict: Map[Descriptor, Any] to store decoded values in. 458 + 459 + Returns: 460 + int, new position in serialized data. 461 + """ 389 462 value = field_dict.get(key) 390 463 if value is None: 391 464 value = field_dict.setdefault(key, new_default(message)) 392 465 while 1: 393 466 (element, new_pos) = _DecodeSignedVarint32(buffer, pos) 467 + # pylint: disable=protected-access 394 468 if element in enum_type.values_by_number: 395 469 value.append(element) 396 470 else: 397 471 if not message._unknown_fields: 398 472 message._unknown_fields = [] 399 473 message._unknown_fields.append( 400 - (tag_bytes, buffer[pos:new_pos])) 474 + (tag_bytes, buffer[pos:new_pos].tobytes())) 475 + if message._unknown_field_set is None: 476 + message._unknown_field_set = containers.UnknownFieldSet() 477 + message._unknown_field_set._add( 478 + field_number, wire_format.WIRETYPE_VARINT, element) 479 + # pylint: enable=protected-access 401 480 # Predict that the next tag is another copy of the same repeated 402 481 # field. 403 482 pos = new_pos + tag_len skipped 5 lines 409 488 return DecodeRepeatedField 410 489 else: 411 490 def DecodeField(buffer, pos, end, message, field_dict): 491 + """Decode serialized repeated enum to its value and a new position. 492 + 493 + Args: 494 + buffer: memoryview of the serialized bytes. 495 + pos: int, position in the memory view to start at. 496 + end: int, end position of serialized data 497 + message: Message object to store unknown fields in 498 + field_dict: Map[Descriptor, Any] to store decoded values in. 499 + 500 + Returns: 501 + int, new position in serialized data. 502 + """ 412 503 value_start_pos = pos 413 504 (enum_value, pos) = _DecodeSignedVarint32(buffer, pos) 414 505 if pos > end: 415 506 raise _DecodeError('Truncated message.') 507 + if clear_if_default and not enum_value: 508 + field_dict.pop(key, None) 509 + return pos 510 + # pylint: disable=protected-access 416 511 if enum_value in enum_type.values_by_number: 417 512 field_dict[key] = enum_value 418 513 else: skipped 2 lines 421 516 tag_bytes = encoder.TagBytes(field_number, 422 517 wire_format.WIRETYPE_VARINT) 423 518 message._unknown_fields.append( 424 - (tag_bytes, buffer[value_start_pos:pos])) 519 + (tag_bytes, buffer[value_start_pos:pos].tobytes())) 520 + if message._unknown_field_set is None: 521 + message._unknown_field_set = containers.UnknownFieldSet() 522 + message._unknown_field_set._add( 523 + field_number, wire_format.WIRETYPE_VARINT, enum_value) 524 + # pylint: enable=protected-access 425 525 return pos 426 526 return DecodeField 427 527 skipped 30 lines 458 558 wire_format.WIRETYPE_VARINT, _DecodeVarint, bool) 459 559 460 560 461 - def StringDecoder(field_number, is_repeated, is_packed, key, new_default): 561 + def StringDecoder(field_number, is_repeated, is_packed, key, new_default, 562 + is_strict_utf8=False, clear_if_default=False): 462 563 """Returns a decoder for a string field.""" 463 564 464 565 local_DecodeVarint = _DecodeVarint 465 566 local_unicode = six.text_type 466 567 467 - def _ConvertToUnicode(byte_str): 568 + def _ConvertToUnicode(memview): 569 + """Convert byte to unicode.""" 570 + byte_str = memview.tobytes() 468 571 try: 469 - return local_unicode(byte_str, 'utf-8') 572 + value = local_unicode(byte_str, 'utf-8') 470 573 except UnicodeDecodeError as e: 471 574 # add more information to the error message and re-raise it. 472 575 e.reason = '%s in field: %s' % (e, key.full_name) 473 576 raise 474 577 578 + if is_strict_utf8 and six.PY2 and sys.maxunicode > _UCS2_MAXUNICODE: 579 + # Only do the check for python2 ucs4 when is_strict_utf8 enabled 580 + if _SURROGATE_PATTERN.search(value): 581 + reason = ('String field %s contains invalid UTF-8 data when parsing' 582 + 'a protocol buffer: surrogates not allowed. Use' 583 + 'the bytes type if you intend to send raw bytes.') % ( 584 + key.full_name) 585 + raise message.DecodeError(reason) 586 + 587 + return value 588 + 475 589 assert not is_packed 476 590 if is_repeated: 477 591 tag_bytes = encoder.TagBytes(field_number, skipped 21 lines 499 613 new_pos = pos + size 500 614 if new_pos > end: 501 615 raise _DecodeError('Truncated string.') 502 - field_dict[key] = _ConvertToUnicode(buffer[pos:new_pos]) 616 + if clear_if_default and not size: 617 + field_dict.pop(key, None) 618 + else: 619 + field_dict[key] = _ConvertToUnicode(buffer[pos:new_pos]) 503 620 return new_pos 504 621 return DecodeField 505 622 506 623 507 - def BytesDecoder(field_number, is_repeated, is_packed, key, new_default): 624 + def BytesDecoder(field_number, is_repeated, is_packed, key, new_default, 625 + clear_if_default=False): 508 626 """Returns a decoder for a bytes field.""" 509 627 510 628 local_DecodeVarint = _DecodeVarint skipped 12 lines 523 641 new_pos = pos + size 524 642 if new_pos > end: 525 643 raise _DecodeError('Truncated string.') 526 - value.append(buffer[pos:new_pos]) 644 + value.append(buffer[pos:new_pos].tobytes()) 527 645 # Predict that the next tag is another copy of the same repeated field. 528 646 pos = new_pos + tag_len 529 647 if buffer[new_pos:pos] != tag_bytes or new_pos == end: skipped 6 lines 536 654 new_pos = pos + size 537 655 if new_pos > end: 538 656 raise _DecodeError('Truncated string.') 539 - field_dict[key] = buffer[pos:new_pos] 657 + if clear_if_default and not size: 658 + field_dict.pop(key, None) 659 + else: 660 + field_dict[key] = buffer[pos:new_pos].tobytes() 540 661 return new_pos 541 662 return DecodeField 542 663 skipped 122 lines 665 786 local_SkipField = SkipField 666 787 667 788 def DecodeItem(buffer, pos, end, message, field_dict): 789 + """Decode serialized message set to its value and new position. 790 + 791 + Args: 792 + buffer: memoryview of the serialized bytes. 793 + pos: int, position in the memory view to start at. 794 + end: int, end position of serialized data 795 + message: Message object to store unknown fields in 796 + field_dict: Map[Descriptor, Any] to store decoded values in. 797 + 798 + Returns: 799 + int, new position in serialized data. 800 + """ 668 801 message_set_item_start = pos 669 802 type_id = -1 670 803 message_start = -1 skipped 24 lines 695 828 raise _DecodeError('MessageSet item missing message.') 696 829 697 830 extension = message.Extensions._FindExtensionByNumber(type_id) 831 + # pylint: disable=protected-access 698 832 if extension is not None: 699 833 value = field_dict.get(extension) 700 834 if value is None: 835 + message_type = extension.message_type 836 + if not hasattr(message_type, '_concrete_class'): 837 + # pylint: disable=protected-access 838 + message._FACTORY.GetPrototype(message_type) 701 839 value = field_dict.setdefault( 702 - extension, extension.message_type._concrete_class()) 840 + extension, message_type._concrete_class()) 703 841 if value._InternalParse(buffer, message_start,message_end) != message_end: 704 842 # The only reason _InternalParse would return early is if it encountered 705 843 # an end-group tag. skipped 1 lines 707 845 else: 708 846 if not message._unknown_fields: 709 847 message._unknown_fields = [] 710 - message._unknown_fields.append((MESSAGE_SET_ITEM_TAG, 711 - buffer[message_set_item_start:pos])) 848 + message._unknown_fields.append( 849 + (MESSAGE_SET_ITEM_TAG, buffer[message_set_item_start:pos].tobytes())) 850 + if message._unknown_field_set is None: 851 + message._unknown_field_set = containers.UnknownFieldSet() 852 + message._unknown_field_set._add( 853 + type_id, 854 + wire_format.WIRETYPE_LENGTH_DELIMITED, 855 + buffer[message_start:message_end].tobytes()) 856 + # pylint: enable=protected-access 712 857 713 858 return pos 714 859 skipped 31 lines 746 891 raise _DecodeError('Unexpected end-group tag.') 747 892 748 893 if is_message_map: 749 - value[submsg.key].MergeFrom(submsg.value) 894 + value[submsg.key].CopyFrom(submsg.value) 750 895 else: 751 896 value[submsg.key] = submsg.value 752 897 skipped 14 lines 767 912 # Previously ord(buffer[pos]) raised IndexError when pos is out of range. 768 913 # With this code, ord(b'') raises TypeError. Both are handled in 769 914 # python_message.py to generate a 'Truncated message' error. 770 - while ord(buffer[pos:pos+1]) & 0x80: 915 + while ord(buffer[pos:pos+1].tobytes()) & 0x80: 771 916 pos += 1 772 917 pos += 1 773 918 if pos > end: skipped 8 lines 782 927 raise _DecodeError('Truncated message.') 783 928 return pos 784 929 930 + 931 + def _DecodeFixed64(buffer, pos): 932 + """Decode a fixed64.""" 933 + new_pos = pos + 8 934 + return (struct.unpack('<Q', buffer[pos:new_pos])[0], new_pos) 935 + 936 + 785 937 def _SkipLengthDelimited(buffer, pos, end): 786 938 """Skip a length-delimited value. Returns the new position.""" 787 939 skipped 2 lines 790 942 if pos > end: 791 943 raise _DecodeError('Truncated message.') 792 944 return pos 945 + 793 946 794 947 def _SkipGroup(buffer, pos, end): 795 948 """Skip sub-group. Returns the new position.""" skipped 5 lines 801 954 return pos 802 955 pos = new_pos 803 956 957 + 958 + def _DecodeUnknownFieldSet(buffer, pos, end_pos=None): 959 + """Decode UnknownFieldSet. Returns the UnknownFieldSet and new position.""" 960 + 961 + unknown_field_set = containers.UnknownFieldSet() 962 + while end_pos is None or pos < end_pos: 963 + (tag_bytes, pos) = ReadTag(buffer, pos) 964 + (tag, _) = _DecodeVarint(tag_bytes, 0) 965 + field_number, wire_type = wire_format.UnpackTag(tag) 966 + if wire_type == wire_format.WIRETYPE_END_GROUP: 967 + break 968 + (data, pos) = _DecodeUnknownField(buffer, pos, wire_type) 969 + # pylint: disable=protected-access 970 + unknown_field_set._add(field_number, wire_type, data) 971 + 972 + return (unknown_field_set, pos) 973 + 974 + 975 + def _DecodeUnknownField(buffer, pos, wire_type): 976 + """Decode a unknown field. Returns the UnknownField and new position.""" 977 + 978 + if wire_type == wire_format.WIRETYPE_VARINT: 979 + (data, pos) = _DecodeVarint(buffer, pos) 980 + elif wire_type == wire_format.WIRETYPE_FIXED64: 981 + (data, pos) = _DecodeFixed64(buffer, pos) 982 + elif wire_type == wire_format.WIRETYPE_FIXED32: 983 + (data, pos) = _DecodeFixed32(buffer, pos) 984 + elif wire_type == wire_format.WIRETYPE_LENGTH_DELIMITED: 985 + (size, pos) = _DecodeVarint(buffer, pos) 986 + data = buffer[pos:pos+size].tobytes() 987 + pos += size 988 + elif wire_type == wire_format.WIRETYPE_START_GROUP: 989 + (data, pos) = _DecodeUnknownFieldSet(buffer, pos) 990 + elif wire_type == wire_format.WIRETYPE_END_GROUP: 991 + return (0, -1) 992 + else: 993 + raise _DecodeError('Wrong wire type in tag.') 994 + 995 + return (data, pos) 996 + 997 + 804 998 def _EndGroup(buffer, pos, end): 805 999 """Skipping an END_GROUP tag returns -1 to tell the parent loop to break.""" 806 1000 807 1001 return -1 1002 + 808 1003 809 1004 def _SkipFixed32(buffer, pos, end): 810 1005 """Skip a fixed32 value. Returns the new position.""" skipped 2 lines 813 1008 if pos > end: 814 1009 raise _DecodeError('Truncated message.') 815 1010 return pos 1011 + 1012 + 1013 + def _DecodeFixed32(buffer, pos): 1014 + """Decode a fixed32.""" 1015 + 1016 + new_pos = pos + 4 1017 + return (struct.unpack('<I', buffer[pos:new_pos])[0], new_pos) 1018 + 816 1019 817 1020 def _RaiseInvalidWireType(buffer, pos, end): 818 1021 """Skip function for unknown wire types. Raises an exception.""" skipped 37 lines -
1 - #! /usr/bin/env python 2 - # 3 - # Protocol Buffers - Google's data interchange format 4 - # Copyright 2008 Google Inc. All rights reserved. 5 - # https://developers.google.com/protocol-buffers/ 6 - # 7 - # Redistribution and use in source and binary forms, with or without 8 - # modification, are permitted provided that the following conditions are 9 - # met: 10 - # 11 - # * Redistributions of source code must retain the above copyright 12 - # notice, this list of conditions and the following disclaimer. 13 - # * Redistributions in binary form must reproduce the above 14 - # copyright notice, this list of conditions and the following disclaimer 15 - # in the documentation and/or other materials provided with the 16 - # distribution. 17 - # * Neither the name of Google Inc. nor the names of its 18 - # contributors may be used to endorse or promote products derived from 19 - # this software without specific prior written permission. 20 - # 21 - # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 - # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 - # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 - # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 - # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 - # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 - # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 - # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 - # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 - # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 - # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 - 33 - """Tests for google.protobuf.descriptor_database.""" 34 - 35 - __author__ = '[email protected] (Matt Toia)' 36 - 37 - try: 38 - import unittest2 as unittest #PY26 39 - except ImportError: 40 - import unittest 41 - 42 - from google.protobuf import descriptor_pb2 43 - from google.protobuf.internal import factory_test2_pb2 44 - from google.protobuf import descriptor_database 45 - 46 - 47 - class DescriptorDatabaseTest(unittest.TestCase): 48 - 49 - def testAdd(self): 50 - db = descriptor_database.DescriptorDatabase() 51 - file_desc_proto = descriptor_pb2.FileDescriptorProto.FromString( 52 - factory_test2_pb2.DESCRIPTOR.serialized_pb) 53 - db.Add(file_desc_proto) 54 - 55 - self.assertEqual(file_desc_proto, db.FindFileByName( 56 - 'google/protobuf/internal/factory_test2.proto')) 57 - self.assertEqual(file_desc_proto, db.FindFileContainingSymbol( 58 - 'google.protobuf.python.internal.Factory2Message')) 59 - self.assertEqual(file_desc_proto, db.FindFileContainingSymbol( 60 - 'google.protobuf.python.internal.Factory2Message.NestedFactory2Message')) 61 - self.assertEqual(file_desc_proto, db.FindFileContainingSymbol( 62 - 'google.protobuf.python.internal.Factory2Enum')) 63 - self.assertEqual(file_desc_proto, db.FindFileContainingSymbol( 64 - 'google.protobuf.python.internal.Factory2Message.NestedFactory2Enum')) 65 - self.assertEqual(file_desc_proto, db.FindFileContainingSymbol( 66 - 'google.protobuf.python.internal.MessageWithNestedEnumOnly.NestedEnum')) 67 - 68 - if __name__ == '__main__': 69 - unittest.main() 70 - -
1 - #! /usr/bin/env python 2 - # 3 - # Protocol Buffers - Google's data interchange format 4 - # Copyright 2008 Google Inc. All rights reserved. 5 - # https://developers.google.com/protocol-buffers/ 6 - # 7 - # Redistribution and use in source and binary forms, with or without 8 - # modification, are permitted provided that the following conditions are 9 - # met: 10 - # 11 - # * Redistributions of source code must retain the above copyright 12 - # notice, this list of conditions and the following disclaimer. 13 - # * Redistributions in binary form must reproduce the above 14 - # copyright notice, this list of conditions and the following disclaimer 15 - # in the documentation and/or other materials provided with the 16 - # distribution. 17 - # * Neither the name of Google Inc. nor the names of its 18 - # contributors may be used to endorse or promote products derived from 19 - # this software without specific prior written permission. 20 - # 21 - # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 - # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 - # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 - # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 - # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 - # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 - # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 - # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 - # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 - # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 - # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 - 33 - """Tests for google.protobuf.descriptor_pool.""" 34 - 35 - __author__ = '[email protected] (Matt Toia)' 36 - 37 - import os 38 - import sys 39 - 40 - try: 41 - import unittest2 as unittest #PY26 42 - except ImportError: 43 - import unittest 44 - 45 - from google.protobuf import unittest_import_pb2 46 - from google.protobuf import unittest_import_public_pb2 47 - from google.protobuf import unittest_pb2 48 - from google.protobuf import descriptor_pb2 49 - from google.protobuf.internal import api_implementation 50 - from google.protobuf.internal import descriptor_pool_test1_pb2 51 - from google.protobuf.internal import descriptor_pool_test2_pb2 52 - from google.protobuf.internal import factory_test1_pb2 53 - from google.protobuf.internal import factory_test2_pb2 54 - from google.protobuf.internal import file_options_test_pb2 55 - from google.protobuf.internal import more_messages_pb2 56 - from google.protobuf import descriptor 57 - from google.protobuf import descriptor_database 58 - from google.protobuf import descriptor_pool 59 - from google.protobuf import message_factory 60 - from google.protobuf import symbol_database 61 - 62 - 63 - class DescriptorPoolTest(unittest.TestCase): 64 - 65 - def setUp(self): 66 - self.pool = descriptor_pool.DescriptorPool() 67 - self.factory_test1_fd = descriptor_pb2.FileDescriptorProto.FromString( 68 - factory_test1_pb2.DESCRIPTOR.serialized_pb) 69 - self.factory_test2_fd = descriptor_pb2.FileDescriptorProto.FromString( 70 - factory_test2_pb2.DESCRIPTOR.serialized_pb) 71 - self.pool.Add(self.factory_test1_fd) 72 - self.pool.Add(self.factory_test2_fd) 73 - 74 - def testFindFileByName(self): 75 - name1 = 'google/protobuf/internal/factory_test1.proto' 76 - file_desc1 = self.pool.FindFileByName(name1) 77 - self.assertIsInstance(file_desc1, descriptor.FileDescriptor) 78 - self.assertEqual(name1, file_desc1.name) 79 - self.assertEqual('google.protobuf.python.internal', file_desc1.package) 80 - self.assertIn('Factory1Message', file_desc1.message_types_by_name) 81 - 82 - name2 = 'google/protobuf/internal/factory_test2.proto' 83 - file_desc2 = self.pool.FindFileByName(name2) 84 - self.assertIsInstance(file_desc2, descriptor.FileDescriptor) 85 - self.assertEqual(name2, file_desc2.name) 86 - self.assertEqual('google.protobuf.python.internal', file_desc2.package) 87 - self.assertIn('Factory2Message', file_desc2.message_types_by_name) 88 - 89 - def testFindFileByNameFailure(self): 90 - with self.assertRaises(KeyError): 91 - self.pool.FindFileByName('Does not exist') 92 - 93 - def testFindFileContainingSymbol(self): 94 - file_desc1 = self.pool.FindFileContainingSymbol( 95 - 'google.protobuf.python.internal.Factory1Message') 96 - self.assertIsInstance(file_desc1, descriptor.FileDescriptor) 97 - self.assertEqual('google/protobuf/internal/factory_test1.proto', 98 - file_desc1.name) 99 - self.assertEqual('google.protobuf.python.internal', file_desc1.package) 100 - self.assertIn('Factory1Message', file_desc1.message_types_by_name) 101 - 102 - file_desc2 = self.pool.FindFileContainingSymbol( 103 - 'google.protobuf.python.internal.Factory2Message') 104 - self.assertIsInstance(file_desc2, descriptor.FileDescriptor) 105 - self.assertEqual('google/protobuf/internal/factory_test2.proto', 106 - file_desc2.name) 107 - self.assertEqual('google.protobuf.python.internal', file_desc2.package) 108 - self.assertIn('Factory2Message', file_desc2.message_types_by_name) 109 - 110 - def testFindFileContainingSymbolFailure(self): 111 - with self.assertRaises(KeyError): 112 - self.pool.FindFileContainingSymbol('Does not exist') 113 - 114 - def testFindMessageTypeByName(self): 115 - msg1 = self.pool.FindMessageTypeByName( 116 - 'google.protobuf.python.internal.Factory1Message') 117 - self.assertIsInstance(msg1, descriptor.Descriptor) 118 - self.assertEqual('Factory1Message', msg1.name) 119 - self.assertEqual('google.protobuf.python.internal.Factory1Message', 120 - msg1.full_name) 121 - self.assertEqual(None, msg1.containing_type) 122 - self.assertFalse(msg1.has_options) 123 - 124 - nested_msg1 = msg1.nested_types[0] 125 - self.assertEqual('NestedFactory1Message', nested_msg1.name) 126 - self.assertEqual(msg1, nested_msg1.containing_type) 127 - 128 - nested_enum1 = msg1.enum_types[0] 129 - self.assertEqual('NestedFactory1Enum', nested_enum1.name) 130 - self.assertEqual(msg1, nested_enum1.containing_type) 131 - 132 - self.assertEqual(nested_msg1, msg1.fields_by_name[ 133 - 'nested_factory_1_message'].message_type) 134 - self.assertEqual(nested_enum1, msg1.fields_by_name[ 135 - 'nested_factory_1_enum'].enum_type) 136 - 137 - msg2 = self.pool.FindMessageTypeByName( 138 - 'google.protobuf.python.internal.Factory2Message') 139 - self.assertIsInstance(msg2, descriptor.Descriptor) 140 - self.assertEqual('Factory2Message', msg2.name) 141 - self.assertEqual('google.protobuf.python.internal.Factory2Message', 142 - msg2.full_name) 143 - self.assertIsNone(msg2.containing_type) 144 - 145 - nested_msg2 = msg2.nested_types[0] 146 - self.assertEqual('NestedFactory2Message', nested_msg2.name) 147 - self.assertEqual(msg2, nested_msg2.containing_type) 148 - 149 - nested_enum2 = msg2.enum_types[0] 150 - self.assertEqual('NestedFactory2Enum', nested_enum2.name) 151 - self.assertEqual(msg2, nested_enum2.containing_type) 152 - 153 - self.assertEqual(nested_msg2, msg2.fields_by_name[ 154 - 'nested_factory_2_message'].message_type) 155 - self.assertEqual(nested_enum2, msg2.fields_by_name[ 156 - 'nested_factory_2_enum'].enum_type) 157 - 158 - self.assertTrue(msg2.fields_by_name['int_with_default'].has_default_value) 159 - self.assertEqual( 160 - 1776, msg2.fields_by_name['int_with_default'].default_value) 161 - 162 - self.assertTrue( 163 - msg2.fields_by_name['double_with_default'].has_default_value) 164 - self.assertEqual( 165 - 9.99, msg2.fields_by_name['double_with_default'].default_value) 166 - 167 - self.assertTrue( 168 - msg2.fields_by_name['string_with_default'].has_default_value) 169 - self.assertEqual( 170 - 'hello world', msg2.fields_by_name['string_with_default'].default_value) 171 - 172 - self.assertTrue(msg2.fields_by_name['bool_with_default'].has_default_value) 173 - self.assertFalse(msg2.fields_by_name['bool_with_default'].default_value) 174 - 175 - self.assertTrue(msg2.fields_by_name['enum_with_default'].has_default_value) 176 - self.assertEqual( 177 - 1, msg2.fields_by_name['enum_with_default'].default_value) 178 - 179 - msg3 = self.pool.FindMessageTypeByName( 180 - 'google.protobuf.python.internal.Factory2Message.NestedFactory2Message') 181 - self.assertEqual(nested_msg2, msg3) 182 - 183 - self.assertTrue(msg2.fields_by_name['bytes_with_default'].has_default_value) 184 - self.assertEqual( 185 - b'a\xfb\x00c', 186 - msg2.fields_by_name['bytes_with_default'].default_value) 187 - 188 - self.assertEqual(1, len(msg2.oneofs)) 189 - self.assertEqual(1, len(msg2.oneofs_by_name)) 190 - self.assertEqual(2, len(msg2.oneofs[0].fields)) 191 - for name in ['oneof_int', 'oneof_string']: 192 - self.assertEqual(msg2.oneofs[0], 193 - msg2.fields_by_name[name].containing_oneof) 194 - self.assertIn(msg2.fields_by_name[name], msg2.oneofs[0].fields) 195 - 196 - def testFindMessageTypeByNameFailure(self): 197 - with self.assertRaises(KeyError): 198 - self.pool.FindMessageTypeByName('Does not exist') 199 - 200 - def testFindEnumTypeByName(self): 201 - enum1 = self.pool.FindEnumTypeByName( 202 - 'google.protobuf.python.internal.Factory1Enum') 203 - self.assertIsInstance(enum1, descriptor.EnumDescriptor) 204 - self.assertEqual(0, enum1.values_by_name['FACTORY_1_VALUE_0'].number) 205 - self.assertEqual(1, enum1.values_by_name['FACTORY_1_VALUE_1'].number) 206 - self.assertFalse(enum1.has_options) 207 - 208 - nested_enum1 = self.pool.FindEnumTypeByName( 209 - 'google.protobuf.python.internal.Factory1Message.NestedFactory1Enum') 210 - self.assertIsInstance(nested_enum1, descriptor.EnumDescriptor) 211 - self.assertEqual( 212 - 0, nested_enum1.values_by_name['NESTED_FACTORY_1_VALUE_0'].number) 213 - self.assertEqual( 214 - 1, nested_enum1.values_by_name['NESTED_FACTORY_1_VALUE_1'].number) 215 - 216 - enum2 = self.pool.FindEnumTypeByName( 217 - 'google.protobuf.python.internal.Factory2Enum') 218 - self.assertIsInstance(enum2, descriptor.EnumDescriptor) 219 - self.assertEqual(0, enum2.values_by_name['FACTORY_2_VALUE_0'].number) 220 - self.assertEqual(1, enum2.values_by_name['FACTORY_2_VALUE_1'].number) 221 - 222 - nested_enum2 = self.pool.FindEnumTypeByName( 223 - 'google.protobuf.python.internal.Factory2Message.NestedFactory2Enum') 224 - self.assertIsInstance(nested_enum2, descriptor.EnumDescriptor) 225 - self.assertEqual( 226 - 0, nested_enum2.values_by_name['NESTED_FACTORY_2_VALUE_0'].number) 227 - self.assertEqual( 228 - 1, nested_enum2.values_by_name['NESTED_FACTORY_2_VALUE_1'].number) 229 - 230 - def testFindEnumTypeByNameFailure(self): 231 - with self.assertRaises(KeyError): 232 - self.pool.FindEnumTypeByName('Does not exist') 233 - 234 - def testFindFieldByName(self): 235 - field = self.pool.FindFieldByName( 236 - 'google.protobuf.python.internal.Factory1Message.list_value') 237 - self.assertEqual(field.name, 'list_value') 238 - self.assertEqual(field.label, field.LABEL_REPEATED) 239 - self.assertFalse(field.has_options) 240 - 241 - with self.assertRaises(KeyError): 242 - self.pool.FindFieldByName('Does not exist') 243 - 244 - def testFindExtensionByName(self): 245 - # An extension defined in a message. 246 - extension = self.pool.FindExtensionByName( 247 - 'google.protobuf.python.internal.Factory2Message.one_more_field') 248 - self.assertEqual(extension.name, 'one_more_field') 249 - # An extension defined at file scope. 250 - extension = self.pool.FindExtensionByName( 251 - 'google.protobuf.python.internal.another_field') 252 - self.assertEqual(extension.name, 'another_field') 253 - self.assertEqual(extension.number, 1002) 254 - with self.assertRaises(KeyError): 255 - self.pool.FindFieldByName('Does not exist') 256 - 257 - def testFindAllExtensions(self): 258 - factory1_message = self.pool.FindMessageTypeByName( 259 - 'google.protobuf.python.internal.Factory1Message') 260 - factory2_message = self.pool.FindMessageTypeByName( 261 - 'google.protobuf.python.internal.Factory2Message') 262 - # An extension defined in a message. 263 - one_more_field = factory2_message.extensions_by_name['one_more_field'] 264 - self.pool.AddExtensionDescriptor(one_more_field) 265 - # An extension defined at file scope. 266 - factory_test2 = self.pool.FindFileByName( 267 - 'google/protobuf/internal/factory_test2.proto') 268 - another_field = factory_test2.extensions_by_name['another_field'] 269 - self.pool.AddExtensionDescriptor(another_field) 270 - 271 - extensions = self.pool.FindAllExtensions(factory1_message) 272 - expected_extension_numbers = set([one_more_field, another_field]) 273 - self.assertEqual(expected_extension_numbers, set(extensions)) 274 - # Verify that mutating the returned list does not affect the pool. 275 - extensions.append('unexpected_element') 276 - # Get the extensions again, the returned value does not contain the 277 - # 'unexpected_element'. 278 - extensions = self.pool.FindAllExtensions(factory1_message) 279 - self.assertEqual(expected_extension_numbers, set(extensions)) 280 - 281 - def testFindExtensionByNumber(self): 282 - factory1_message = self.pool.FindMessageTypeByName( 283 - 'google.protobuf.python.internal.Factory1Message') 284 - factory2_message = self.pool.FindMessageTypeByName( 285 - 'google.protobuf.python.internal.Factory2Message') 286 - # An extension defined in a message. 287 - one_more_field = factory2_message.extensions_by_name['one_more_field'] 288 - self.pool.AddExtensionDescriptor(one_more_field) 289 - # An extension defined at file scope. 290 - factory_test2 = self.pool.FindFileByName( 291 - 'google/protobuf/internal/factory_test2.proto') 292 - another_field = factory_test2.extensions_by_name['another_field'] 293 - self.pool.AddExtensionDescriptor(another_field) 294 - 295 - # An extension defined in a message. 296 - extension = self.pool.FindExtensionByNumber(factory1_message, 1001) 297 - self.assertEqual(extension.name, 'one_more_field') 298 - # An extension defined at file scope. 299 - extension = self.pool.FindExtensionByNumber(factory1_message, 1002) 300 - self.assertEqual(extension.name, 'another_field') 301 - with self.assertRaises(KeyError): 302 - extension = self.pool.FindExtensionByNumber(factory1_message, 1234567) 303 - 304 - def testExtensionsAreNotFields(self): 305 - with self.assertRaises(KeyError): 306 - self.pool.FindFieldByName('google.protobuf.python.internal.another_field') 307 - with self.assertRaises(KeyError): 308 - self.pool.FindFieldByName( 309 - 'google.protobuf.python.internal.Factory2Message.one_more_field') 310 - with self.assertRaises(KeyError): 311 - self.pool.FindExtensionByName( 312 - 'google.protobuf.python.internal.Factory1Message.list_value') 313 - 314 - def testUserDefinedDB(self): 315 - db = descriptor_database.DescriptorDatabase() 316 - self.pool = descriptor_pool.DescriptorPool(db) 317 - db.Add(self.factory_test1_fd) 318 - db.Add(self.factory_test2_fd) 319 - self.testFindMessageTypeByName() 320 - 321 - def testAddSerializedFile(self): 322 - self.pool = descriptor_pool.DescriptorPool() 323 - self.pool.AddSerializedFile(self.factory_test1_fd.SerializeToString()) 324 - self.pool.AddSerializedFile(self.factory_test2_fd.SerializeToString()) 325 - self.testFindMessageTypeByName() 326 - 327 - def testComplexNesting(self): 328 - more_messages_desc = descriptor_pb2.FileDescriptorProto.FromString( 329 - more_messages_pb2.DESCRIPTOR.serialized_pb) 330 - test1_desc = descriptor_pb2.FileDescriptorProto.FromString( 331 - descriptor_pool_test1_pb2.DESCRIPTOR.serialized_pb) 332 - test2_desc = descriptor_pb2.FileDescriptorProto.FromString( 333 - descriptor_pool_test2_pb2.DESCRIPTOR.serialized_pb) 334 - self.pool.Add(more_messages_desc) 335 - self.pool.Add(test1_desc) 336 - self.pool.Add(test2_desc) 337 - TEST1_FILE.CheckFile(self, self.pool) 338 - TEST2_FILE.CheckFile(self, self.pool) 339 - 340 - 341 - def testEnumDefaultValue(self): 342 - """Test the default value of enums which don't start at zero.""" 343 - def _CheckDefaultValue(file_descriptor): 344 - default_value = (file_descriptor 345 - .message_types_by_name['DescriptorPoolTest1'] 346 - .fields_by_name['nested_enum'] 347 - .default_value) 348 - self.assertEqual(default_value, 349 - descriptor_pool_test1_pb2.DescriptorPoolTest1.BETA) 350 - # First check what the generated descriptor contains. 351 - _CheckDefaultValue(descriptor_pool_test1_pb2.DESCRIPTOR) 352 - # Then check the generated pool. Normally this is the same descriptor. 353 - file_descriptor = symbol_database.Default().pool.FindFileByName( 354 - 'google/protobuf/internal/descriptor_pool_test1.proto') 355 - self.assertIs(file_descriptor, descriptor_pool_test1_pb2.DESCRIPTOR) 356 - _CheckDefaultValue(file_descriptor) 357 - 358 - # Then check the dynamic pool and its internal DescriptorDatabase. 359 - descriptor_proto = descriptor_pb2.FileDescriptorProto.FromString( 360 - descriptor_pool_test1_pb2.DESCRIPTOR.serialized_pb) 361 - self.pool.Add(descriptor_proto) 362 - # And do the same check as above 363 - file_descriptor = self.pool.FindFileByName( 364 - 'google/protobuf/internal/descriptor_pool_test1.proto') 365 - _CheckDefaultValue(file_descriptor) 366 - 367 - def testDefaultValueForCustomMessages(self): 368 - """Check the value returned by non-existent fields.""" 369 - def _CheckValueAndType(value, expected_value, expected_type): 370 - self.assertEqual(value, expected_value) 371 - self.assertIsInstance(value, expected_type) 372 - 373 - def _CheckDefaultValues(msg): 374 - try: 375 - int64 = long 376 - except NameError: # Python3 377 - int64 = int 378 - try: 379 - unicode_type = unicode 380 - except NameError: # Python3 381 - unicode_type = str 382 - _CheckValueAndType(msg.optional_int32, 0, int) 383 - _CheckValueAndType(msg.optional_uint64, 0, (int64, int)) 384 - _CheckValueAndType(msg.optional_float, 0, (float, int)) 385 - _CheckValueAndType(msg.optional_double, 0, (float, int)) 386 - _CheckValueAndType(msg.optional_bool, False, bool) 387 - _CheckValueAndType(msg.optional_string, u'', unicode_type) 388 - _CheckValueAndType(msg.optional_bytes, b'', bytes) 389 - _CheckValueAndType(msg.optional_nested_enum, msg.FOO, int) 390 - # First for the generated message 391 - _CheckDefaultValues(unittest_pb2.TestAllTypes()) 392 - # Then for a message built with from the DescriptorPool. 393 - pool = descriptor_pool.DescriptorPool() 394 - pool.Add(descriptor_pb2.FileDescriptorProto.FromString( 395 - unittest_import_public_pb2.DESCRIPTOR.serialized_pb)) 396 - pool.Add(descriptor_pb2.FileDescriptorProto.FromString( 397 - unittest_import_pb2.DESCRIPTOR.serialized_pb)) 398 - pool.Add(descriptor_pb2.FileDescriptorProto.FromString( 399 - unittest_pb2.DESCRIPTOR.serialized_pb)) 400 - message_class = message_factory.MessageFactory(pool).GetPrototype( 401 - pool.FindMessageTypeByName( 402 - unittest_pb2.TestAllTypes.DESCRIPTOR.full_name)) 403 - _CheckDefaultValues(message_class()) 404 - 405 - 406 - class ProtoFile(object): 407 - 408 - def __init__(self, name, package, messages, dependencies=None, 409 - public_dependencies=None): 410 - self.name = name 411 - self.package = package 412 - self.messages = messages 413 - self.dependencies = dependencies or [] 414 - self.public_dependencies = public_dependencies or [] 415 - 416 - def CheckFile(self, test, pool): 417 - file_desc = pool.FindFileByName(self.name) 418 - test.assertEqual(self.name, file_desc.name) 419 - test.assertEqual(self.package, file_desc.package) 420 - dependencies_names = [f.name for f in file_desc.dependencies] 421 - test.assertEqual(self.dependencies, dependencies_names) 422 - public_dependencies_names = [f.name for f in file_desc.public_dependencies] 423 - test.assertEqual(self.public_dependencies, public_dependencies_names) 424 - for name, msg_type in self.messages.items(): 425 - msg_type.CheckType(test, None, name, file_desc) 426 - 427 - 428 - class EnumType(object): 429 - 430 - def __init__(self, values): 431 - self.values = values 432 - 433 - def CheckType(self, test, msg_desc, name, file_desc): 434 - enum_desc = msg_desc.enum_types_by_name[name] 435 - test.assertEqual(name, enum_desc.name) 436 - expected_enum_full_name = '.'.join([msg_desc.full_name, name]) 437 - test.assertEqual(expected_enum_full_name, enum_desc.full_name) 438 - test.assertEqual(msg_desc, enum_desc.containing_type) 439 - test.assertEqual(file_desc, enum_desc.file) 440 - for index, (value, number) in enumerate(self.values): 441 - value_desc = enum_desc.values_by_name[value] 442 - test.assertEqual(value, value_desc.name) 443 - test.assertEqual(index, value_desc.index) 444 - test.assertEqual(number, value_desc.number) 445 - test.assertEqual(enum_desc, value_desc.type) 446 - test.assertIn(value, msg_desc.enum_values_by_name) 447 - 448 - 449 - class MessageType(object): 450 - 451 - def __init__(self, type_dict, field_list, is_extendable=False, 452 - extensions=None): 453 - self.type_dict = type_dict 454 - self.field_list = field_list 455 - self.is_extendable = is_extendable 456 - self.extensions = extensions or [] 457 - 458 - def CheckType(self, test, containing_type_desc, name, file_desc): 459 - if containing_type_desc is None: 460 - desc = file_desc.message_types_by_name[name] 461 - expected_full_name = '.'.join([file_desc.package, name]) 462 - else: 463 - desc = containing_type_desc.nested_types_by_name[name] 464 - expected_full_name = '.'.join([containing_type_desc.full_name, name]) 465 - 466 - test.assertEqual(name, desc.name) 467 - test.assertEqual(expected_full_name, desc.full_name) 468 - test.assertEqual(containing_type_desc, desc.containing_type) 469 - test.assertEqual(desc.file, file_desc) 470 - test.assertEqual(self.is_extendable, desc.is_extendable) 471 - for name, subtype in self.type_dict.items(): 472 - subtype.CheckType(test, desc, name, file_desc) 473 - 474 - for index, (name, field) in enumerate(self.field_list): 475 - field.CheckField(test, desc, name, index) 476 - 477 - for index, (name, field) in enumerate(self.extensions): 478 - field.CheckField(test, desc, name, index) 479 - 480 - 481 - class EnumField(object): 482 - 483 - def __init__(self, number, type_name, default_value): 484 - self.number = number 485 - self.type_name = type_name 486 - self.default_value = default_value 487 - 488 - def CheckField(self, test, msg_desc, name, index): 489 - field_desc = msg_desc.fields_by_name[name] 490 - enum_desc = msg_desc.enum_types_by_name[self.type_name] 491 - test.assertEqual(name, field_desc.name) 492 - expected_field_full_name = '.'.join([msg_desc.full_name, name]) 493 - test.assertEqual(expected_field_full_name, field_desc.full_name) 494 - test.assertEqual(index, field_desc.index) 495 - test.assertEqual(self.number, field_desc.number) 496 - test.assertEqual(descriptor.FieldDescriptor.TYPE_ENUM, field_desc.type) 497 - test.assertEqual(descriptor.FieldDescriptor.CPPTYPE_ENUM, 498 - field_desc.cpp_type) 499 - test.assertTrue(field_desc.has_default_value) 500 - test.assertEqual(enum_desc.values_by_name[self.default_value].number, 501 - field_desc.default_value) 502 - test.assertFalse(enum_desc.values_by_name[self.default_value].has_options) 503 - test.assertEqual(msg_desc, field_desc.containing_type) 504 - test.assertEqual(enum_desc, field_desc.enum_type) 505 - 506 - 507 - class MessageField(object): 508 - 509 - def __init__(self, number, type_name): 510 - self.number = number 511 - self.type_name = type_name 512 - 513 - def CheckField(self, test, msg_desc, name, index): 514 - field_desc = msg_desc.fields_by_name[name] 515 - field_type_desc = msg_desc.nested_types_by_name[self.type_name] 516 - test.assertEqual(name, field_desc.name) 517 - expected_field_full_name = '.'.join([msg_desc.full_name, name]) 518 - test.assertEqual(expected_field_full_name, field_desc.full_name) 519 - test.assertEqual(index, field_desc.index) 520 - test.assertEqual(self.number, field_desc.number) 521 - test.assertEqual(descriptor.FieldDescriptor.TYPE_MESSAGE, field_desc.type) 522 - test.assertEqual(descriptor.FieldDescriptor.CPPTYPE_MESSAGE, 523 - field_desc.cpp_type) 524 - test.assertFalse(field_desc.has_default_value) 525 - test.assertEqual(msg_desc, field_desc.containing_type) 526 - test.assertEqual(field_type_desc, field_desc.message_type) 527 - 528 - 529 - class StringField(object): 530 - 531 - def __init__(self, number, default_value): 532 - self.number = number 533 - self.default_value = default_value 534 - 535 - def CheckField(self, test, msg_desc, name, index): 536 - field_desc = msg_desc.fields_by_name[name] 537 - test.assertEqual(name, field_desc.name) 538 - expected_field_full_name = '.'.join([msg_desc.full_name, name]) 539 - test.assertEqual(expected_field_full_name, field_desc.full_name) 540 - test.assertEqual(index, field_desc.index) 541 - test.assertEqual(self.number, field_desc.number) 542 - test.assertEqual(descriptor.FieldDescriptor.TYPE_STRING, field_desc.type) 543 - test.assertEqual(descriptor.FieldDescriptor.CPPTYPE_STRING, 544 - field_desc.cpp_type) 545 - test.assertTrue(field_desc.has_default_value) 546 - test.assertEqual(self.default_value, field_desc.default_value) 547 - 548 - 549 - class ExtensionField(object): 550 - 551 - def __init__(self, number, extended_type): 552 - self.number = number 553 - self.extended_type = extended_type 554 - 555 - def CheckField(self, test, msg_desc, name, index): 556 - field_desc = msg_desc.extensions_by_name[name] 557 - test.assertEqual(name, field_desc.name) 558 - expected_field_full_name = '.'.join([msg_desc.full_name, name]) 559 - test.assertEqual(expected_field_full_name, field_desc.full_name) 560 - test.assertEqual(self.number, field_desc.number) 561 - test.assertEqual(index, field_desc.index) 562 - test.assertEqual(descriptor.FieldDescriptor.TYPE_MESSAGE, field_desc.type) 563 - test.assertEqual(descriptor.FieldDescriptor.CPPTYPE_MESSAGE, 564 - field_desc.cpp_type) 565 - test.assertFalse(field_desc.has_default_value) 566 - test.assertTrue(field_desc.is_extension) 567 - test.assertEqual(msg_desc, field_desc.extension_scope) 568 - test.assertEqual(msg_desc, field_desc.message_type) 569 - test.assertEqual(self.extended_type, field_desc.containing_type.name) 570 - 571 - 572 - class AddDescriptorTest(unittest.TestCase): 573 - 574 - def _TestMessage(self, prefix): 575 - pool = descriptor_pool.DescriptorPool() 576 - pool.AddDescriptor(unittest_pb2.TestAllTypes.DESCRIPTOR) 577 - self.assertEqual( 578 - 'protobuf_unittest.TestAllTypes', 579 - pool.FindMessageTypeByName( 580 - prefix + 'protobuf_unittest.TestAllTypes').full_name) 581 - 582 - # AddDescriptor is not recursive. 583 - with self.assertRaises(KeyError): 584 - pool.FindMessageTypeByName( 585 - prefix + 'protobuf_unittest.TestAllTypes.NestedMessage') 586 - 587 - pool.AddDescriptor(unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR) 588 - self.assertEqual( 589 - 'protobuf_unittest.TestAllTypes.NestedMessage', 590 - pool.FindMessageTypeByName( 591 - prefix + 'protobuf_unittest.TestAllTypes.NestedMessage').full_name) 592 - 593 - # Files are implicitly also indexed when messages are added. 594 - self.assertEqual( 595 - 'google/protobuf/unittest.proto', 596 - pool.FindFileByName( 597 - 'google/protobuf/unittest.proto').name) 598 - 599 - self.assertEqual( 600 - 'google/protobuf/unittest.proto', 601 - pool.FindFileContainingSymbol( 602 - prefix + 'protobuf_unittest.TestAllTypes.NestedMessage').name) 603 - 604 - @unittest.skipIf(api_implementation.Type() == 'cpp', 605 - 'With the cpp implementation, Add() must be called first') 606 - def testMessage(self): 607 - self._TestMessage('') 608 - self._TestMessage('.') 609 - 610 - def _TestEnum(self, prefix): 611 - pool = descriptor_pool.DescriptorPool() 612 - pool.AddEnumDescriptor(unittest_pb2.ForeignEnum.DESCRIPTOR) 613 - self.assertEqual( 614 - 'protobuf_unittest.ForeignEnum', 615 - pool.FindEnumTypeByName( 616 - prefix + 'protobuf_unittest.ForeignEnum').full_name) 617 - 618 - # AddEnumDescriptor is not recursive. 619 - with self.assertRaises(KeyError): 620 - pool.FindEnumTypeByName( 621 - prefix + 'protobuf_unittest.ForeignEnum.NestedEnum') 622 - 623 - pool.AddEnumDescriptor(unittest_pb2.TestAllTypes.NestedEnum.DESCRIPTOR) 624 - self.assertEqual( 625 - 'protobuf_unittest.TestAllTypes.NestedEnum', 626 - pool.FindEnumTypeByName( 627 - prefix + 'protobuf_unittest.TestAllTypes.NestedEnum').full_name) 628 - 629 - # Files are implicitly also indexed when enums are added. 630 - self.assertEqual( 631 - 'google/protobuf/unittest.proto', 632 - pool.FindFileByName( 633 - 'google/protobuf/unittest.proto').name) 634 - 635 - self.assertEqual( 636 - 'google/protobuf/unittest.proto', 637 - pool.FindFileContainingSymbol( 638 - prefix + 'protobuf_unittest.TestAllTypes.NestedEnum').name) 639 - 640 - @unittest.skipIf(api_implementation.Type() == 'cpp', 641 - 'With the cpp implementation, Add() must be called first') 642 - def testEnum(self): 643 - self._TestEnum('') 644 - self._TestEnum('.') 645 - 646 - @unittest.skipIf(api_implementation.Type() == 'cpp', 647 - 'With the cpp implementation, Add() must be called first') 648 - def testFile(self): 649 - pool = descriptor_pool.DescriptorPool() 650 - pool.AddFileDescriptor(unittest_pb2.DESCRIPTOR) 651 - self.assertEqual( 652 - 'google/protobuf/unittest.proto', 653 - pool.FindFileByName( 654 - 'google/protobuf/unittest.proto').name) 655 - 656 - # AddFileDescriptor is not recursive; messages and enums within files must 657 - # be explicitly registered. 658 - with self.assertRaises(KeyError): 659 - pool.FindFileContainingSymbol( 660 - 'protobuf_unittest.TestAllTypes') 661 - 662 - def testEmptyDescriptorPool(self): 663 - # Check that an empty DescriptorPool() contains no messages. 664 - pool = descriptor_pool.DescriptorPool() 665 - proto_file_name = descriptor_pb2.DESCRIPTOR.name 666 - self.assertRaises(KeyError, pool.FindFileByName, proto_file_name) 667 - # Add the above file to the pool 668 - file_descriptor = descriptor_pb2.FileDescriptorProto() 669 - descriptor_pb2.DESCRIPTOR.CopyToProto(file_descriptor) 670 - pool.Add(file_descriptor) 671 - # Now it exists. 672 - self.assertTrue(pool.FindFileByName(proto_file_name)) 673 - 674 - def testCustomDescriptorPool(self): 675 - # Create a new pool, and add a file descriptor. 676 - pool = descriptor_pool.DescriptorPool() 677 - file_desc = descriptor_pb2.FileDescriptorProto( 678 - name='some/file.proto', package='package') 679 - file_desc.message_type.add(name='Message') 680 - pool.Add(file_desc) 681 - self.assertEqual(pool.FindFileByName('some/file.proto').name, 682 - 'some/file.proto') 683 - self.assertEqual(pool.FindMessageTypeByName('package.Message').name, 684 - 'Message') 685 - 686 - def testFileDescriptorOptionsWithCustomDescriptorPool(self): 687 - # Create a descriptor pool, and add a new FileDescriptorProto to it. 688 - pool = descriptor_pool.DescriptorPool() 689 - file_name = 'file_descriptor_options_with_custom_descriptor_pool.proto' 690 - file_descriptor_proto = descriptor_pb2.FileDescriptorProto(name=file_name) 691 - extension_id = file_options_test_pb2.foo_options 692 - file_descriptor_proto.options.Extensions[extension_id].foo_name = 'foo' 693 - pool.Add(file_descriptor_proto) 694 - # The options set on the FileDescriptorProto should be available in the 695 - # descriptor even if they contain extensions that cannot be deserialized 696 - # using the pool. 697 - file_descriptor = pool.FindFileByName(file_name) 698 - options = file_descriptor.GetOptions() 699 - self.assertEqual('foo', options.Extensions[extension_id].foo_name) 700 - # The object returned by GetOptions() is cached. 701 - self.assertIs(options, file_descriptor.GetOptions()) 702 - 703 - 704 - @unittest.skipIf( 705 - api_implementation.Type() != 'cpp', 706 - 'default_pool is only supported by the C++ implementation') 707 - class DefaultPoolTest(unittest.TestCase): 708 - 709 - def testFindMethods(self): 710 - # pylint: disable=g-import-not-at-top 711 - from google.protobuf.pyext import _message 712 - pool = _message.default_pool 713 - self.assertIs( 714 - pool.FindFileByName('google/protobuf/unittest.proto'), 715 - unittest_pb2.DESCRIPTOR) 716 - self.assertIs( 717 - pool.FindMessageTypeByName('protobuf_unittest.TestAllTypes'), 718 - unittest_pb2.TestAllTypes.DESCRIPTOR) 719 - self.assertIs( 720 - pool.FindFieldByName('protobuf_unittest.TestAllTypes.optional_int32'), 721 - unittest_pb2.TestAllTypes.DESCRIPTOR.fields_by_name['optional_int32']) 722 - self.assertIs( 723 - pool.FindExtensionByName('protobuf_unittest.optional_int32_extension'), 724 - unittest_pb2.DESCRIPTOR.extensions_by_name['optional_int32_extension']) 725 - self.assertIs( 726 - pool.FindEnumTypeByName('protobuf_unittest.ForeignEnum'), 727 - unittest_pb2.ForeignEnum.DESCRIPTOR) 728 - self.assertIs( 729 - pool.FindOneofByName('protobuf_unittest.TestAllTypes.oneof_field'), 730 - unittest_pb2.TestAllTypes.DESCRIPTOR.oneofs_by_name['oneof_field']) 731 - 732 - def testAddFileDescriptor(self): 733 - # pylint: disable=g-import-not-at-top 734 - from google.protobuf.pyext import _message 735 - pool = _message.default_pool 736 - file_desc = descriptor_pb2.FileDescriptorProto(name='some/file.proto') 737 - pool.Add(file_desc) 738 - pool.AddSerializedFile(file_desc.SerializeToString()) 739 - 740 - 741 - TEST1_FILE = ProtoFile( 742 - 'google/protobuf/internal/descriptor_pool_test1.proto', 743 - 'google.protobuf.python.internal', 744 - { 745 - 'DescriptorPoolTest1': MessageType({ 746 - 'NestedEnum': EnumType([('ALPHA', 1), ('BETA', 2)]), 747 - 'NestedMessage': MessageType({ 748 - 'NestedEnum': EnumType([('EPSILON', 5), ('ZETA', 6)]), 749 - 'DeepNestedMessage': MessageType({ 750 - 'NestedEnum': EnumType([('ETA', 7), ('THETA', 8)]), 751 - }, [ 752 - ('nested_enum', EnumField(1, 'NestedEnum', 'ETA')), 753 - ('nested_field', StringField(2, 'theta')), 754 - ]), 755 - }, [ 756 - ('nested_enum', EnumField(1, 'NestedEnum', 'ZETA')), 757 - ('nested_field', StringField(2, 'beta')), 758 - ('deep_nested_message', MessageField(3, 'DeepNestedMessage')), 759 - ]) 760 - }, [ 761 - ('nested_enum', EnumField(1, 'NestedEnum', 'BETA')), 762 - ('nested_message', MessageField(2, 'NestedMessage')), 763 - ], is_extendable=True), 764 - 765 - 'DescriptorPoolTest2': MessageType({ 766 - 'NestedEnum': EnumType([('GAMMA', 3), ('DELTA', 4)]), 767 - 'NestedMessage': MessageType({ 768 - 'NestedEnum': EnumType([('IOTA', 9), ('KAPPA', 10)]), 769 - 'DeepNestedMessage': MessageType({ 770 - 'NestedEnum': EnumType([('LAMBDA', 11), ('MU', 12)]), 771 - }, [ 772 - ('nested_enum', EnumField(1, 'NestedEnum', 'MU')), 773 - ('nested_field', StringField(2, 'lambda')), 774 - ]), 775 - }, [ 776 - ('nested_enum', EnumField(1, 'NestedEnum', 'IOTA')), 777 - ('nested_field', StringField(2, 'delta')), 778 - ('deep_nested_message', MessageField(3, 'DeepNestedMessage')), 779 - ]) 780 - }, [ 781 - ('nested_enum', EnumField(1, 'NestedEnum', 'GAMMA')), 782 - ('nested_message', MessageField(2, 'NestedMessage')), 783 - ]), 784 - }) 785 - 786 - 787 - TEST2_FILE = ProtoFile( 788 - 'google/protobuf/internal/descriptor_pool_test2.proto', 789 - 'google.protobuf.python.internal', 790 - { 791 - 'DescriptorPoolTest3': MessageType({ 792 - 'NestedEnum': EnumType([('NU', 13), ('XI', 14)]), 793 - 'NestedMessage': MessageType({ 794 - 'NestedEnum': EnumType([('OMICRON', 15), ('PI', 16)]), 795 - 'DeepNestedMessage': MessageType({ 796 - 'NestedEnum': EnumType([('RHO', 17), ('SIGMA', 18)]), 797 - }, [ 798 - ('nested_enum', EnumField(1, 'NestedEnum', 'RHO')), 799 - ('nested_field', StringField(2, 'sigma')), 800 - ]), 801 - }, [ 802 - ('nested_enum', EnumField(1, 'NestedEnum', 'PI')), 803 - ('nested_field', StringField(2, 'nu')), 804 - ('deep_nested_message', MessageField(3, 'DeepNestedMessage')), 805 - ]) 806 - }, [ 807 - ('nested_enum', EnumField(1, 'NestedEnum', 'XI')), 808 - ('nested_message', MessageField(2, 'NestedMessage')), 809 - ], extensions=[ 810 - ('descriptor_pool_test', 811 - ExtensionField(1001, 'DescriptorPoolTest1')), 812 - ]), 813 - }, 814 - dependencies=['google/protobuf/internal/descriptor_pool_test1.proto', 815 - 'google/protobuf/internal/more_messages.proto'], 816 - public_dependencies=['google/protobuf/internal/more_messages.proto']) 817 - 818 - 819 - if __name__ == '__main__': 820 - unittest.main() 821 -