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 if getattr(self, '_FieldList__field', None): 1143 self.__field.validate_element(value) 1144 return list.append(self, value) 1145 1146 def extend(self, sequence): 1147 """Validate extension of list.""" 1148 if getattr(self, '_FieldList__field', None): 1149 self.__field.validate(sequence) 1150 return list.extend(self, sequence) 1151 1152 def insert(self, index, value): 1153 """Validate item insertion to list.""" 1154 self.__field.validate_element(value) 1155 return list.insert(self, index, value) 1156 1157 1158class _FieldMeta(type): 1159 1160 def __init__(cls, name, bases, dct): 1161 getattr(cls, '_Field__variant_to_type').update( 1162 (variant, cls) for variant in dct.get('VARIANTS', [])) 1163 type.__init__(cls, name, bases, dct) 1164 1165 1166# TODO(rafek): Prevent additional field subclasses. 1167class Field(six.with_metaclass(_FieldMeta, object)): 1168 """Definition for message field.""" 1169 1170 __initialized = False # pylint:disable=invalid-name 1171 __variant_to_type = {} # pylint:disable=invalid-name 1172 1173 @util.positional(2) 1174 def __init__(self, 1175 number, 1176 required=False, 1177 repeated=False, 1178 variant=None, 1179 default=None): 1180 """Constructor. 1181 1182 The required and repeated parameters are mutually exclusive. 1183 Setting both to True will raise a FieldDefinitionError. 1184 1185 Sub-class Attributes: 1186 Each sub-class of Field must define the following: 1187 VARIANTS: Set of variant types accepted by that field. 1188 DEFAULT_VARIANT: Default variant type if not specified in 1189 constructor. 1190 1191 Args: 1192 number: Number of field. Must be unique per message class. 1193 required: Whether or not field is required. Mutually exclusive with 1194 'repeated'. 1195 repeated: Whether or not field is repeated. Mutually exclusive with 1196 'required'. 1197 variant: Wire-format variant hint. 1198 default: Default value for field if not found in stream. 1199 1200 Raises: 1201 InvalidVariantError when invalid variant for field is provided. 1202 InvalidDefaultError when invalid default for field is provided. 1203 FieldDefinitionError when invalid number provided or mutually 1204 exclusive fields are used. 1205 InvalidNumberError when the field number is out of range or reserved. 1206 1207 """ 1208 if not isinstance(number, int) or not 1 <= number <= MAX_FIELD_NUMBER: 1209 raise InvalidNumberError( 1210 'Invalid number for field: %s\n' 1211 'Number must be 1 or greater and %d or less' % 1212 (number, MAX_FIELD_NUMBER)) 1213 1214 if FIRST_RESERVED_FIELD_NUMBER <= number <= LAST_RESERVED_FIELD_NUMBER: 1215 raise InvalidNumberError('Tag number %d is a reserved number.\n' 1216 'Numbers %d to %d are reserved' % 1217 (number, FIRST_RESERVED_FIELD_NUMBER, 1218 LAST_RESERVED_FIELD_NUMBER)) 1219 1220 if repeated and required: 1221 raise FieldDefinitionError('Cannot set both repeated and required') 1222 1223 if variant is None: 1224 variant = self.DEFAULT_VARIANT 1225 1226 if repeated and default is not None: 1227 raise FieldDefinitionError('Repeated fields may not have defaults') 1228 1229 if variant not in self.VARIANTS: 1230 raise InvalidVariantError( 1231 'Invalid variant: %s\nValid variants for %s are %r' % 1232 (variant, type(self).__name__, sorted(self.VARIANTS))) 1233 1234 self.number = number 1235 self.required = required 1236 self.repeated = repeated 1237 self.variant = variant 1238 1239 if default is not None: 1240 try: 1241 self.validate_default(default) 1242 except ValidationError as err: 1243 try: 1244 name = self.name 1245 except AttributeError: 1246 # For when raising error before name initialization. 1247 raise InvalidDefaultError( 1248 'Invalid default value for %s: %r: %s' % 1249 (self.__class__.__name__, default, err)) 1250 else: 1251 raise InvalidDefaultError( 1252 'Invalid default value for field %s: ' 1253 '%r: %s' % (name, default, err)) 1254 1255 self.__default = default 1256 self.__initialized = True 1257 1258 def __setattr__(self, name, value): 1259 """Setter overidden to prevent assignment to fields after creation. 1260 1261 Args: 1262 name: Name of attribute to set. 1263 value: Value to assign. 1264 """ 1265 # Special case post-init names. They need to be set after constructor. 1266 if name in _POST_INIT_FIELD_ATTRIBUTE_NAMES: 1267 object.__setattr__(self, name, value) 1268 return 1269 1270 # All other attributes must be set before __initialized. 1271 if not self.__initialized: 1272 # Not initialized yet, allow assignment. 1273 object.__setattr__(self, name, value) 1274 else: 1275 raise AttributeError('Field objects are read-only') 1276 1277 def __set__(self, message_instance, value): 1278 """Set value on message. 1279 1280 Args: 1281 message_instance: Message instance to set value on. 1282 value: Value to set on message. 1283 """ 1284 # Reaches in to message instance directly to assign to private tags. 1285 if value is None: 1286 if self.repeated: 1287 raise ValidationError( 1288 'May not assign None to repeated field %s' % self.name) 1289 else: 1290 message_instance._Message__tags.pop(self.number, None) 1291 else: 1292 if self.repeated: 1293 value = FieldList(self, value) 1294 else: 1295 value = self.validate(value) 1296 message_instance._Message__tags[self.number] = value 1297 1298 def __get__(self, message_instance, message_class): 1299 if message_instance is None: 1300 return self 1301 1302 result = message_instance._Message__tags.get(self.number) 1303 if result is None: 1304 return self.default 1305 return result 1306 1307 def validate_element(self, value): 1308 """Validate single element of field. 1309 1310 This is different from validate in that it is used on individual 1311 values of repeated fields. 1312 1313 Args: 1314 value: Value to validate. 1315 1316 Returns: 1317 The value casted in the expected type. 1318 1319 Raises: 1320 ValidationError if value is not expected type. 1321 """ 1322 if not isinstance(value, self.type): 1323 1324 # Authorize int values as float. 1325 if isinstance(value, six.integer_types) and self.type == float: 1326 return float(value) 1327 1328 if value is None: 1329 if self.required: 1330 raise ValidationError('Required field is missing') 1331 else: 1332 try: 1333 name = self.name 1334 except AttributeError: 1335 raise ValidationError('Expected type %s for %s, ' 1336 'found %s (type %s)' % 1337 (self.type, self.__class__.__name__, 1338 value, type(value))) 1339 else: 1340 raise ValidationError( 1341 'Expected type %s for field %s, found %s (type %s)' % 1342 (self.type, name, value, type(value))) 1343 return value 1344 1345 def __validate(self, value, validate_element): 1346 """Internal validation function. 1347 1348 Validate an internal value using a function to validate 1349 individual elements. 1350 1351 Args: 1352 value: Value to validate. 1353 validate_element: Function to use to validate individual elements. 1354 1355 Raises: 1356 ValidationError if value is not expected type. 1357 1358 """ 1359 if not self.repeated: 1360 return validate_element(value) 1361 else: 1362 # Must be a list or tuple, may not be a string. 1363 if isinstance(value, (list, tuple)): 1364 result = [] 1365 for element in value: 1366 if element is None: 1367 try: 1368 name = self.name 1369 except AttributeError: 1370 raise ValidationError( 1371 'Repeated values for %s ' 1372 'may not be None' % self.__class__.__name__) 1373 else: 1374 raise ValidationError( 1375 'Repeated values for field %s ' 1376 'may not be None' % name) 1377 result.append(validate_element(element)) 1378 return result 1379 elif value is not None: 1380 try: 1381 name = self.name 1382 except AttributeError: 1383 raise ValidationError('%s is repeated. Found: %s' % ( 1384 self.__class__.__name__, value)) 1385 else: 1386 raise ValidationError( 1387 'Field %s is repeated. Found: %s' % (name, value)) 1388 return value 1389 1390 def validate(self, value): 1391 """Validate value assigned to field. 1392 1393 Args: 1394 value: Value to validate. 1395 1396 Returns: 1397 the value in casted in the correct type. 1398 1399 Raises: 1400 ValidationError if value is not expected type. 1401 """ 1402 return self.__validate(value, self.validate_element) 1403 1404 def validate_default_element(self, value): 1405 """Validate value as assigned to field default field. 1406 1407 Some fields may allow for delayed resolution of default types 1408 necessary in the case of circular definition references. In 1409 this case, the default value might be a place holder that is 1410 resolved when needed after all the message classes are 1411 defined. 1412 1413 Args: 1414 value: Default value to validate. 1415 1416 Returns: 1417 the value in casted in the correct type. 1418 1419 Raises: 1420 ValidationError if value is not expected type. 1421 1422 """ 1423 return self.validate_element(value) 1424 1425 def validate_default(self, value): 1426 """Validate default value assigned to field. 1427 1428 Args: 1429 value: Value to validate. 1430 1431 Returns: 1432 the value in casted in the correct type. 1433 1434 Raises: 1435 ValidationError if value is not expected type. 1436 """ 1437 return self.__validate(value, self.validate_default_element) 1438 1439 def message_definition(self): 1440 """Get Message definition that contains this Field definition. 1441 1442 Returns: 1443 Containing Message definition for Field. Will return None if 1444 for some reason Field is defined outside of a Message class. 1445 1446 """ 1447 try: 1448 return self._message_definition() 1449 except AttributeError: 1450 return None 1451 1452 @property 1453 def default(self): 1454 """Get default value for field.""" 1455 return self.__default 1456 1457 @classmethod 1458 def lookup_field_type_by_variant(cls, variant): 1459 return cls.__variant_to_type[variant] 1460 1461 1462class IntegerField(Field): 1463 """Field definition for integer values.""" 1464 1465 VARIANTS = frozenset([ 1466 Variant.INT32, 1467 Variant.INT64, 1468 Variant.UINT32, 1469 Variant.UINT64, 1470 Variant.SINT32, 1471 Variant.SINT64, 1472 ]) 1473 1474 DEFAULT_VARIANT = Variant.INT64 1475 1476 type = six.integer_types 1477 1478 1479class FloatField(Field): 1480 """Field definition for float values.""" 1481 1482 VARIANTS = frozenset([ 1483 Variant.FLOAT, 1484 Variant.DOUBLE, 1485 ]) 1486 1487 DEFAULT_VARIANT = Variant.DOUBLE 1488 1489 type = float 1490 1491 1492class BooleanField(Field): 1493 """Field definition for boolean values.""" 1494 1495 VARIANTS = frozenset([Variant.BOOL]) 1496 1497 DEFAULT_VARIANT = Variant.BOOL 1498 1499 type = bool 1500 1501 1502class BytesField(Field): 1503 """Field definition for byte string values.""" 1504 1505 VARIANTS = frozenset([Variant.BYTES]) 1506 1507 DEFAULT_VARIANT = Variant.BYTES 1508 1509 type = bytes 1510 1511 1512class StringField(Field): 1513 """Field definition for unicode string values.""" 1514 1515 VARIANTS = frozenset([Variant.STRING]) 1516 1517 DEFAULT_VARIANT = Variant.STRING 1518 1519 type = six.text_type 1520 1521 def validate_element(self, value): 1522 """Validate StringField allowing for str and unicode. 1523 1524 Raises: 1525 ValidationError if a str value is not UTF-8. 1526 """ 1527 # If value is str is it considered valid. Satisfies "required=True". 1528 if isinstance(value, bytes): 1529 try: 1530 six.text_type(value, 'UTF-8') 1531 except UnicodeDecodeError as err: 1532 try: 1533 _ = self.name 1534 except AttributeError: 1535 validation_error = ValidationError( 1536 'Field encountered non-UTF-8 string %r: %s' % (value, 1537 err)) 1538 else: 1539 validation_error = ValidationError( 1540 'Field %s encountered non-UTF-8 string %r: %s' % ( 1541 self.name, value, err)) 1542 validation_error.field_name = self.name 1543 raise validation_error 1544 else: 1545 return super(StringField, self).validate_element(value) 1546 return value 1547 1548 1549class MessageField(Field): 1550 """Field definition for sub-message values. 1551 1552 Message fields contain instance of other messages. Instances stored 1553 on messages stored on message fields are considered to be owned by 1554 the containing message instance and should not be shared between 1555 owning instances. 1556 1557 Message fields must be defined to reference a single type of message. 1558 Normally message field are defined by passing the referenced message 1559 class in to the constructor. 1560 1561 It is possible to define a message field for a type that does not 1562 yet exist by passing the name of the message in to the constructor 1563 instead of a message class. Resolution of the actual type of the 1564 message is deferred until it is needed, for example, during 1565 message verification. Names provided to the constructor must refer 1566 to a class within the same python module as the class that is 1567 using it. Names refer to messages relative to the containing 1568 messages scope. For example, the two fields of OuterMessage refer 1569 to the same message type: 1570 1571 class Outer(Message): 1572 1573 inner_relative = MessageField('Inner', 1) 1574 inner_absolute = MessageField('Outer.Inner', 2) 1575 1576 class Inner(Message): 1577 ... 1578 1579 When resolving an actual type, MessageField will traverse the 1580 entire scope of nested messages to match a message name. This 1581 makes it easy for siblings to reference siblings: 1582 1583 class Outer(Message): 1584 1585 class Inner(Message): 1586 1587 sibling = MessageField('Sibling', 1) 1588 1589 class Sibling(Message): 1590 ... 1591 1592 """ 1593 1594 VARIANTS = frozenset([Variant.MESSAGE]) 1595 1596 DEFAULT_VARIANT = Variant.MESSAGE 1597 1598 @util.positional(3) 1599 def __init__(self, 1600 message_type, 1601 number, 1602 required=False, 1603 repeated=False, 1604 variant=None): 1605 """Constructor. 1606 1607 Args: 1608 message_type: Message type for field. Must be subclass of Message. 1609 number: Number of field. Must be unique per message class. 1610 required: Whether or not field is required. Mutually exclusive to 1611 'repeated'. 1612 repeated: Whether or not field is repeated. Mutually exclusive to 1613 'required'. 1614 variant: Wire-format variant hint. 1615 1616 Raises: 1617 FieldDefinitionError when invalid message_type is provided. 1618 """ 1619 valid_type = (isinstance(message_type, six.string_types) or 1620 (message_type is not Message and 1621 isinstance(message_type, type) and 1622 issubclass(message_type, Message))) 1623 1624 if not valid_type: 1625 raise FieldDefinitionError( 1626 'Invalid message class: %s' % message_type) 1627 1628 if isinstance(message_type, six.string_types): 1629 self.__type_name = message_type 1630 self.__type = None 1631 else: 1632 self.__type = message_type 1633 1634 super(MessageField, self).__init__(number, 1635 required=required, 1636 repeated=repeated, 1637 variant=variant) 1638 1639 def __set__(self, message_instance, value): 1640 """Set value on message. 1641 1642 Args: 1643 message_instance: Message instance to set value on. 1644 value: Value to set on message. 1645 """ 1646 t = self.type 1647 if isinstance(t, type) and issubclass(t, Message): 1648 if self.repeated: 1649 if value and isinstance(value, (list, tuple)): 1650 value = [(t(**v) if isinstance(v, dict) else v) 1651 for v in value] 1652 elif isinstance(value, dict): 1653 value = t(**value) 1654 super(MessageField, self).__set__(message_instance, value) 1655 1656 @property 1657 def type(self): 1658 """Message type used for field.""" 1659 if self.__type is None: 1660 message_type = find_definition( 1661 self.__type_name, self.message_definition()) 1662 if not (message_type is not Message and 1663 isinstance(message_type, type) and 1664 issubclass(message_type, Message)): 1665 raise FieldDefinitionError( 1666 'Invalid message class: %s' % message_type) 1667 self.__type = message_type 1668 return self.__type 1669 1670 @property 1671 def message_type(self): 1672 """Underlying message type used for serialization. 1673 1674 Will always be a sub-class of Message. This is different from type 1675 which represents the python value that message_type is mapped to for 1676 use by the user. 1677 """ 1678 return self.type 1679 1680 def value_from_message(self, message): 1681 """Convert a message to a value instance. 1682 1683 Used by deserializers to convert from underlying messages to 1684 value of expected user type. 1685 1686 Args: 1687 message: A message instance of type self.message_type. 1688 1689 Returns: 1690 Value of self.message_type. 1691 """ 1692 if not isinstance(message, self.message_type): 1693 raise DecodeError('Expected type %s, got %s: %r' % 1694 (self.message_type.__name__, 1695 type(message).__name__, 1696 message)) 1697 return message 1698 1699 def value_to_message(self, value): 1700 """Convert a value instance to a message. 1701 1702 Used by serializers to convert Python user types to underlying 1703 messages for transmission. 1704 1705 Args: 1706 value: A value of type self.type. 1707 1708 Returns: 1709 An instance of type self.message_type. 1710 """ 1711 if not isinstance(value, self.type): 1712 raise EncodeError('Expected type %s, got %s: %r' % 1713 (self.type.__name__, 1714 type(value).__name__, 1715 value)) 1716 return value 1717 1718 1719class EnumField(Field): 1720 """Field definition for enum values. 1721 1722 Enum fields may have default values that are delayed until the 1723 associated enum type is resolved. This is necessary to support 1724 certain circular references. 1725 1726 For example: 1727 1728 class Message1(Message): 1729 1730 class Color(Enum): 1731 1732 RED = 1 1733 GREEN = 2 1734 BLUE = 3 1735 1736 # This field default value will be validated when default is accessed. 1737 animal = EnumField('Message2.Animal', 1, default='HORSE') 1738 1739 class Message2(Message): 1740 1741 class Animal(Enum): 1742 1743 DOG = 1 1744 CAT = 2 1745 HORSE = 3 1746 1747 # This fields default value will be validated right away since Color 1748 # is already fully resolved. 1749 color = EnumField(Message1.Color, 1, default='RED') 1750 """ 1751 1752 VARIANTS = frozenset([Variant.ENUM]) 1753 1754 DEFAULT_VARIANT = Variant.ENUM 1755 1756 def __init__(self, enum_type, number, **kwargs): 1757 """Constructor. 1758 1759 Args: 1760 enum_type: Enum type for field. Must be subclass of Enum. 1761 number: Number of field. Must be unique per message class. 1762 required: Whether or not field is required. Mutually exclusive to 1763 'repeated'. 1764 repeated: Whether or not field is repeated. Mutually exclusive to 1765 'required'. 1766 variant: Wire-format variant hint. 1767 default: Default value for field if not found in stream. 1768 1769 Raises: 1770 FieldDefinitionError when invalid enum_type is provided. 1771 """ 1772 valid_type = (isinstance(enum_type, six.string_types) or 1773 (enum_type is not Enum and 1774 isinstance(enum_type, type) and 1775 issubclass(enum_type, Enum))) 1776 1777 if not valid_type: 1778 raise FieldDefinitionError('Invalid enum type: %s' % enum_type) 1779 1780 if isinstance(enum_type, six.string_types): 1781 self.__type_name = enum_type 1782 self.__type = None 1783 else: 1784 self.__type = enum_type 1785 1786 super(EnumField, self).__init__(number, **kwargs) 1787 1788 def validate_default_element(self, value): 1789 """Validate default element of Enum field. 1790 1791 Enum fields allow for delayed resolution of default values 1792 when the type of the field has not been resolved. The default 1793 value of a field may be a string or an integer. If the Enum 1794 type of the field has been resolved, the default value is 1795 validated against that type. 1796 1797 Args: 1798 value: Value to validate. 1799 1800 Raises: 1801 ValidationError if value is not expected message type. 1802 1803 """ 1804 if isinstance(value, (six.string_types, six.integer_types)): 1805 # Validation of the value does not happen for delayed resolution 1806 # enumerated types. Ignore if type is not yet resolved. 1807 if self.__type: 1808 self.__type(value) 1809 return value 1810 1811 return super(EnumField, self).validate_default_element(value) 1812 1813 @property 1814 def type(self): 1815 """Enum type used for field.""" 1816 if self.__type is None: 1817 found_type = find_definition( 1818 self.__type_name, self.message_definition()) 1819 if not (found_type is not Enum and 1820 isinstance(found_type, type) and 1821 issubclass(found_type, Enum)): 1822 raise FieldDefinitionError( 1823 'Invalid enum type: %s' % found_type) 1824 1825 self.__type = found_type 1826 return self.__type 1827 1828 @property 1829 def default(self): 1830 """Default for enum field. 1831 1832 Will cause resolution of Enum type and unresolved default value. 1833 """ 1834 try: 1835 return self.__resolved_default 1836 except AttributeError: 1837 resolved_default = super(EnumField, self).default 1838 if isinstance(resolved_default, (six.string_types, 1839 six.integer_types)): 1840 # pylint:disable=not-callable 1841 resolved_default = self.type(resolved_default) 1842 self.__resolved_default = resolved_default 1843 return self.__resolved_default 1844 1845 1846@util.positional(2) 1847def find_definition(name, relative_to=None, importer=__import__): 1848 """Find definition by name in module-space. 1849 1850 The find algorthm will look for definitions by name relative to a 1851 message definition or by fully qualfied name. If no definition is 1852 found relative to the relative_to parameter it will do the same 1853 search against the container of relative_to. If relative_to is a 1854 nested Message, it will search its message_definition(). If that 1855 message has no message_definition() it will search its module. If 1856 relative_to is a module, it will attempt to look for the 1857 containing module and search relative to it. If the module is a 1858 top-level module, it will look for the a message using a fully 1859 qualified name. If no message is found then, the search fails and 1860 DefinitionNotFoundError is raised. 1861 1862 For example, when looking for any definition 'foo.bar.ADefinition' 1863 relative to an actual message definition abc.xyz.SomeMessage: 1864 1865 find_definition('foo.bar.ADefinition', SomeMessage) 1866 1867 It is like looking for the following fully qualified names: 1868 1869 abc.xyz.SomeMessage. foo.bar.ADefinition 1870 abc.xyz. foo.bar.ADefinition 1871 abc. foo.bar.ADefinition 1872 foo.bar.ADefinition 1873 1874 When resolving the name relative to Message definitions and modules, the 1875 algorithm searches any Messages or sub-modules found in its path. 1876 Non-Message values are not searched. 1877 1878 A name that begins with '.' is considered to be a fully qualified 1879 name. The name is always searched for from the topmost package. 1880 For example, assume two message types: 1881 1882 abc.xyz.SomeMessage 1883 xyz.SomeMessage 1884 1885 Searching for '.xyz.SomeMessage' relative to 'abc' will resolve to 1886 'xyz.SomeMessage' and not 'abc.xyz.SomeMessage'. For this kind of name, 1887 the relative_to parameter is effectively ignored and always set to None. 1888 1889 For more information about package name resolution, please see: 1890 1891 http://code.google.com/apis/protocolbuffers/docs/proto.html#packages 1892 1893 Args: 1894 name: Name of definition to find. May be fully qualified or relative 1895 name. 1896 relative_to: Search for definition relative to message definition or 1897 module. None will cause a fully qualified name search. 1898 importer: Import function to use for resolving modules. 1899 1900 Returns: 1901 Enum or Message class definition associated with name. 1902 1903 Raises: 1904 DefinitionNotFoundError if no definition is found in any search path. 1905 1906 """ 1907 # Check parameters. 1908 if not (relative_to is None or 1909 isinstance(relative_to, types.ModuleType) or 1910 isinstance(relative_to, type) and 1911 issubclass(relative_to, Message)): 1912 raise TypeError( 1913 'relative_to must be None, Message definition or module.' 1914 ' Found: %s' % relative_to) 1915 1916 name_path = name.split('.') 1917 1918 # Handle absolute path reference. 1919 if not name_path[0]: 1920 relative_to = None 1921 name_path = name_path[1:] 1922 1923 def search_path(): 1924 """Performs a single iteration searching the path from relative_to. 1925 1926 This is the function that searches up the path from a relative object. 1927 1928 fully.qualified.object . relative.or.nested.Definition 1929 ----------------------------> 1930 ^ 1931 | 1932 this part of search --+ 1933 1934 Returns: 1935 Message or Enum at the end of name_path, else None. 1936 """ 1937 next_part = relative_to 1938 for node in name_path: 1939 # Look for attribute first. 1940 attribute = getattr(next_part, node, None) 1941 1942 if attribute is not None: 1943 next_part = attribute 1944 else: 1945 # If module, look for sub-module. 1946 if (next_part is None or 1947 isinstance(next_part, types.ModuleType)): 1948 if next_part is None: 1949 module_name = node 1950 else: 1951 module_name = '%s.%s' % (next_part.__name__, node) 1952 1953 try: 1954 fromitem = module_name.split('.')[-1] 1955 next_part = importer(module_name, '', '', 1956 [str(fromitem)]) 1957 except ImportError: 1958 return None 1959 else: 1960 return None 1961 1962 if not isinstance(next_part, types.ModuleType): 1963 if not (isinstance(next_part, type) and 1964 issubclass(next_part, (Message, Enum))): 1965 return None 1966 1967 return next_part 1968 1969 while True: 1970 found = search_path() 1971 if isinstance(found, type) and issubclass(found, (Enum, Message)): 1972 return found 1973 else: 1974 # Find next relative_to to search against. 1975 # 1976 # fully.qualified.object . relative.or.nested.Definition 1977 # <--------------------- 1978 # ^ 1979 # | 1980 # does this part of search 1981 if relative_to is None: 1982 # Fully qualified search was done. Nothing found. Fail. 1983 raise DefinitionNotFoundError( 1984 'Could not find definition for %s' % name) 1985 else: 1986 if isinstance(relative_to, types.ModuleType): 1987 # Find parent module. 1988 module_path = relative_to.__name__.split('.')[:-1] 1989 if not module_path: 1990 relative_to = None 1991 else: 1992 # Should not raise ImportError. If it does... 1993 # weird and unexpected. Propagate. 1994 relative_to = importer( 1995 '.'.join(module_path), '', '', [module_path[-1]]) 1996 elif (isinstance(relative_to, type) and 1997 issubclass(relative_to, Message)): 1998 parent = relative_to.message_definition() 1999 if parent is None: 2000 last_module_name = relative_to.__module__.split( 2001 '.')[-1] 2002 relative_to = importer( 2003 relative_to.__module__, '', '', [last_module_name]) 2004 else: 2005 relative_to = parent 2006