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