1#!/usr/bin/env python 2# 3# Copyright 2010 Google Inc. 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16# 17 18# pylint: disable=too-many-lines 19 20"""Stand-alone implementation of in memory protocol messages. 21 22Public Classes: 23 Enum: Represents an enumerated type. 24 Variant: Hint for wire format to determine how to serialize. 25 Message: Base class for user defined messages. 26 IntegerField: Field for integer values. 27 FloatField: Field for float values. 28 BooleanField: Field for boolean values. 29 BytesField: Field for binary string values. 30 StringField: Field for UTF-8 string values. 31 MessageField: Field for other message type values. 32 EnumField: Field for enumerated type values. 33 34Public Exceptions (indentation indications class hierarchy): 35 EnumDefinitionError: Raised when enumeration is incorrectly defined. 36 FieldDefinitionError: Raised when field is incorrectly defined. 37 InvalidVariantError: Raised when variant is not compatible with field type. 38 InvalidDefaultError: Raised when default is not compatiable with field. 39 InvalidNumberError: Raised when field number is out of range or reserved. 40 MessageDefinitionError: Raised when message is incorrectly defined. 41 DuplicateNumberError: Raised when field has duplicate number with another. 42 ValidationError: Raised when a message or field is not valid. 43 DefinitionNotFoundError: Raised when definition not found. 44""" 45import types 46import weakref 47 48import six 49 50from apitools.base.protorpclite import util 51 52__all__ = [ 53 'MAX_ENUM_VALUE', 54 'MAX_FIELD_NUMBER', 55 'FIRST_RESERVED_FIELD_NUMBER', 56 'LAST_RESERVED_FIELD_NUMBER', 57 58 'Enum', 59 'Field', 60 'FieldList', 61 'Variant', 62 'Message', 63 'IntegerField', 64 'FloatField', 65 'BooleanField', 66 'BytesField', 67 'StringField', 68 'MessageField', 69 'EnumField', 70 'find_definition', 71 72 'Error', 73 'DecodeError', 74 'EncodeError', 75 'EnumDefinitionError', 76 'FieldDefinitionError', 77 'InvalidVariantError', 78 'InvalidDefaultError', 79 'InvalidNumberError', 80 'MessageDefinitionError', 81 'DuplicateNumberError', 82 'ValidationError', 83 'DefinitionNotFoundError', 84] 85 86# pylint:disable=attribute-defined-outside-init 87# pylint:disable=protected-access 88 89 90# TODO(rafek): Add extended module test to ensure all exceptions 91# in services extends Error. 92Error = util.Error 93 94 95class EnumDefinitionError(Error): 96 """Enumeration definition error.""" 97 98 99class FieldDefinitionError(Error): 100 """Field definition error.""" 101 102 103class InvalidVariantError(FieldDefinitionError): 104 """Invalid variant provided to field.""" 105 106 107class InvalidDefaultError(FieldDefinitionError): 108 """Invalid default provided to field.""" 109 110 111class InvalidNumberError(FieldDefinitionError): 112 """Invalid number provided to field.""" 113 114 115class MessageDefinitionError(Error): 116 """Message definition error.""" 117 118 119class DuplicateNumberError(Error): 120 """Duplicate number assigned to field.""" 121 122 123class DefinitionNotFoundError(Error): 124 """Raised when definition is not found.""" 125 126 127class DecodeError(Error): 128 """Error found decoding message from encoded form.""" 129 130 131class EncodeError(Error): 132 """Error found when encoding message.""" 133 134 135class ValidationError(Error): 136 """Invalid value for message error.""" 137 138 def __str__(self): 139 """Prints string with field name if present on exception.""" 140 return Error.__str__(self) 141 142 143# Attributes that are reserved by a class definition that 144# may not be used by either Enum or Message class definitions. 145_RESERVED_ATTRIBUTE_NAMES = frozenset( 146 ['__module__', '__doc__', '__qualname__']) 147 148_POST_INIT_FIELD_ATTRIBUTE_NAMES = frozenset( 149 ['name', 150 '_message_definition', 151 '_MessageField__type', 152 '_EnumField__type', 153 '_EnumField__resolved_default']) 154 155_POST_INIT_ATTRIBUTE_NAMES = frozenset( 156 ['_message_definition']) 157 158# Maximum enumeration value as defined by the protocol buffers standard. 159# All enum values must be less than or equal to this value. 160MAX_ENUM_VALUE = (2 ** 29) - 1 161 162# Maximum field number as defined by the protocol buffers standard. 163# All field numbers must be less than or equal to this value. 164MAX_FIELD_NUMBER = (2 ** 29) - 1 165 166# Field numbers between 19000 and 19999 inclusive are reserved by the 167# protobuf protocol and may not be used by fields. 168FIRST_RESERVED_FIELD_NUMBER = 19000 169LAST_RESERVED_FIELD_NUMBER = 19999 170 171 172# pylint: disable=no-value-for-parameter 173class _DefinitionClass(type): 174 """Base meta-class used for definition meta-classes. 175 176 The Enum and Message definition classes share some basic functionality. 177 Both of these classes may be contained by a Message definition. After 178 initialization, neither class may have attributes changed 179 except for the protected _message_definition attribute, and that attribute 180 may change only once. 181 """ 182 183 __initialized = False # pylint:disable=invalid-name 184 185 def __init__(cls, name, bases, dct): 186 """Constructor.""" 187 type.__init__(cls, name, bases, dct) 188 # Base classes may never be initialized. 189 if cls.__bases__ != (object,): 190 cls.__initialized = True 191 192 def message_definition(cls): 193 """Get outer Message definition that contains this definition. 194 195 Returns: 196 Containing Message definition if definition is contained within one, 197 else None. 198 """ 199 try: 200 return cls._message_definition() 201 except AttributeError: 202 return None 203 204 def __setattr__(cls, name, value): 205 """Overridden to avoid setting variables after init. 206 207 Setting attributes on a class must work during the period of 208 initialization to set the enumation value class variables and 209 build the name/number maps. Once __init__ has set the 210 __initialized flag to True prohibits setting any more values 211 on the class. The class is in effect frozen. 212 213 Args: 214 name: Name of value to set. 215 value: Value to set. 216 217 """ 218 if cls.__initialized and name not in _POST_INIT_ATTRIBUTE_NAMES: 219 raise AttributeError('May not change values: %s' % name) 220 else: 221 type.__setattr__(cls, name, value) 222 223 def __delattr__(cls, name): 224 """Overridden so that cannot delete varaibles on definition classes.""" 225 raise TypeError('May not delete attributes on definition class') 226 227 def definition_name(cls): 228 """Helper method for creating definition name. 229 230 Names will be generated to include the classes package name, 231 scope (if the class is nested in another definition) and class 232 name. 233 234 By default, the package name for a definition is derived from 235 its module name. However, this value can be overriden by 236 placing a 'package' attribute in the module that contains the 237 definition class. For example: 238 239 package = 'some.alternate.package' 240 241 class MyMessage(Message): 242 ... 243 244 >>> MyMessage.definition_name() 245 some.alternate.package.MyMessage 246 247 Returns: 248 Dot-separated fully qualified name of definition. 249 250 """ 251 outer_definition_name = cls.outer_definition_name() 252 if outer_definition_name is None: 253 return six.text_type(cls.__name__) 254 return u'%s.%s' % (outer_definition_name, cls.__name__) 255 256 def outer_definition_name(cls): 257 """Helper method for creating outer definition name. 258 259 Returns: 260 If definition is nested, will return the outer definitions 261 name, else the package name. 262 263 """ 264 outer_definition = cls.message_definition() 265 if not outer_definition: 266 return util.get_package_for_module(cls.__module__) 267 return outer_definition.definition_name() 268 269 def definition_package(cls): 270 """Helper method for creating creating the package of a definition. 271 272 Returns: 273 Name of package that definition belongs to. 274 """ 275 outer_definition = cls.message_definition() 276 if not outer_definition: 277 return util.get_package_for_module(cls.__module__) 278 return outer_definition.definition_package() 279 280 281class _EnumClass(_DefinitionClass): 282 """Meta-class used for defining the Enum base class. 283 284 Meta-class enables very specific behavior for any defined Enum 285 class. All attributes defined on an Enum sub-class must be integers. 286 Each attribute defined on an Enum sub-class is translated 287 into an instance of that sub-class, with the name of the attribute 288 as its name, and the number provided as its value. It also ensures 289 that only one level of Enum class hierarchy is possible. In other 290 words it is not possible to delcare sub-classes of sub-classes of 291 Enum. 292 293 This class also defines some functions in order to restrict the 294 behavior of the Enum class and its sub-classes. It is not possible 295 to change the behavior of the Enum class in later classes since 296 any new classes may be defined with only integer values, and no methods. 297 """ 298 299 def __init__(cls, name, bases, dct): 300 # Can only define one level of sub-classes below Enum. 301 if not (bases == (object,) or bases == (Enum,)): 302 raise EnumDefinitionError( 303 'Enum type %s may only inherit from Enum' % name) 304 305 cls.__by_number = {} 306 cls.__by_name = {} 307 308 # Enum base class does not need to be initialized or locked. 309 if bases != (object,): 310 # Replace integer with number. 311 for attribute, value in dct.items(): 312 313 # Module will be in every enum class. 314 if attribute in _RESERVED_ATTRIBUTE_NAMES: 315 continue 316 317 # Reject anything that is not an int. 318 if not isinstance(value, six.integer_types): 319 raise EnumDefinitionError( 320 'May only use integers in Enum definitions. ' 321 'Found: %s = %s' % 322 (attribute, value)) 323 324 # Protocol buffer standard recommends non-negative values. 325 # Reject negative values. 326 if value < 0: 327 raise EnumDefinitionError( 328 'Must use non-negative enum values. Found: %s = %d' % 329 (attribute, value)) 330 331 if value > MAX_ENUM_VALUE: 332 raise EnumDefinitionError( 333 'Must use enum values less than or equal %d. ' 334 'Found: %s = %d' % 335 (MAX_ENUM_VALUE, attribute, value)) 336 337 if value in cls.__by_number: 338 raise EnumDefinitionError( 339 'Value for %s = %d is already defined: %s' % 340 (attribute, value, cls.__by_number[value].name)) 341 342 # Create enum instance and list in new Enum type. 343 instance = object.__new__(cls) 344 # pylint:disable=non-parent-init-called 345 cls.__init__(instance, attribute, value) 346 cls.__by_name[instance.name] = instance 347 cls.__by_number[instance.number] = instance 348 setattr(cls, attribute, instance) 349 350 _DefinitionClass.__init__(cls, name, bases, dct) 351 352 def __iter__(cls): 353 """Iterate over all values of enum. 354 355 Yields: 356 Enumeration instances of the Enum class in arbitrary order. 357 """ 358 return iter(cls.__by_number.values()) 359 360 def names(cls): 361 """Get all names for Enum. 362 363 Returns: 364 An iterator for names of the enumeration in arbitrary order. 365 """ 366 return cls.__by_name.keys() 367 368 def numbers(cls): 369 """Get all numbers for Enum. 370 371 Returns: 372 An iterator for all numbers of the enumeration in arbitrary order. 373 """ 374 return cls.__by_number.keys() 375 376 def lookup_by_name(cls, name): 377 """Look up Enum by name. 378 379 Args: 380 name: Name of enum to find. 381 382 Returns: 383 Enum sub-class instance of that value. 384 """ 385 return cls.__by_name[name] 386 387 def lookup_by_number(cls, number): 388 """Look up Enum by number. 389 390 Args: 391 number: Number of enum to find. 392 393 Returns: 394 Enum sub-class instance of that value. 395 """ 396 return cls.__by_number[number] 397 398 def __len__(cls): 399 return len(cls.__by_name) 400 401 402class Enum(six.with_metaclass(_EnumClass, object)): 403 """Base class for all enumerated types.""" 404 405 __slots__ = set(('name', 'number')) 406 407 def __new__(cls, index): 408 """Acts as look-up routine after class is initialized. 409 410 The purpose of overriding __new__ is to provide a way to treat 411 Enum subclasses as casting types, similar to how the int type 412 functions. A program can pass a string or an integer and this 413 method with "convert" that value in to an appropriate Enum instance. 414 415 Args: 416 index: Name or number to look up. During initialization 417 this is always the name of the new enum value. 418 419 Raises: 420 TypeError: When an inappropriate index value is passed provided. 421 """ 422 # If is enum type of this class, return it. 423 if isinstance(index, cls): 424 return index 425 426 # If number, look up by number. 427 if isinstance(index, six.integer_types): 428 try: 429 return cls.lookup_by_number(index) 430 except KeyError: 431 pass 432 433 # If name, look up by name. 434 if isinstance(index, six.string_types): 435 try: 436 return cls.lookup_by_name(index) 437 except KeyError: 438 pass 439 440 raise TypeError('No such value for %s in Enum %s' % 441 (index, cls.__name__)) 442 443 def __init__(self, name, number=None): 444 """Initialize new Enum instance. 445 446 Since this should only be called during class initialization any 447 calls that happen after the class is frozen raises an exception. 448 """ 449 # Immediately return if __init__ was called after _Enum.__init__(). 450 # It means that casting operator version of the class constructor 451 # is being used. 452 if getattr(type(self), '_DefinitionClass__initialized'): 453 return 454 object.__setattr__(self, 'name', name) 455 object.__setattr__(self, 'number', number) 456 457 def __setattr__(self, name, value): 458 raise TypeError('May not change enum values') 459 460 def __str__(self): 461 return self.name 462 463 def __int__(self): 464 return self.number 465 466 def __repr__(self): 467 return '%s(%s, %d)' % (type(self).__name__, self.name, self.number) 468 469 def __reduce__(self): 470 """Enable pickling. 471 472 Returns: 473 A 2-tuple containing the class and __new__ args to be used 474 for restoring a pickled instance. 475 476 """ 477 return self.__class__, (self.number,) 478 479 def __cmp__(self, other): 480 """Order is by number.""" 481 if isinstance(other, type(self)): 482 return cmp(self.number, other.number) 483 return NotImplemented 484 485 def __lt__(self, other): 486 """Order is by number.""" 487 if isinstance(other, type(self)): 488 return self.number < other.number 489 return NotImplemented 490 491 def __le__(self, other): 492 """Order is by number.""" 493 if isinstance(other, type(self)): 494 return self.number <= other.number 495 return NotImplemented 496 497 def __eq__(self, other): 498 """Order is by number.""" 499 if isinstance(other, type(self)): 500 return self.number == other.number 501 return NotImplemented 502 503 def __ne__(self, other): 504 """Order is by number.""" 505 if isinstance(other, type(self)): 506 return self.number != other.number 507 return NotImplemented 508 509 def __ge__(self, other): 510 """Order is by number.""" 511 if isinstance(other, type(self)): 512 return self.number >= other.number 513 return NotImplemented 514 515 def __gt__(self, other): 516 """Order is by number.""" 517 if isinstance(other, type(self)): 518 return self.number > other.number 519 return NotImplemented 520 521 def __hash__(self): 522 """Hash by number.""" 523 return hash(self.number) 524 525 @classmethod 526 def to_dict(cls): 527 """Make dictionary version of enumerated class. 528 529 Dictionary created this way can be used with def_num. 530 531 Returns: 532 A dict (name) -> number 533 """ 534 return dict((item.name, item.number) for item in iter(cls)) 535 536 @staticmethod 537 def def_enum(dct, name): 538 """Define enum class from dictionary. 539 540 Args: 541 dct: Dictionary of enumerated values for type. 542 name: Name of enum. 543 """ 544 return type(name, (Enum,), dct) 545 546 547# TODO(rafek): Determine to what degree this enumeration should be compatible 548# with FieldDescriptor.Type in https://github.com/google/protobuf. 549class Variant(Enum): 550 """Wire format variant. 551 552 Used by the 'protobuf' wire format to determine how to transmit 553 a single piece of data. May be used by other formats. 554 555 See: http://code.google.com/apis/protocolbuffers/docs/encoding.html 556 557 Values: 558 DOUBLE: 64-bit floating point number. 559 FLOAT: 32-bit floating point number. 560 INT64: 64-bit signed integer. 561 UINT64: 64-bit unsigned integer. 562 INT32: 32-bit signed integer. 563 BOOL: Boolean value (True or False). 564 STRING: String of UTF-8 encoded text. 565 MESSAGE: Embedded message as byte string. 566 BYTES: String of 8-bit bytes. 567 UINT32: 32-bit unsigned integer. 568 ENUM: Enum value as integer. 569 SINT32: 32-bit signed integer. Uses "zig-zag" encoding. 570 SINT64: 64-bit signed integer. Uses "zig-zag" encoding. 571 """ 572 DOUBLE = 1 573 FLOAT = 2 574 INT64 = 3 575 UINT64 = 4 576 INT32 = 5 577 BOOL = 8 578 STRING = 9 579 MESSAGE = 11 580 BYTES = 12 581 UINT32 = 13 582 ENUM = 14 583 SINT32 = 17 584 SINT64 = 18 585 586 587class _MessageClass(_DefinitionClass): 588 """Meta-class used for defining the Message base class. 589 590 For more details about Message classes, see the Message class docstring. 591 Information contained there may help understanding this class. 592 593 Meta-class enables very specific behavior for any defined Message 594 class. All attributes defined on an Message sub-class must be 595 field instances, Enum class definitions or other Message class 596 definitions. Each field attribute defined on an Message sub-class 597 is added to the set of field definitions and the attribute is 598 translated in to a slot. It also ensures that only one level of 599 Message class hierarchy is possible. In other words it is not 600 possible to declare sub-classes of sub-classes of Message. 601 602 This class also defines some functions in order to restrict the 603 behavior of the Message class and its sub-classes. It is not 604 possible to change the behavior of the Message class in later 605 classes since any new classes may be defined with only field, 606 Enums and Messages, and no methods. 607 608 """ 609 610 # pylint:disable=bad-mcs-classmethod-argument 611 def __new__(cls, name, bases, dct): 612 """Create new Message class instance. 613 614 The __new__ method of the _MessageClass type is overridden so as to 615 allow the translation of Field instances to slots. 616 """ 617 by_number = {} 618 by_name = {} 619 620 variant_map = {} # pylint:disable=unused-variable 621 622 if bases != (object,): 623 # Can only define one level of sub-classes below Message. 624 if bases != (Message,): 625 raise MessageDefinitionError( 626 'Message types may only inherit from Message') 627 628 enums = [] 629 messages = [] 630 # Must not use iteritems because this loop will change the state of 631 # dct. 632 for key, field in dct.items(): 633 634 if key in _RESERVED_ATTRIBUTE_NAMES: 635 continue 636 637 if isinstance(field, type) and issubclass(field, Enum): 638 enums.append(key) 639 continue 640 641 if (isinstance(field, type) and 642 issubclass(field, Message) and 643 field is not Message): 644 messages.append(key) 645 continue 646 647 # Reject anything that is not a field. 648 # pylint:disable=unidiomatic-typecheck 649 if type(field) is Field or not isinstance(field, Field): 650 raise MessageDefinitionError( 651 'May only use fields in message definitions. ' 652 'Found: %s = %s' % 653 (key, field)) 654 655 if field.number in by_number: 656 raise DuplicateNumberError( 657 'Field with number %d declared more than once in %s' % 658 (field.number, name)) 659 660 field.name = key 661 662 # Place in name and number maps. 663 by_name[key] = field 664 by_number[field.number] = field 665 666 # Add enums if any exist. 667 if enums: 668 dct['__enums__'] = sorted(enums) 669 670 # Add messages if any exist. 671 if messages: 672 dct['__messages__'] = sorted(messages) 673 674 dct['_Message__by_number'] = by_number 675 dct['_Message__by_name'] = by_name 676 677 return _DefinitionClass.__new__(cls, name, bases, dct) 678 679 def __init__(cls, name, bases, dct): 680 """Initializer required to assign references to new class.""" 681 if bases != (object,): 682 for v in dct.values(): 683 if isinstance(v, _DefinitionClass) and v is not Message: 684 v._message_definition = weakref.ref(cls) 685 686 for field in cls.all_fields(): 687 field._message_definition = weakref.ref(cls) 688 689 _DefinitionClass.__init__(cls, name, bases, dct) 690 691 692class Message(six.with_metaclass(_MessageClass, object)): 693 """Base class for user defined message objects. 694 695 Used to define messages for efficient transmission across network or 696 process space. Messages are defined using the field classes (IntegerField, 697 FloatField, EnumField, etc.). 698 699 Messages are more restricted than normal classes in that they may 700 only contain field attributes and other Message and Enum 701 definitions. These restrictions are in place because the structure 702 of the Message class is intentended to itself be transmitted 703 across network or process space and used directly by clients or 704 even other servers. As such methods and non-field attributes could 705 not be transmitted with the structural information causing 706 discrepancies between different languages and implementations. 707 708 Initialization and validation: 709 710 A Message object is considered to be initialized if it has all required 711 fields and any nested messages are also initialized. 712 713 Calling 'check_initialized' will raise a ValidationException if it is not 714 initialized; 'is_initialized' returns a boolean value indicating if it is 715 valid. 716 717 Validation automatically occurs when Message objects are created 718 and populated. Validation that a given value will be compatible with 719 a field that it is assigned to can be done through the Field instances 720 validate() method. The validate method used on a message will check that 721 all values of a message and its sub-messages are valid. Assingning an 722 invalid value to a field will raise a ValidationException. 723 724 Example: 725 726 # Trade type. 727 class TradeType(Enum): 728 BUY = 1 729 SELL = 2 730 SHORT = 3 731 CALL = 4 732 733 class Lot(Message): 734 price = IntegerField(1, required=True) 735 quantity = IntegerField(2, required=True) 736 737 class Order(Message): 738 symbol = StringField(1, required=True) 739 total_quantity = IntegerField(2, required=True) 740 trade_type = EnumField(TradeType, 3, required=True) 741 lots = MessageField(Lot, 4, repeated=True) 742 limit = IntegerField(5) 743 744 order = Order(symbol='GOOG', 745 total_quantity=10, 746 trade_type=TradeType.BUY) 747 748 lot1 = Lot(price=304, 749 quantity=7) 750 751 lot2 = Lot(price = 305, 752 quantity=3) 753 754 order.lots = [lot1, lot2] 755 756 # Now object is initialized! 757 order.check_initialized() 758 759 """ 760 761 def __init__(self, **kwargs): 762 """Initialize internal messages state. 763 764 Args: 765 A message can be initialized via the constructor by passing 766 in keyword arguments corresponding to fields. For example: 767 768 class Date(Message): 769 day = IntegerField(1) 770 month = IntegerField(2) 771 year = IntegerField(3) 772 773 Invoking: 774 775 date = Date(day=6, month=6, year=1911) 776 777 is the same as doing: 778 779 date = Date() 780 date.day = 6 781 date.month = 6 782 date.year = 1911 783 784 """ 785 # Tag being an essential implementation detail must be private. 786 self.__tags = {} 787 self.__unrecognized_fields = {} 788 789 assigned = set() 790 for name, value in kwargs.items(): 791 setattr(self, name, value) 792 assigned.add(name) 793 794 # initialize repeated fields. 795 for field in self.all_fields(): 796 if field.repeated and field.name not in assigned: 797 setattr(self, field.name, []) 798 799 def check_initialized(self): 800 """Check class for initialization status. 801 802 Check that all required fields are initialized 803 804 Raises: 805 ValidationError: If message is not initialized. 806 """ 807 for name, field in self.__by_name.items(): 808 value = getattr(self, name) 809 if value is None: 810 if field.required: 811 raise ValidationError( 812 "Message %s is missing required field %s" % 813 (type(self).__name__, name)) 814 else: 815 try: 816 if (isinstance(field, MessageField) and 817 issubclass(field.message_type, Message)): 818 if field.repeated: 819 for item in value: 820 item_message_value = field.value_to_message( 821 item) 822 item_message_value.check_initialized() 823 else: 824 message_value = field.value_to_message(value) 825 message_value.check_initialized() 826 except ValidationError as err: 827 if not hasattr(err, 'message_name'): 828 err.message_name = type(self).__name__ 829 raise 830 831 def is_initialized(self): 832 """Get initialization status. 833 834 Returns: 835 True if message is valid, else False. 836 """ 837 try: 838 self.check_initialized() 839 except ValidationError: 840 return False 841 else: 842 return True 843 844 @classmethod 845 def all_fields(cls): 846 """Get all field definition objects. 847 848 Ordering is arbitrary. 849 850 Returns: 851 Iterator over all values in arbitrary order. 852 """ 853 return cls.__by_name.values() 854 855 @classmethod 856 def field_by_name(cls, name): 857 """Get field by name. 858 859 Returns: 860 Field object associated with name. 861 862 Raises: 863 KeyError if no field found by that name. 864 """ 865 return cls.__by_name[name] 866 867 @classmethod 868 def field_by_number(cls, number): 869 """Get field by number. 870 871 Returns: 872 Field object associated with number. 873 874 Raises: 875 KeyError if no field found by that number. 876 """ 877 return cls.__by_number[number] 878 879 def get_assigned_value(self, name): 880 """Get the assigned value of an attribute. 881 882 Get the underlying value of an attribute. If value has not 883 been set, will not return the default for the field. 884 885 Args: 886 name: Name of attribute to get. 887 888 Returns: 889 Value of attribute, None if it has not been set. 890 891 """ 892 message_type = type(self) 893 try: 894 field = message_type.field_by_name(name) 895 except KeyError: 896 raise AttributeError('Message %s has no field %s' % ( 897 message_type.__name__, name)) 898 return self.__tags.get(field.number) 899 900 def reset(self, name): 901 """Reset assigned value for field. 902 903 Resetting a field will return it to its default value or None. 904 905 Args: 906 name: Name of field to reset. 907 """ 908 message_type = type(self) 909 try: 910 field = message_type.field_by_name(name) 911 except KeyError: 912 if name not in message_type.__by_name: 913 raise AttributeError('Message %s has no field %s' % ( 914 message_type.__name__, name)) 915 if field.repeated: 916 self.__tags[field.number] = FieldList(field, []) 917 else: 918 self.__tags.pop(field.number, None) 919 920 def all_unrecognized_fields(self): 921 """Get the names of all unrecognized fields in this message.""" 922 return list(self.__unrecognized_fields.keys()) 923 924 def get_unrecognized_field_info(self, key, value_default=None, 925 variant_default=None): 926 """Get the value and variant of an unknown field in this message. 927 928 Args: 929 key: The name or number of the field to retrieve. 930 value_default: Value to be returned if the key isn't found. 931 variant_default: Value to be returned as variant if the key isn't 932 found. 933 934 Returns: 935 (value, variant), where value and variant are whatever was passed 936 to set_unrecognized_field. 937 """ 938 value, variant = self.__unrecognized_fields.get(key, (value_default, 939 variant_default)) 940 return value, variant 941 942 def set_unrecognized_field(self, key, value, variant): 943 """Set an unrecognized field, used when decoding a message. 944 945 Args: 946 key: The name or number used to refer to this unknown value. 947 value: The value of the field. 948 variant: Type information needed to interpret the value or re-encode 949 it. 950 951 Raises: 952 TypeError: If the variant is not an instance of messages.Variant. 953 """ 954 if not isinstance(variant, Variant): 955 raise TypeError('Variant type %s is not valid.' % variant) 956 self.__unrecognized_fields[key] = value, variant 957 958 def __setattr__(self, name, value): 959 """Change set behavior for messages. 960 961 Messages may only be assigned values that are fields. 962 963 Does not try to validate field when set. 964 965 Args: 966 name: Name of field to assign to. 967 value: Value to assign to field. 968 969 Raises: 970 AttributeError when trying to assign value that is not a field. 971 """ 972 if name in self.__by_name or name.startswith('_Message__'): 973 object.__setattr__(self, name, value) 974 else: 975 raise AttributeError("May not assign arbitrary value %s " 976 "to message %s" % (name, type(self).__name__)) 977 978 def __repr__(self): 979 """Make string representation of message. 980 981 Example: 982 983 class MyMessage(messages.Message): 984 integer_value = messages.IntegerField(1) 985 string_value = messages.StringField(2) 986 987 my_message = MyMessage() 988 my_message.integer_value = 42 989 my_message.string_value = u'A string' 990 991 print my_message 992 >>> <MyMessage 993 ... integer_value: 42 994 ... string_value: u'A string'> 995 996 Returns: 997 String representation of message, including the values 998 of all fields and repr of all sub-messages. 999 """ 1000 body = ['<', type(self).__name__] 1001 for field in sorted(self.all_fields(), 1002 key=lambda f: f.number): 1003 attribute = field.name 1004 value = self.get_assigned_value(field.name) 1005 if value is not None: 1006 body.append('\n %s: %s' % (attribute, repr(value))) 1007 body.append('>') 1008 return ''.join(body) 1009 1010 def __eq__(self, other): 1011 """Equality operator. 1012 1013 Does field by field comparison with other message. For 1014 equality, must be same type and values of all fields must be 1015 equal. 1016 1017 Messages not required to be initialized for comparison. 1018 1019 Does not attempt to determine equality for values that have 1020 default values that are not set. In other words: 1021 1022 class HasDefault(Message): 1023 1024 attr1 = StringField(1, default='default value') 1025 1026 message1 = HasDefault() 1027 message2 = HasDefault() 1028 message2.attr1 = 'default value' 1029 1030 message1 != message2 1031 1032 Does not compare unknown values. 1033 1034 Args: 1035 other: Other message to compare with. 1036 """ 1037 # TODO(rafek): Implement "equivalent" which does comparisons 1038 # taking default values in to consideration. 1039 if self is other: 1040 return True 1041 1042 if type(self) is not type(other): 1043 return False 1044 1045 return self.__tags == other.__tags 1046 1047 def __ne__(self, other): 1048 """Not equals operator. 1049 1050 Does field by field comparison with other message. For 1051 non-equality, must be different type or any value of a field must be 1052 non-equal to the same field in the other instance. 1053 1054 Messages not required to be initialized for comparison. 1055 1056 Args: 1057 other: Other message to compare with. 1058 """ 1059 return not self.__eq__(other) 1060 1061 1062class FieldList(list): 1063 """List implementation that validates field values. 1064 1065 This list implementation overrides all methods that add values in 1066 to a list in order to validate those new elements. Attempting to 1067 add or set list values that are not of the correct type will raise 1068 ValidationError. 1069 1070 """ 1071 1072 def __init__(self, field_instance, sequence): 1073 """Constructor. 1074 1075 Args: 1076 field_instance: Instance of field that validates the list. 1077 sequence: List or tuple to construct list from. 1078 """ 1079 if not field_instance.repeated: 1080 raise FieldDefinitionError( 1081 'FieldList may only accept repeated fields') 1082 self.__field = field_instance 1083 self.__field.validate(sequence) 1084 list.__init__(self, sequence) 1085 1086 def __getstate__(self): 1087 """Enable pickling. 1088 1089 The assigned field instance can't be pickled if it belongs to 1090 a Message definition (message_definition uses a weakref), so 1091 the Message class and field number are returned in that case. 1092 1093 Returns: 1094 A 3-tuple containing: 1095 - The field instance, or None if it belongs to a Message class. 1096 - The Message class that the field instance belongs to, or None. 1097 - The field instance number of the Message class it belongs to, or 1098 None. 1099 1100 """ 1101 message_class = self.__field.message_definition() 1102 if message_class is None: 1103 return self.__field, None, None 1104 return None, message_class, self.__field.number 1105 1106 def __setstate__(self, state): 1107 """Enable unpickling. 1108 1109 Args: 1110 state: A 3-tuple containing: 1111 - The field instance, or None if it belongs to a Message class. 1112 - The Message class that the field instance belongs to, or None. 1113 - The field instance number of the Message class it belongs to, or 1114 None. 1115 """ 1116 field_instance, message_class, number = state 1117 if field_instance is None: 1118 self.__field = message_class.field_by_number(number) 1119 else: 1120 self.__field = field_instance 1121 1122 @property 1123 def field(self): 1124 """Field that validates list.""" 1125 return self.__field 1126 1127 def __setslice__(self, i, j, sequence): 1128 """Validate slice assignment to list.""" 1129 self.__field.validate(sequence) 1130 list.__setslice__(self, i, j, sequence) 1131 1132 def __setitem__(self, index, value): 1133 """Validate item assignment to list.""" 1134 if isinstance(index, slice): 1135 self.__field.validate(value) 1136 else: 1137 self.__field.validate_element(value) 1138 list.__setitem__(self, index, value) 1139 1140 def append(self, value): 1141 """Validate item appending to list.""" 1142 self.__field.validate_element(value) 1143 return list.append(self, value) 1144 1145 def extend(self, sequence): 1146 """Validate extension of list.""" 1147 self.__field.validate(sequence) 1148 return list.extend(self, sequence) 1149 1150 def insert(self, index, value): 1151 """Validate item insertion to list.""" 1152 self.__field.validate_element(value) 1153 return list.insert(self, index, value) 1154 1155 1156class _FieldMeta(type): 1157 1158 def __init__(cls, name, bases, dct): 1159 getattr(cls, '_Field__variant_to_type').update( 1160 (variant, cls) for variant in dct.get('VARIANTS', [])) 1161 type.__init__(cls, name, bases, dct) 1162 1163 1164# TODO(rafek): Prevent additional field subclasses. 1165class Field(six.with_metaclass(_FieldMeta, object)): 1166 """Definition for message field.""" 1167 1168 __initialized = False # pylint:disable=invalid-name 1169 __variant_to_type = {} # pylint:disable=invalid-name 1170 1171 @util.positional(2) 1172 def __init__(self, 1173 number, 1174 required=False, 1175 repeated=False, 1176 variant=None, 1177 default=None): 1178 """Constructor. 1179 1180 The required and repeated parameters are mutually exclusive. 1181 Setting both to True will raise a FieldDefinitionError. 1182 1183 Sub-class Attributes: 1184 Each sub-class of Field must define the following: 1185 VARIANTS: Set of variant types accepted by that field. 1186 DEFAULT_VARIANT: Default variant type if not specified in 1187 constructor. 1188 1189 Args: 1190 number: Number of field. Must be unique per message class. 1191 required: Whether or not field is required. Mutually exclusive with 1192 'repeated'. 1193 repeated: Whether or not field is repeated. Mutually exclusive with 1194 'required'. 1195 variant: Wire-format variant hint. 1196 default: Default value for field if not found in stream. 1197 1198 Raises: 1199 InvalidVariantError when invalid variant for field is provided. 1200 InvalidDefaultError when invalid default for field is provided. 1201 FieldDefinitionError when invalid number provided or mutually 1202 exclusive fields are used. 1203 InvalidNumberError when the field number is out of range or reserved. 1204 1205 """ 1206 if not isinstance(number, int) or not 1 <= number <= MAX_FIELD_NUMBER: 1207 raise InvalidNumberError( 1208 'Invalid number for field: %s\n' 1209 'Number must be 1 or greater and %d or less' % 1210 (number, MAX_FIELD_NUMBER)) 1211 1212 if FIRST_RESERVED_FIELD_NUMBER <= number <= LAST_RESERVED_FIELD_NUMBER: 1213 raise InvalidNumberError('Tag number %d is a reserved number.\n' 1214 'Numbers %d to %d are reserved' % 1215 (number, FIRST_RESERVED_FIELD_NUMBER, 1216 LAST_RESERVED_FIELD_NUMBER)) 1217 1218 if repeated and required: 1219 raise FieldDefinitionError('Cannot set both repeated and required') 1220 1221 if variant is None: 1222 variant = self.DEFAULT_VARIANT 1223 1224 if repeated and default is not None: 1225 raise FieldDefinitionError('Repeated fields may not have defaults') 1226 1227 if variant not in self.VARIANTS: 1228 raise InvalidVariantError( 1229 'Invalid variant: %s\nValid variants for %s are %r' % 1230 (variant, type(self).__name__, sorted(self.VARIANTS))) 1231 1232 self.number = number 1233 self.required = required 1234 self.repeated = repeated 1235 self.variant = variant 1236 1237 if default is not None: 1238 try: 1239 self.validate_default(default) 1240 except ValidationError as err: 1241 try: 1242 name = self.name 1243 except AttributeError: 1244 # For when raising error before name initialization. 1245 raise InvalidDefaultError( 1246 'Invalid default value for %s: %r: %s' % 1247 (self.__class__.__name__, default, err)) 1248 else: 1249 raise InvalidDefaultError( 1250 'Invalid default value for field %s: ' 1251 '%r: %s' % (name, default, err)) 1252 1253 self.__default = default 1254 self.__initialized = True 1255 1256 def __setattr__(self, name, value): 1257 """Setter overidden to prevent assignment to fields after creation. 1258 1259 Args: 1260 name: Name of attribute to set. 1261 value: Value to assign. 1262 """ 1263 # Special case post-init names. They need to be set after constructor. 1264 if name in _POST_INIT_FIELD_ATTRIBUTE_NAMES: 1265 object.__setattr__(self, name, value) 1266 return 1267 1268 # All other attributes must be set before __initialized. 1269 if not self.__initialized: 1270 # Not initialized yet, allow assignment. 1271 object.__setattr__(self, name, value) 1272 else: 1273 raise AttributeError('Field objects are read-only') 1274 1275 def __set__(self, message_instance, value): 1276 """Set value on message. 1277 1278 Args: 1279 message_instance: Message instance to set value on. 1280 value: Value to set on message. 1281 """ 1282 # Reaches in to message instance directly to assign to private tags. 1283 if value is None: 1284 if self.repeated: 1285 raise ValidationError( 1286 'May not assign None to repeated field %s' % self.name) 1287 else: 1288 message_instance._Message__tags.pop(self.number, None) 1289 else: 1290 if self.repeated: 1291 value = FieldList(self, value) 1292 else: 1293 value = self.validate(value) 1294 message_instance._Message__tags[self.number] = value 1295 1296 def __get__(self, message_instance, message_class): 1297 if message_instance is None: 1298 return self 1299 1300 result = message_instance._Message__tags.get(self.number) 1301 if result is None: 1302 return self.default 1303 return result 1304 1305 def validate_element(self, value): 1306 """Validate single element of field. 1307 1308 This is different from validate in that it is used on individual 1309 values of repeated fields. 1310 1311 Args: 1312 value: Value to validate. 1313 1314 Returns: 1315 The value casted in the expected type. 1316 1317 Raises: 1318 ValidationError if value is not expected type. 1319 """ 1320 if not isinstance(value, self.type): 1321 1322 # Authorize int values as float. 1323 if isinstance(value, six.integer_types) and self.type == float: 1324 return float(value) 1325 1326 if value is None: 1327 if self.required: 1328 raise ValidationError('Required field is missing') 1329 else: 1330 try: 1331 name = self.name 1332 except AttributeError: 1333 raise ValidationError('Expected type %s for %s, ' 1334 'found %s (type %s)' % 1335 (self.type, self.__class__.__name__, 1336 value, type(value))) 1337 else: 1338 raise ValidationError( 1339 'Expected type %s for field %s, found %s (type %s)' % 1340 (self.type, name, value, type(value))) 1341 return value 1342 1343 def __validate(self, value, validate_element): 1344 """Internal validation function. 1345 1346 Validate an internal value using a function to validate 1347 individual elements. 1348 1349 Args: 1350 value: Value to validate. 1351 validate_element: Function to use to validate individual elements. 1352 1353 Raises: 1354 ValidationError if value is not expected type. 1355 1356 """ 1357 if not self.repeated: 1358 return validate_element(value) 1359 else: 1360 # Must be a list or tuple, may not be a string. 1361 if isinstance(value, (list, tuple)): 1362 result = [] 1363 for element in value: 1364 if element is None: 1365 try: 1366 name = self.name 1367 except AttributeError: 1368 raise ValidationError( 1369 'Repeated values for %s ' 1370 'may not be None' % self.__class__.__name__) 1371 else: 1372 raise ValidationError( 1373 'Repeated values for field %s ' 1374 'may not be None' % name) 1375 result.append(validate_element(element)) 1376 return result 1377 elif value is not None: 1378 try: 1379 name = self.name 1380 except AttributeError: 1381 raise ValidationError('%s is repeated. Found: %s' % ( 1382 self.__class__.__name__, value)) 1383 else: 1384 raise ValidationError( 1385 'Field %s is repeated. Found: %s' % (name, value)) 1386 return value 1387 1388 def validate(self, value): 1389 """Validate value assigned to field. 1390 1391 Args: 1392 value: Value to validate. 1393 1394 Returns: 1395 the value in casted in the correct type. 1396 1397 Raises: 1398 ValidationError if value is not expected type. 1399 """ 1400 return self.__validate(value, self.validate_element) 1401 1402 def validate_default_element(self, value): 1403 """Validate value as assigned to field default field. 1404 1405 Some fields may allow for delayed resolution of default types 1406 necessary in the case of circular definition references. In 1407 this case, the default value might be a place holder that is 1408 resolved when needed after all the message classes are 1409 defined. 1410 1411 Args: 1412 value: Default value to validate. 1413 1414 Returns: 1415 the value in casted in the correct type. 1416 1417 Raises: 1418 ValidationError if value is not expected type. 1419 1420 """ 1421 return self.validate_element(value) 1422 1423 def validate_default(self, value): 1424 """Validate default value assigned to field. 1425 1426 Args: 1427 value: Value to validate. 1428 1429 Returns: 1430 the value in casted in the correct type. 1431 1432 Raises: 1433 ValidationError if value is not expected type. 1434 """ 1435 return self.__validate(value, self.validate_default_element) 1436 1437 def message_definition(self): 1438 """Get Message definition that contains this Field definition. 1439 1440 Returns: 1441 Containing Message definition for Field. Will return None if 1442 for some reason Field is defined outside of a Message class. 1443 1444 """ 1445 try: 1446 return self._message_definition() 1447 except AttributeError: 1448 return None 1449 1450 @property 1451 def default(self): 1452 """Get default value for field.""" 1453 return self.__default 1454 1455 @classmethod 1456 def lookup_field_type_by_variant(cls, variant): 1457 return cls.__variant_to_type[variant] 1458 1459 1460class IntegerField(Field): 1461 """Field definition for integer values.""" 1462 1463 VARIANTS = frozenset([ 1464 Variant.INT32, 1465 Variant.INT64, 1466 Variant.UINT32, 1467 Variant.UINT64, 1468 Variant.SINT32, 1469 Variant.SINT64, 1470 ]) 1471 1472 DEFAULT_VARIANT = Variant.INT64 1473 1474 type = six.integer_types 1475 1476 1477class FloatField(Field): 1478 """Field definition for float values.""" 1479 1480 VARIANTS = frozenset([ 1481 Variant.FLOAT, 1482 Variant.DOUBLE, 1483 ]) 1484 1485 DEFAULT_VARIANT = Variant.DOUBLE 1486 1487 type = float 1488 1489 1490class BooleanField(Field): 1491 """Field definition for boolean values.""" 1492 1493 VARIANTS = frozenset([Variant.BOOL]) 1494 1495 DEFAULT_VARIANT = Variant.BOOL 1496 1497 type = bool 1498 1499 1500class BytesField(Field): 1501 """Field definition for byte string values.""" 1502 1503 VARIANTS = frozenset([Variant.BYTES]) 1504 1505 DEFAULT_VARIANT = Variant.BYTES 1506 1507 type = bytes 1508 1509 1510class StringField(Field): 1511 """Field definition for unicode string values.""" 1512 1513 VARIANTS = frozenset([Variant.STRING]) 1514 1515 DEFAULT_VARIANT = Variant.STRING 1516 1517 type = six.text_type 1518 1519 def validate_element(self, value): 1520 """Validate StringField allowing for str and unicode. 1521 1522 Raises: 1523 ValidationError if a str value is not UTF-8. 1524 """ 1525 # If value is str is it considered valid. Satisfies "required=True". 1526 if isinstance(value, bytes): 1527 try: 1528 six.text_type(value, 'UTF-8') 1529 except UnicodeDecodeError as err: 1530 try: 1531 _ = self.name 1532 except AttributeError: 1533 validation_error = ValidationError( 1534 'Field encountered non-UTF-8 string %r: %s' % (value, 1535 err)) 1536 else: 1537 validation_error = ValidationError( 1538 'Field %s encountered non-UTF-8 string %r: %s' % ( 1539 self.name, value, err)) 1540 validation_error.field_name = self.name 1541 raise validation_error 1542 else: 1543 return super(StringField, self).validate_element(value) 1544 return value 1545 1546 1547class MessageField(Field): 1548 """Field definition for sub-message values. 1549 1550 Message fields contain instance of other messages. Instances stored 1551 on messages stored on message fields are considered to be owned by 1552 the containing message instance and should not be shared between 1553 owning instances. 1554 1555 Message fields must be defined to reference a single type of message. 1556 Normally message field are defined by passing the referenced message 1557 class in to the constructor. 1558 1559 It is possible to define a message field for a type that does not 1560 yet exist by passing the name of the message in to the constructor 1561 instead of a message class. Resolution of the actual type of the 1562 message is deferred until it is needed, for example, during 1563 message verification. Names provided to the constructor must refer 1564 to a class within the same python module as the class that is 1565 using it. Names refer to messages relative to the containing 1566 messages scope. For example, the two fields of OuterMessage refer 1567 to the same message type: 1568 1569 class Outer(Message): 1570 1571 inner_relative = MessageField('Inner', 1) 1572 inner_absolute = MessageField('Outer.Inner', 2) 1573 1574 class Inner(Message): 1575 ... 1576 1577 When resolving an actual type, MessageField will traverse the 1578 entire scope of nested messages to match a message name. This 1579 makes it easy for siblings to reference siblings: 1580 1581 class Outer(Message): 1582 1583 class Inner(Message): 1584 1585 sibling = MessageField('Sibling', 1) 1586 1587 class Sibling(Message): 1588 ... 1589 1590 """ 1591 1592 VARIANTS = frozenset([Variant.MESSAGE]) 1593 1594 DEFAULT_VARIANT = Variant.MESSAGE 1595 1596 @util.positional(3) 1597 def __init__(self, 1598 message_type, 1599 number, 1600 required=False, 1601 repeated=False, 1602 variant=None): 1603 """Constructor. 1604 1605 Args: 1606 message_type: Message type for field. Must be subclass of Message. 1607 number: Number of field. Must be unique per message class. 1608 required: Whether or not field is required. Mutually exclusive to 1609 'repeated'. 1610 repeated: Whether or not field is repeated. Mutually exclusive to 1611 'required'. 1612 variant: Wire-format variant hint. 1613 1614 Raises: 1615 FieldDefinitionError when invalid message_type is provided. 1616 """ 1617 valid_type = (isinstance(message_type, six.string_types) or 1618 (message_type is not Message and 1619 isinstance(message_type, type) and 1620 issubclass(message_type, Message))) 1621 1622 if not valid_type: 1623 raise FieldDefinitionError( 1624 'Invalid message class: %s' % message_type) 1625 1626 if isinstance(message_type, six.string_types): 1627 self.__type_name = message_type 1628 self.__type = None 1629 else: 1630 self.__type = message_type 1631 1632 super(MessageField, self).__init__(number, 1633 required=required, 1634 repeated=repeated, 1635 variant=variant) 1636 1637 def __set__(self, message_instance, value): 1638 """Set value on message. 1639 1640 Args: 1641 message_instance: Message instance to set value on. 1642 value: Value to set on message. 1643 """ 1644 t = self.type 1645 if isinstance(t, type) and issubclass(t, Message): 1646 if self.repeated: 1647 if value and isinstance(value, (list, tuple)): 1648 value = [(t(**v) if isinstance(v, dict) else v) 1649 for v in value] 1650 elif isinstance(value, dict): 1651 value = t(**value) 1652 super(MessageField, self).__set__(message_instance, value) 1653 1654 @property 1655 def type(self): 1656 """Message type used for field.""" 1657 if self.__type is None: 1658 message_type = find_definition( 1659 self.__type_name, self.message_definition()) 1660 if not (message_type is not Message and 1661 isinstance(message_type, type) and 1662 issubclass(message_type, Message)): 1663 raise FieldDefinitionError( 1664 'Invalid message class: %s' % message_type) 1665 self.__type = message_type 1666 return self.__type 1667 1668 @property 1669 def message_type(self): 1670 """Underlying message type used for serialization. 1671 1672 Will always be a sub-class of Message. This is different from type 1673 which represents the python value that message_type is mapped to for 1674 use by the user. 1675 """ 1676 return self.type 1677 1678 def value_from_message(self, message): 1679 """Convert a message to a value instance. 1680 1681 Used by deserializers to convert from underlying messages to 1682 value of expected user type. 1683 1684 Args: 1685 message: A message instance of type self.message_type. 1686 1687 Returns: 1688 Value of self.message_type. 1689 """ 1690 if not isinstance(message, self.message_type): 1691 raise DecodeError('Expected type %s, got %s: %r' % 1692 (self.message_type.__name__, 1693 type(message).__name__, 1694 message)) 1695 return message 1696 1697 def value_to_message(self, value): 1698 """Convert a value instance to a message. 1699 1700 Used by serializers to convert Python user types to underlying 1701 messages for transmission. 1702 1703 Args: 1704 value: A value of type self.type. 1705 1706 Returns: 1707 An instance of type self.message_type. 1708 """ 1709 if not isinstance(value, self.type): 1710 raise EncodeError('Expected type %s, got %s: %r' % 1711 (self.type.__name__, 1712 type(value).__name__, 1713 value)) 1714 return value 1715 1716 1717class EnumField(Field): 1718 """Field definition for enum values. 1719 1720 Enum fields may have default values that are delayed until the 1721 associated enum type is resolved. This is necessary to support 1722 certain circular references. 1723 1724 For example: 1725 1726 class Message1(Message): 1727 1728 class Color(Enum): 1729 1730 RED = 1 1731 GREEN = 2 1732 BLUE = 3 1733 1734 # This field default value will be validated when default is accessed. 1735 animal = EnumField('Message2.Animal', 1, default='HORSE') 1736 1737 class Message2(Message): 1738 1739 class Animal(Enum): 1740 1741 DOG = 1 1742 CAT = 2 1743 HORSE = 3 1744 1745 # This fields default value will be validated right away since Color 1746 # is already fully resolved. 1747 color = EnumField(Message1.Color, 1, default='RED') 1748 """ 1749 1750 VARIANTS = frozenset([Variant.ENUM]) 1751 1752 DEFAULT_VARIANT = Variant.ENUM 1753 1754 def __init__(self, enum_type, number, **kwargs): 1755 """Constructor. 1756 1757 Args: 1758 enum_type: Enum type for field. Must be subclass of Enum. 1759 number: Number of field. Must be unique per message class. 1760 required: Whether or not field is required. Mutually exclusive to 1761 'repeated'. 1762 repeated: Whether or not field is repeated. Mutually exclusive to 1763 'required'. 1764 variant: Wire-format variant hint. 1765 default: Default value for field if not found in stream. 1766 1767 Raises: 1768 FieldDefinitionError when invalid enum_type is provided. 1769 """ 1770 valid_type = (isinstance(enum_type, six.string_types) or 1771 (enum_type is not Enum and 1772 isinstance(enum_type, type) and 1773 issubclass(enum_type, Enum))) 1774 1775 if not valid_type: 1776 raise FieldDefinitionError('Invalid enum type: %s' % enum_type) 1777 1778 if isinstance(enum_type, six.string_types): 1779 self.__type_name = enum_type 1780 self.__type = None 1781 else: 1782 self.__type = enum_type 1783 1784 super(EnumField, self).__init__(number, **kwargs) 1785 1786 def validate_default_element(self, value): 1787 """Validate default element of Enum field. 1788 1789 Enum fields allow for delayed resolution of default values 1790 when the type of the field has not been resolved. The default 1791 value of a field may be a string or an integer. If the Enum 1792 type of the field has been resolved, the default value is 1793 validated against that type. 1794 1795 Args: 1796 value: Value to validate. 1797 1798 Raises: 1799 ValidationError if value is not expected message type. 1800 1801 """ 1802 if isinstance(value, (six.string_types, six.integer_types)): 1803 # Validation of the value does not happen for delayed resolution 1804 # enumerated types. Ignore if type is not yet resolved. 1805 if self.__type: 1806 self.__type(value) 1807 return value 1808 1809 return super(EnumField, self).validate_default_element(value) 1810 1811 @property 1812 def type(self): 1813 """Enum type used for field.""" 1814 if self.__type is None: 1815 found_type = find_definition( 1816 self.__type_name, self.message_definition()) 1817 if not (found_type is not Enum and 1818 isinstance(found_type, type) and 1819 issubclass(found_type, Enum)): 1820 raise FieldDefinitionError( 1821 'Invalid enum type: %s' % found_type) 1822 1823 self.__type = found_type 1824 return self.__type 1825 1826 @property 1827 def default(self): 1828 """Default for enum field. 1829 1830 Will cause resolution of Enum type and unresolved default value. 1831 """ 1832 try: 1833 return self.__resolved_default 1834 except AttributeError: 1835 resolved_default = super(EnumField, self).default 1836 if isinstance(resolved_default, (six.string_types, 1837 six.integer_types)): 1838 # pylint:disable=not-callable 1839 resolved_default = self.type(resolved_default) 1840 self.__resolved_default = resolved_default 1841 return self.__resolved_default 1842 1843 1844@util.positional(2) 1845def find_definition(name, relative_to=None, importer=__import__): 1846 """Find definition by name in module-space. 1847 1848 The find algorthm will look for definitions by name relative to a 1849 message definition or by fully qualfied name. If no definition is 1850 found relative to the relative_to parameter it will do the same 1851 search against the container of relative_to. If relative_to is a 1852 nested Message, it will search its message_definition(). If that 1853 message has no message_definition() it will search its module. If 1854 relative_to is a module, it will attempt to look for the 1855 containing module and search relative to it. If the module is a 1856 top-level module, it will look for the a message using a fully 1857 qualified name. If no message is found then, the search fails and 1858 DefinitionNotFoundError is raised. 1859 1860 For example, when looking for any definition 'foo.bar.ADefinition' 1861 relative to an actual message definition abc.xyz.SomeMessage: 1862 1863 find_definition('foo.bar.ADefinition', SomeMessage) 1864 1865 It is like looking for the following fully qualified names: 1866 1867 abc.xyz.SomeMessage. foo.bar.ADefinition 1868 abc.xyz. foo.bar.ADefinition 1869 abc. foo.bar.ADefinition 1870 foo.bar.ADefinition 1871 1872 When resolving the name relative to Message definitions and modules, the 1873 algorithm searches any Messages or sub-modules found in its path. 1874 Non-Message values are not searched. 1875 1876 A name that begins with '.' is considered to be a fully qualified 1877 name. The name is always searched for from the topmost package. 1878 For example, assume two message types: 1879 1880 abc.xyz.SomeMessage 1881 xyz.SomeMessage 1882 1883 Searching for '.xyz.SomeMessage' relative to 'abc' will resolve to 1884 'xyz.SomeMessage' and not 'abc.xyz.SomeMessage'. For this kind of name, 1885 the relative_to parameter is effectively ignored and always set to None. 1886 1887 For more information about package name resolution, please see: 1888 1889 http://code.google.com/apis/protocolbuffers/docs/proto.html#packages 1890 1891 Args: 1892 name: Name of definition to find. May be fully qualified or relative 1893 name. 1894 relative_to: Search for definition relative to message definition or 1895 module. None will cause a fully qualified name search. 1896 importer: Import function to use for resolving modules. 1897 1898 Returns: 1899 Enum or Message class definition associated with name. 1900 1901 Raises: 1902 DefinitionNotFoundError if no definition is found in any search path. 1903 1904 """ 1905 # Check parameters. 1906 if not (relative_to is None or 1907 isinstance(relative_to, types.ModuleType) or 1908 isinstance(relative_to, type) and 1909 issubclass(relative_to, Message)): 1910 raise TypeError( 1911 'relative_to must be None, Message definition or module.' 1912 ' Found: %s' % relative_to) 1913 1914 name_path = name.split('.') 1915 1916 # Handle absolute path reference. 1917 if not name_path[0]: 1918 relative_to = None 1919 name_path = name_path[1:] 1920 1921 def search_path(): 1922 """Performs a single iteration searching the path from relative_to. 1923 1924 This is the function that searches up the path from a relative object. 1925 1926 fully.qualified.object . relative.or.nested.Definition 1927 ----------------------------> 1928 ^ 1929 | 1930 this part of search --+ 1931 1932 Returns: 1933 Message or Enum at the end of name_path, else None. 1934 """ 1935 next_part = relative_to 1936 for node in name_path: 1937 # Look for attribute first. 1938 attribute = getattr(next_part, node, None) 1939 1940 if attribute is not None: 1941 next_part = attribute 1942 else: 1943 # If module, look for sub-module. 1944 if (next_part is None or 1945 isinstance(next_part, types.ModuleType)): 1946 if next_part is None: 1947 module_name = node 1948 else: 1949 module_name = '%s.%s' % (next_part.__name__, node) 1950 1951 try: 1952 fromitem = module_name.split('.')[-1] 1953 next_part = importer(module_name, '', '', 1954 [str(fromitem)]) 1955 except ImportError: 1956 return None 1957 else: 1958 return None 1959 1960 if not isinstance(next_part, types.ModuleType): 1961 if not (isinstance(next_part, type) and 1962 issubclass(next_part, (Message, Enum))): 1963 return None 1964 1965 return next_part 1966 1967 while True: 1968 found = search_path() 1969 if isinstance(found, type) and issubclass(found, (Enum, Message)): 1970 return found 1971 else: 1972 # Find next relative_to to search against. 1973 # 1974 # fully.qualified.object . relative.or.nested.Definition 1975 # <--------------------- 1976 # ^ 1977 # | 1978 # does this part of search 1979 if relative_to is None: 1980 # Fully qualified search was done. Nothing found. Fail. 1981 raise DefinitionNotFoundError( 1982 'Could not find definition for %s' % name) 1983 else: 1984 if isinstance(relative_to, types.ModuleType): 1985 # Find parent module. 1986 module_path = relative_to.__name__.split('.')[:-1] 1987 if not module_path: 1988 relative_to = None 1989 else: 1990 # Should not raise ImportError. If it does... 1991 # weird and unexpected. Propagate. 1992 relative_to = importer( 1993 '.'.join(module_path), '', '', [module_path[-1]]) 1994 elif (isinstance(relative_to, type) and 1995 issubclass(relative_to, Message)): 1996 parent = relative_to.message_definition() 1997 if parent is None: 1998 last_module_name = relative_to.__module__.split( 1999 '.')[-1] 2000 relative_to = importer( 2001 relative_to.__module__, '', '', [last_module_name]) 2002 else: 2003 relative_to = parent 2004