App Engine Python SDK version 1.8.1
[gae.git] / python / lib / protorpc / protorpc / messages.py
blob741072617529beadabaa803b08f4027304fcb4cd
1 #!/usr/bin/env python
3 # Copyright 2010 Google Inc.
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
9 # http://www.apache.org/licenses/LICENSE-2.0
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.
18 """Stand-alone implementation of in memory protocol messages.
20 Public Classes:
21 Enum: Represents an enumerated type.
22 Variant: Hint for wire format to determine how to serialize.
23 Message: Base class for user defined messages.
24 IntegerField: Field for integer values.
25 FloatField: Field for float values.
26 BooleanField: Field for boolean values.
27 BytesField: Field for binary string values.
28 StringField: Field for UTF-8 string values.
29 MessageField: Field for other message type values.
30 EnumField: Field for enumerated type values.
32 Public Exceptions (indentation indications class hierarchy):
33 EnumDefinitionError: Raised when enumeration is incorrectly defined.
34 FieldDefinitionError: Raised when field is incorrectly defined.
35 InvalidVariantError: Raised when variant is not compatible with field type.
36 InvalidDefaultError: Raised when default is not compatiable with field.
37 InvalidNumberError: Raised when field number is out of range or reserved.
38 MessageDefinitionError: Raised when message is incorrectly defined.
39 DuplicateNumberError: Raised when field has duplicate number with another.
40 ValidationError: Raised when a message or field is not valid.
41 DefinitionNotFoundError: Raised when definition not found.
42 """
44 __author__ = 'rafek@google.com (Rafe Kaplan)'
47 import inspect
48 import os
49 import sys
50 import traceback
51 import types
52 import weakref
54 from . import util
56 __all__ = ['MAX_ENUM_VALUE',
57 'MAX_FIELD_NUMBER',
58 'FIRST_RESERVED_FIELD_NUMBER',
59 'LAST_RESERVED_FIELD_NUMBER',
61 'Enum',
62 'Field',
63 'FieldList',
64 'Variant',
65 'Message',
66 'IntegerField',
67 'FloatField',
68 'BooleanField',
69 'BytesField',
70 'StringField',
71 'MessageField',
72 'EnumField',
73 'find_definition',
75 'Error',
76 'DecodeError',
77 'EncodeError',
78 'EnumDefinitionError',
79 'FieldDefinitionError',
80 'InvalidVariantError',
81 'InvalidDefaultError',
82 'InvalidNumberError',
83 'MessageDefinitionError',
84 'DuplicateNumberError',
85 'ValidationError',
86 'DefinitionNotFoundError',
90 # TODO(rafek): Add extended module test to ensure all exceptions
91 # in services extends Error.
92 Error = util.Error
95 class EnumDefinitionError(Error):
96 """Enumeration definition error."""
99 class FieldDefinitionError(Error):
100 """Field definition error."""
103 class InvalidVariantError(FieldDefinitionError):
104 """Invalid variant provided to field."""
107 class InvalidDefaultError(FieldDefinitionError):
108 """Invalid default provided to field."""
111 class InvalidNumberError(FieldDefinitionError):
112 """Invalid number provided to field."""
115 class MessageDefinitionError(Error):
116 """Message definition error."""
119 class DuplicateNumberError(Error):
120 """Duplicate number assigned to field."""
123 class DefinitionNotFoundError(Error):
124 """Raised when definition is not found."""
127 class DecodeError(Error):
128 """Error found decoding message from encoded form."""
131 class EncodeError(Error):
132 """Error found when encoding message."""
135 class ValidationError(Error):
136 """Invalid value for message error."""
138 def __str__(self):
139 """Prints string with field name if present on exception."""
140 message = Error.__str__(self)
141 try:
142 field_name = self.field_name
143 except AttributeError:
144 return message
145 else:
146 return message
149 # Attributes that are reserved by a class definition that
150 # may not be used by either Enum or Message class definitions.
151 _RESERVED_ATTRIBUTE_NAMES = frozenset(
152 ['__module__', '__doc__'])
154 _POST_INIT_FIELD_ATTRIBUTE_NAMES = frozenset(
155 ['name',
156 '_message_definition',
157 '_MessageField__type',
158 '_EnumField__type',
159 '_EnumField__resolved_default'])
161 _POST_INIT_ATTRIBUTE_NAMES = frozenset(
162 ['_message_definition'])
164 # Maximum enumeration value as defined by the protocol buffers standard.
165 # All enum values must be less than or equal to this value.
166 MAX_ENUM_VALUE = (2 ** 29) - 1
168 # Maximum field number as defined by the protocol buffers standard.
169 # All field numbers must be less than or equal to this value.
170 MAX_FIELD_NUMBER = (2 ** 29) - 1
172 # Field numbers between 19000 and 19999 inclusive are reserved by the
173 # protobuf protocol and may not be used by fields.
174 FIRST_RESERVED_FIELD_NUMBER = 19000
175 LAST_RESERVED_FIELD_NUMBER = 19999
178 class _DefinitionClass(type):
179 """Base meta-class used for definition meta-classes.
181 The Enum and Message definition classes share some basic functionality.
182 Both of these classes may be contained by a Message definition. After
183 initialization, neither class may have attributes changed
184 except for the protected _message_definition attribute, and that attribute
185 may change only once.
188 __initialized = False
190 def __init__(cls, name, bases, dct):
191 """Constructor."""
192 type.__init__(cls, name, bases, dct)
193 # Base classes may never be initialized.
194 if cls.__bases__ != (object,):
195 cls.__initialized = True
197 def message_definition(cls):
198 """Get outer Message definition that contains this definition.
200 Returns:
201 Containing Message definition if definition is contained within one,
202 else None.
204 try:
205 return cls._message_definition()
206 except AttributeError:
207 return None
209 def __setattr__(cls, name, value):
210 """Overridden so that cannot set variables on definition classes after init.
212 Setting attributes on a class must work during the period of initialization
213 to set the enumation value class variables and build the name/number maps.
214 Once __init__ has set the __initialized flag to True prohibits setting any
215 more values on the class. The class is in effect frozen.
217 Args:
218 name: Name of value to set.
219 value: Value to set.
221 if cls.__initialized and name not in _POST_INIT_ATTRIBUTE_NAMES:
222 raise AttributeError('May not change values: %s' % name)
223 else:
224 type.__setattr__(cls, name, value)
226 def __delattr__(cls, name):
227 """Overridden so that cannot delete varaibles on definition classes."""
228 raise TypeError('May not delete attributes on definition class')
230 def definition_name(cls):
231 """Helper method for creating definition name.
233 Names will be generated to include the classes package name, scope (if the
234 class is nested in another definition) and class name.
236 By default, the package name for a definition is derived from its module
237 name. However, this value can be overriden by placing a 'package' attribute
238 in the module that contains the definition class. For example:
240 package = 'some.alternate.package'
242 class MyMessage(Message):
245 >>> MyMessage.definition_name()
246 some.alternate.package.MyMessage
248 Returns:
249 Dot-separated fully qualified name of definition.
251 outer_definition_name = cls.outer_definition_name()
252 if outer_definition_name is None:
253 return unicode(cls.__name__)
254 else:
255 return u'%s.%s' % (outer_definition_name, cls.__name__)
257 def outer_definition_name(cls):
258 """Helper method for creating outer definition name.
260 Returns:
261 If definition is nested, will return the outer definitions name, else the
262 package name.
264 outer_definition = cls.message_definition()
265 if not outer_definition:
266 return util.get_package_for_module(cls.__module__)
267 else:
268 return outer_definition.definition_name()
270 def definition_package(cls):
271 """Helper method for creating creating the package of a definition.
273 Returns:
274 Name of package that definition belongs to.
276 outer_definition = cls.message_definition()
277 if not outer_definition:
278 return util.get_package_for_module(cls.__module__)
279 else:
280 return outer_definition.definition_package()
283 class _EnumClass(_DefinitionClass):
284 """Meta-class used for defining the Enum base class.
286 Meta-class enables very specific behavior for any defined Enum
287 class. All attributes defined on an Enum sub-class must be integers.
288 Each attribute defined on an Enum sub-class is translated
289 into an instance of that sub-class, with the name of the attribute
290 as its name, and the number provided as its value. It also ensures
291 that only one level of Enum class hierarchy is possible. In other
292 words it is not possible to delcare sub-classes of sub-classes of
293 Enum.
295 This class also defines some functions in order to restrict the
296 behavior of the Enum class and its sub-classes. It is not possible
297 to change the behavior of the Enum class in later classes since
298 any new classes may be defined with only integer values, and no methods.
301 def __init__(cls, name, bases, dct):
302 # Can only define one level of sub-classes below Enum.
303 if not (bases == (object,) or bases == (Enum,)):
304 raise EnumDefinitionError('Enum type %s may only inherit from Enum' %
305 (name,))
307 cls.__by_number = {}
308 cls.__by_name = {}
310 # Enum base class does not need to be initialized or locked.
311 if bases != (object,):
312 # Replace integer with number.
313 for attribute, value in dct.iteritems():
315 # Module will be in every enum class.
316 if attribute in _RESERVED_ATTRIBUTE_NAMES:
317 continue
319 # Reject anything that is not an int.
320 if not isinstance(value, (int, long)):
321 raise EnumDefinitionError(
322 'May only use integers in Enum definitions. Found: %s = %s' %
323 (attribute, value))
325 # Protocol buffer standard recommends non-negative values.
326 # Reject negative values.
327 if value < 0:
328 raise EnumDefinitionError(
329 'Must use non-negative enum values. Found: %s = %d' %
330 (attribute, value))
332 if value > MAX_ENUM_VALUE:
333 raise EnumDefinitionError(
334 'Must use enum values less than or equal %d. Found: %s = %d' %
335 (MAX_ENUM_VALUE, attribute, value))
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))
342 # Create enum instance and list in new Enum type.
343 instance = object.__new__(cls)
344 cls.__init__(instance, attribute, value)
345 cls.__by_name[instance.name] = instance
346 cls.__by_number[instance.number] = instance
347 setattr(cls, attribute, instance)
349 _DefinitionClass.__init__(cls, name, bases, dct)
351 def __iter__(cls):
352 """Iterate over all values of enum.
354 Yields:
355 Enumeration instances of the Enum class in arbitrary order.
357 return cls.__by_number.itervalues()
359 def names(cls):
360 """Get all names for Enum.
362 Returns:
363 An iterator for names of the enumeration in arbitrary order.
365 return cls.__by_name.iterkeys()
367 def numbers(cls):
368 """Get all numbers for Enum.
370 Returns:
371 An iterator for all numbers of the enumeration in arbitrary order.
373 return cls.__by_number.iterkeys()
375 def lookup_by_name(cls, name):
376 """Look up Enum by name.
378 Args:
379 name: Name of enum to find.
381 Returns:
382 Enum sub-class instance of that value.
384 return cls.__by_name[name]
386 def lookup_by_number(cls, number):
387 """Look up Enum by number.
389 Args:
390 number: Number of enum to find.
392 Returns:
393 Enum sub-class instance of that value.
395 return cls.__by_number[number]
397 def __len__(cls):
398 return len(cls.__by_name)
401 class Enum(object):
402 """Base class for all enumerated types."""
404 __metaclass__ = _EnumClass
406 __slots__ = set(('name', 'number'))
408 def __new__(cls, index):
409 """Acts as look-up routine after class is initialized.
411 The purpose of overriding __new__ is to provide a way to treat
412 Enum subclasses as casting types, similar to how the int type
413 functions. A program can pass a string or an integer and this
414 method with "convert" that value in to an appropriate Enum instance.
416 Args:
417 index: Name or number to look up. During initialization
418 this is always the name of the new enum value.
420 Raises:
421 TypeError: When an inappropriate index value is passed provided.
423 # If is enum type of this class, return it.
424 if isinstance(index, cls):
425 return index
427 # If number, look up by number.
428 if isinstance(index, (int, long)):
429 try:
430 return cls.lookup_by_number(index)
431 except KeyError:
432 pass
434 # If name, look up by name.
435 if isinstance(index, basestring):
436 try:
437 return cls.lookup_by_name(index)
438 except KeyError:
439 pass
441 raise TypeError('No such value for %s in Enum %s' %
442 (index, cls.__name__))
444 def __init__(self, name, number=None):
445 """Initialize new Enum instance.
447 Since this should only be called during class initialization any
448 calls that happen after the class is frozen raises an exception.
450 # Immediately return if __init__ was called after _Enum.__init__().
451 # It means that casting operator version of the class constructor
452 # is being used.
453 if getattr(type(self), '_DefinitionClass__initialized'):
454 return
455 object.__setattr__(self, 'name', name)
456 object.__setattr__(self, 'number', number)
458 def __setattr__(self, name, value):
459 raise TypeError('May not change enum values')
461 def __str__(self):
462 return self.name
464 def __int__(self):
465 return self.number
467 def __repr__(self):
468 return '%s(%s, %d)' % (type(self).__name__, self.name, self.number)
470 def __cmp__(self, other):
471 """Order is by number."""
472 if isinstance(other, type(self)):
473 return cmp(self.number, other.number)
474 return NotImplemented
476 @classmethod
477 def to_dict(cls):
478 """Make dictionary version of enumerated class.
480 Dictionary created this way can be used with def_num.
482 Returns:
483 A dict (name) -> number
485 return dict((item.name, item.number) for item in iter(cls))
487 @staticmethod
488 def def_enum(dct, name):
489 """Define enum class from dictionary.
491 Args:
492 dct: Dictionary of enumerated values for type.
493 name: Name of enum.
495 return type(name, (Enum,), dct)
498 # TODO(rafek): Determine to what degree this enumeration should be compatible
499 # with FieldDescriptor.Type in:
501 # http://code.google.com/p/protobuf/source/browse/trunk/src/google/protobuf/descriptor.proto
502 class Variant(Enum):
503 """Wire format variant.
505 Used by the 'protobuf' wire format to determine how to transmit
506 a single piece of data. May be used by other formats.
508 See: http://code.google.com/apis/protocolbuffers/docs/encoding.html
510 Values:
511 DOUBLE: 64-bit floating point number.
512 FLOAT: 32-bit floating point number.
513 INT64: 64-bit signed integer.
514 UINT64: 64-bit unsigned integer.
515 INT32: 32-bit signed integer.
516 BOOL: Boolean value (True or False).
517 STRING: String of UTF-8 encoded text.
518 MESSAGE: Embedded message as byte string.
519 BYTES: String of 8-bit bytes.
520 UINT32: 32-bit unsigned integer.
521 ENUM: Enum value as integer.
522 SINT32: 32-bit signed integer. Uses "zig-zag" encoding.
523 SINT64: 64-bit signed integer. Uses "zig-zag" encoding.
525 DOUBLE = 1
526 FLOAT = 2
527 INT64 = 3
528 UINT64 = 4
529 INT32 = 5
530 BOOL = 8
531 STRING = 9
532 MESSAGE = 11
533 BYTES = 12
534 UINT32 = 13
535 ENUM = 14
536 SINT32 = 17
537 SINT64 = 18
540 class _MessageClass(_DefinitionClass):
541 """Meta-class used for defining the Message base class.
543 For more details about Message classes, see the Message class docstring.
544 Information contained there may help understanding this class.
546 Meta-class enables very specific behavior for any defined Message
547 class. All attributes defined on an Message sub-class must be field
548 instances, Enum class definitions or other Message class definitions. Each
549 field attribute defined on an Message sub-class is added to the set of
550 field definitions and the attribute is translated in to a slot. It also
551 ensures that only one level of Message class hierarchy is possible. In other
552 words it is not possible to declare sub-classes of sub-classes of
553 Message.
555 This class also defines some functions in order to restrict the
556 behavior of the Message class and its sub-classes. It is not possible
557 to change the behavior of the Message class in later classes since
558 any new classes may be defined with only field, Enums and Messages, and
559 no methods.
562 def __new__(cls, name, bases, dct):
563 """Create new Message class instance.
565 The __new__ method of the _MessageClass type is overridden so as to
566 allow the translation of Field instances to slots.
568 by_number = {}
569 by_name = {}
571 variant_map = {}
573 if bases != (object,):
574 # Can only define one level of sub-classes below Message.
575 if bases != (Message,):
576 raise MessageDefinitionError(
577 'Message types may only inherit from Message')
579 enums = []
580 messages = []
581 # Must not use iteritems because this loop will change the state of dct.
582 for key, field in dct.items():
584 if key in _RESERVED_ATTRIBUTE_NAMES:
585 continue
587 if isinstance(field, type) and issubclass(field, Enum):
588 enums.append(key)
589 continue
591 if (isinstance(field, type) and
592 issubclass(field, Message) and
593 field is not Message):
594 messages.append(key)
595 continue
597 # Reject anything that is not a field.
598 if type(field) is Field or not isinstance(field, Field):
599 raise MessageDefinitionError(
600 'May only use fields in message definitions. Found: %s = %s' %
601 (key, field))
603 if field.number in by_number:
604 raise DuplicateNumberError(
605 'Field with number %d declared more than once in %s' %
606 (field.number, name))
608 field.name = key
610 # Place in name and number maps.
611 by_name[key] = field
612 by_number[field.number] = field
614 # Add enums if any exist.
615 if enums:
616 dct['__enums__'] = sorted(enums)
618 # Add messages if any exist.
619 if messages:
620 dct['__messages__'] = sorted(messages)
622 dct['_Message__by_number'] = by_number
623 dct['_Message__by_name'] = by_name
625 return _DefinitionClass.__new__(cls, name, bases, dct)
627 def __init__(cls, name, bases, dct):
628 """Initializer required to assign references to new class."""
629 if bases != (object,):
630 for value in dct.itervalues():
631 if isinstance(value, _DefinitionClass) and not value is Message:
632 value._message_definition = weakref.ref(cls)
634 for field in cls.all_fields():
635 field._message_definition = weakref.ref(cls)
637 _DefinitionClass.__init__(cls, name, bases, dct)
640 class Message(object):
641 """Base class for user defined message objects.
643 Used to define messages for efficient transmission across network or
644 process space. Messages are defined using the field classes (IntegerField,
645 FloatField, EnumField, etc.).
647 Messages are more restricted than normal classes in that they may only
648 contain field attributes and other Message and Enum definitions. These
649 restrictions are in place because the structure of the Message class is
650 intentended to itself be transmitted across network or process space and
651 used directly by clients or even other servers. As such methods and
652 non-field attributes could not be transmitted with the structural information
653 causing discrepancies between different languages and implementations.
655 Initialization and validation:
657 A Message object is considered to be initialized if it has all required
658 fields and any nested messages are also initialized.
660 Calling 'check_initialized' will raise a ValidationException if it is not
661 initialized; 'is_initialized' returns a boolean value indicating if it is
662 valid.
664 Validation automatically occurs when Message objects are created
665 and populated. Validation that a given value will be compatible with
666 a field that it is assigned to can be done through the Field instances
667 validate() method. The validate method used on a message will check that
668 all values of a message and its sub-messages are valid. Assingning an
669 invalid value to a field will raise a ValidationException.
671 Example:
673 # Trade type.
674 class TradeType(Enum):
675 BUY = 1
676 SELL = 2
677 SHORT = 3
678 CALL = 4
680 class Lot(Message):
681 price = IntegerField(1, required=True)
682 quantity = IntegerField(2, required=True)
684 class Order(Message):
685 symbol = StringField(1, required=True)
686 total_quantity = IntegerField(2, required=True)
687 trade_type = EnumField(TradeType, 3, required=True)
688 lots = MessageField(Lot, 4, repeated=True)
689 limit = IntegerField(5)
691 order = Order(symbol='GOOG',
692 total_quantity=10,
693 trade_type=TradeType.BUY)
695 lot1 = Lot(price=304,
696 quantity=7)
698 lot2 = Lot(price = 305,
699 quantity=3)
701 order.lots = [lot1, lot2]
703 # Now object is initialized!
704 order.check_initialized()
707 __metaclass__ = _MessageClass
709 def __init__(self, **kwargs):
710 """Initialize internal messages state.
712 Args:
713 A message can be initialized via the constructor by passing in keyword
714 arguments corresponding to fields. For example:
716 class Date(Message):
717 day = IntegerField(1)
718 month = IntegerField(2)
719 year = IntegerField(3)
721 Invoking:
723 date = Date(day=6, month=6, year=1911)
725 is the same as doing:
727 date = Date()
728 date.day = 6
729 date.month = 6
730 date.year = 1911
732 # Tag being an essential implementation detail must be private.
733 self.__tags = {}
734 self.__unrecognized_fields = {}
736 assigned = set()
737 for name, value in kwargs.iteritems():
738 setattr(self, name, value)
739 assigned.add(name)
741 # initialize repeated fields.
742 for field in self.all_fields():
743 if field.repeated and field.name not in assigned:
744 setattr(self, field.name, [])
747 def check_initialized(self):
748 """Check class for initialization status.
750 Check that all required fields are initialized
752 Raises:
753 ValidationError: If message is not initialized.
755 for name, field in self.__by_name.iteritems():
756 value = getattr(self, name)
757 if value is None:
758 if field.required:
759 raise ValidationError("Message %s is missing required field %s" %
760 (type(self).__name__, name))
761 else:
762 try:
763 if (isinstance(field, MessageField) and
764 issubclass(field.message_type, Message)):
765 if field.repeated:
766 for item in value:
767 item_message_value = field.value_to_message(item)
768 item_message_value.check_initialized()
769 else:
770 message_value = field.value_to_message(value)
771 message_value.check_initialized()
772 except ValidationError, err:
773 if not hasattr(err, 'message_name'):
774 err.message_name = type(self).__name__
775 raise
777 def is_initialized(self):
778 """Get initialization status.
780 Returns:
781 True if message is valid, else False.
783 try:
784 self.check_initialized()
785 except ValidationError:
786 return False
787 else:
788 return True
790 @classmethod
791 def all_fields(cls):
792 """Get all field definition objects.
794 Ordering is arbitrary.
796 Returns:
797 Iterator over all values in arbitrary order.
799 return cls.__by_name.itervalues()
801 @classmethod
802 def field_by_name(cls, name):
803 """Get field by name.
805 Returns:
806 Field object associated with name.
808 Raises:
809 KeyError if no field found by that name.
811 return cls.__by_name[name]
813 @classmethod
814 def field_by_number(cls, number):
815 """Get field by number.
817 Returns:
818 Field object associated with number.
820 Raises:
821 KeyError if no field found by that number.
823 return cls.__by_number[number]
825 def get_assigned_value(self, name):
826 """Get the assigned value of an attribute.
828 Get the underlying value of an attribute. If value has not been set, will
829 not return the default for the field.
831 Args:
832 name: Name of attribute to get.
834 Returns:
835 Value of attribute, None if it has not been set.
837 message_type = type(self)
838 try:
839 field = message_type.field_by_name(name)
840 except KeyError:
841 raise AttributeError('Message %s has no field %s' % (
842 message_type.__name__, name))
843 return self.__tags.get(field.number)
845 def reset(self, name):
846 """Reset assigned value for field.
848 Resetting a field will return it to its default value or None.
850 Args:
851 name: Name of field to reset.
853 message_type = type(self)
854 try:
855 field = message_type.field_by_name(name)
856 except KeyError:
857 if name not in message_type.__by_name:
858 raise AttributeError('Message %s has no field %s' % (
859 message_type.__name__, name))
860 self.__tags.pop(field.number, None)
862 def all_unrecognized_fields(self):
863 """Get the names of all unrecognized fields in this message."""
864 return self.__unrecognized_fields.keys()
866 def get_unrecognized_field_info(self, key, value_default=None,
867 variant_default=None):
868 """Get the value and variant of an unknown field in this message.
870 Args:
871 key: The name or number of the field to retrieve.
872 value_default: Value to be returned if the key isn't found.
873 variant_default: Value to be returned as variant if the key isn't
874 found.
876 Returns:
877 (value, variant), where value and variant are whatever was passed
878 to set_unrecognized_field.
880 value, variant = self.__unrecognized_fields.get(key, (value_default,
881 variant_default))
882 return value, variant
884 def set_unrecognized_field(self, key, value, variant):
885 """Set an unrecognized field, used when decoding a message.
887 Args:
888 key: The name or number used to refer to this unknown value.
889 value: The value of the field.
890 variant: Type information needed to interpret the value or re-encode it.
892 Raises:
893 TypeError: If the variant is not an instance of messages.Variant.
895 if not isinstance(variant, Variant):
896 raise TypeError('Variant type %s is not valid.' % variant)
897 self.__unrecognized_fields[key] = value, variant
899 def __setattr__(self, name, value):
900 """Change set behavior for messages.
902 Messages may only be assigned values that are fields.
904 Does not try to validate field when set.
906 Args:
907 name: Name of field to assign to.
908 vlaue: Value to assign to field.
910 Raises:
911 AttributeError when trying to assign value that is not a field.
913 if name in self.__by_name or name.startswith('_Message__'):
914 object.__setattr__(self, name, value)
915 else:
916 raise AttributeError("May not assign arbitrary value %s "
917 "to message %s" % (name, type(self).__name__))
919 def __repr__(self):
920 """Make string representation of message.
922 Example:
924 class MyMessage(messages.Message):
925 integer_value = messages.IntegerField(1)
926 string_value = messages.StringField(2)
928 my_message = MyMessage()
929 my_message.integer_value = 42
930 my_message.string_value = u'A string'
932 print my_message
933 >>> <MyMessage
934 ... integer_value: 42
935 ... string_value: u'A string'>
937 Returns:
938 String representation of message, including the values
939 of all fields and repr of all sub-messages.
941 body = ['<', type(self).__name__]
942 for field in sorted(self.all_fields(),
943 key=lambda f: f.number):
944 attribute = field.name
945 value = self.get_assigned_value(field.name)
946 if value is not None:
947 body.append('\n %s: %s' % (attribute, repr(value)))
948 body.append('>')
949 return ''.join(body)
951 def __eq__(self, other):
952 """Equality operator.
954 Does field by field comparison with other message. For
955 equality, must be same type and values of all fields must be
956 equal.
958 Messages not required to be initialized for comparison.
960 Does not attempt to determine equality for values that have
961 default values that are not set. In other words:
963 class HasDefault(Message):
965 attr1 = StringField(1, default='default value')
967 message1 = HasDefault()
968 message2 = HasDefault()
969 message2.attr1 = 'default value'
971 message1 != message2
973 Does not compare unknown values.
975 Args:
976 other: Other message to compare with.
978 # TODO(rafek): Implement "equivalent" which does comparisons
979 # taking default values in to consideration.
980 if self is other:
981 return True
983 if type(self) is not type(other):
984 return False
986 return self.__tags == other.__tags
988 def __ne__(self, other):
989 """Not equals operator.
991 Does field by field comparison with other message. For
992 non-equality, must be different type or any value of a field must be
993 non-equal to the same field in the other instance.
995 Messages not required to be initialized for comparison.
997 Args:
998 other: Other message to compare with.
1000 return not self.__eq__(other)
1003 class FieldList(list):
1004 """List implementation that validates field values.
1006 This list implementation overrides all methods that add values in to a list
1007 in order to validate those new elements. Attempting to add or set list
1008 values that are not of the correct type will raise ValidationError.
1011 def __init__(self, field_instance, sequence):
1012 """Constructor.
1014 Args:
1015 field_instance: Instance of field that validates the list.
1016 sequence: List or tuple to construct list from.
1018 if not field_instance.repeated:
1019 raise FieldDefinitionError('FieldList may only accept repeated fields')
1020 self.__field = field_instance
1021 self.__field.validate(sequence)
1022 list.__init__(self, sequence)
1024 @property
1025 def field(self):
1026 """Field that validates list."""
1027 return self.__field
1029 def __setslice__(self, i, j, sequence):
1030 """Validate slice assignment to list."""
1031 self.__field.validate(sequence)
1032 list.__setslice__(self, i, j, sequence)
1034 def __setitem__(self, index, value):
1035 """Validate item assignment to list."""
1036 self.__field.validate_element(value)
1037 list.__setitem__(self, index, value)
1039 def append(self, value):
1040 """Validate item appending to list."""
1041 self.__field.validate_element(value)
1042 return list.append(self, value)
1044 def extend(self, sequence):
1045 """Validate extension of list."""
1046 self.__field.validate(sequence)
1047 return list.extend(self, sequence)
1049 def insert(self, index, value):
1050 """Validate item insertion to list."""
1051 self.__field.validate_element(value)
1052 return list.insert(self, index, value)
1055 # TODO(rafek): Prevent additional field subclasses.
1056 class Field(object):
1058 __variant_to_type = {}
1060 class __metaclass__(type):
1062 def __init__(cls, name, bases, dct):
1063 getattr(cls, '_Field__variant_to_type').update(
1064 (variant, cls) for variant in dct.get('VARIANTS', []))
1065 type.__init__(cls, name, bases, dct)
1067 __initialized = False
1069 @util.positional(2)
1070 def __init__(self,
1071 number,
1072 required=False,
1073 repeated=False,
1074 variant=None,
1075 default=None):
1076 """Constructor.
1078 The required and repeated parameters are mutually exclusive. Setting both
1079 to True will raise a FieldDefinitionError.
1081 Sub-class Attributes:
1082 Each sub-class of Field must define the following:
1083 VARIANTS: Set of variant types accepted by that field.
1084 DEFAULT_VARIANT: Default variant type if not specified in constructor.
1086 Args:
1087 number: Number of field. Must be unique per message class.
1088 required: Whether or not field is required. Mutually exclusive with
1089 'repeated'.
1090 repeated: Whether or not field is repeated. Mutually exclusive with
1091 'required'.
1092 variant: Wire-format variant hint.
1093 default: Default value for field if not found in stream.
1095 Raises:
1096 InvalidVariantError when invalid variant for field is provided.
1097 InvalidDefaultError when invalid default for field is provided.
1098 FieldDefinitionError when invalid number provided or mutually exclusive
1099 fields are used.
1100 InvalidNumberError when the field number is out of range or reserved.
1102 if not isinstance(number, int) or not 1 <= number <= MAX_FIELD_NUMBER:
1103 raise InvalidNumberError('Invalid number for field: %s\n'
1104 'Number must be 1 or greater and %d or less' %
1105 (number, MAX_FIELD_NUMBER))
1107 if FIRST_RESERVED_FIELD_NUMBER <= number <= LAST_RESERVED_FIELD_NUMBER:
1108 raise InvalidNumberError('Tag number %d is a reserved number.\n'
1109 'Numbers %d to %d are reserved' %
1110 (number, FIRST_RESERVED_FIELD_NUMBER,
1111 LAST_RESERVED_FIELD_NUMBER))
1113 if repeated and required:
1114 raise FieldDefinitionError('Cannot set both repeated and required')
1116 if variant is None:
1117 variant = self.DEFAULT_VARIANT
1119 if repeated and default is not None:
1120 raise FieldDefinitionError('Repeated fields may not have defaults')
1122 if variant not in self.VARIANTS:
1123 raise InvalidVariantError(
1124 'Invalid variant: %s\nValid variants for %s are %r' %
1125 (variant, type(self).__name__, sorted(self.VARIANTS)))
1127 self.number = number
1128 self.required = required
1129 self.repeated = repeated
1130 self.variant = variant
1132 if default is not None:
1133 try:
1134 self.validate_default(default)
1135 except ValidationError, err:
1136 try:
1137 name = self.name
1138 except AttributeError:
1139 # For when raising error before name initialization.
1140 raise InvalidDefaultError('Invalid default value for %s: %s: %s' %
1141 (self.__class__.__name__, default, err))
1142 else:
1143 raise InvalidDefaultError('Invalid default value for field %s: '
1144 '%s: %s' % (name, default, err))
1146 self.__default = default
1147 self.__initialized = True
1149 def __setattr__(self, name, value):
1150 """Setter overidden to prevent assignment to fields after creation.
1152 Args:
1153 name: Name of attribute to set.
1154 value: Value to assign.
1156 # Special case post-init names. They need to be set after constructor.
1157 if name in _POST_INIT_FIELD_ATTRIBUTE_NAMES:
1158 object.__setattr__(self, name, value)
1159 return
1161 # All other attributes must be set before __initialized.
1162 if not self.__initialized:
1163 # Not initialized yet, allow assignment.
1164 object.__setattr__(self, name, value)
1165 else:
1166 raise AttributeError('Field objects are read-only')
1168 def __set__(self, message_instance, value):
1169 """Set value on message.
1171 Args:
1172 message_instance: Message instance to set value on.
1173 value: Value to set on message.
1175 # Reaches in to message instance directly to assign to private tags.
1176 if value is None:
1177 if self.repeated:
1178 raise ValidationError(
1179 'May not assign None to repeated field %s' % self.name)
1180 else:
1181 message_instance._Message__tags.pop(self.number, None)
1182 else:
1183 if self.repeated:
1184 value = FieldList(self, value)
1185 else:
1186 self.validate(value)
1187 message_instance._Message__tags[self.number] = value
1189 def __get__(self, message_instance, message_class):
1190 if message_instance is None:
1191 return self
1193 result = message_instance._Message__tags.get(self.number)
1194 if result is None:
1195 return self.default
1196 else:
1197 return result
1199 def validate_element(self, value):
1200 """Validate single element of field.
1202 This is different from validate in that it is used on individual
1203 values of repeated fields.
1205 Args:
1206 value: Value to validate.
1208 Raises:
1209 ValidationError if value is not expected type.
1211 if not isinstance(value, self.type):
1212 if value is None:
1213 if self.required:
1214 raise ValidationError('Required field is missing')
1215 else:
1216 try:
1217 name = self.name
1218 except AttributeError:
1219 raise ValidationError('Expected type %s for %s, '
1220 'found %s (type %s)' %
1221 (self.type, self.__class__.__name__,
1222 value, type(value)))
1223 else:
1224 raise ValidationError('Expected type %s for field %s, '
1225 'found %s (type %s)' %
1226 (self.type, name, value, type(value)))
1228 def __validate(self, value, validate_element):
1229 """Internal validation function.
1231 Validate an internal value using a function to validate individual elements.
1233 Args:
1234 value: Value to validate.
1235 validate_element: Function to use to validate individual elements.
1237 Raises:
1238 ValidationError if value is not expected type.
1240 if not self.repeated:
1241 validate_element(value)
1242 else:
1243 # Must be a list or tuple, may not be a string.
1244 if isinstance(value, (list, tuple)):
1245 for element in value:
1246 if element is None:
1247 try:
1248 name = self.name
1249 except AttributeError:
1250 raise ValidationError('Repeated values for %s '
1251 'may not be None' % self.__class__.__name__)
1252 else:
1253 raise ValidationError('Repeated values for field %s '
1254 'may not be None' % name)
1255 validate_element(element)
1256 elif value is not None:
1257 try:
1258 name = self.name
1259 except AttributeError:
1260 raise ValidationError('%s is repeated. Found: %s' % (
1261 self.__class__.__name__, value))
1262 else:
1263 raise ValidationError('Field %s is repeated. Found: %s' % (name,
1264 value))
1266 def validate(self, value):
1267 """Validate value assigned to field.
1269 Args:
1270 value: Value to validate.
1272 Raises:
1273 ValidationError if value is not expected type.
1275 self.__validate(value, self.validate_element)
1277 def validate_default_element(self, value):
1278 """Validate value as assigned to field default field.
1280 Some fields may allow for delayed resolution of default types necessary
1281 in the case of circular definition references. In this case, the default
1282 value might be a place holder that is resolved when needed after all the
1283 message classes are defined.
1285 Args:
1286 value: Default value to validate.
1288 Raises:
1289 ValidationError if value is not expected type.
1291 self.validate_element(value)
1293 def validate_default(self, value):
1294 """Validate default value assigned to field.
1296 Args:
1297 value: Value to validate.
1299 Raises:
1300 ValidationError if value is not expected type.
1302 self.__validate(value, self.validate_default_element)
1304 def message_definition(self):
1305 """Get Message definition that contains this Field definition.
1307 Returns:
1308 Containing Message definition for Field. Will return None if for
1309 some reason Field is defined outside of a Message class.
1311 try:
1312 return self._message_definition()
1313 except AttributeError:
1314 return None
1316 @property
1317 def default(self):
1318 """Get default value for field."""
1319 return self.__default
1321 @classmethod
1322 def lookup_field_type_by_variant(cls, variant):
1323 return cls.__variant_to_type[variant]
1326 class IntegerField(Field):
1327 """Field definition for integer values."""
1329 VARIANTS = frozenset([Variant.INT32,
1330 Variant.INT64,
1331 Variant.UINT32,
1332 Variant.UINT64,
1333 Variant.SINT32,
1334 Variant.SINT64,
1337 DEFAULT_VARIANT = Variant.INT64
1339 type = (int, long)
1342 class FloatField(Field):
1343 """Field definition for float values."""
1345 VARIANTS = frozenset([Variant.FLOAT,
1346 Variant.DOUBLE,
1349 DEFAULT_VARIANT = Variant.DOUBLE
1351 type = float
1354 class BooleanField(Field):
1355 """Field definition for boolean values."""
1357 VARIANTS = frozenset([Variant.BOOL])
1359 DEFAULT_VARIANT = Variant.BOOL
1361 type = bool
1364 class BytesField(Field):
1365 """Field definition for byte string values."""
1367 VARIANTS = frozenset([Variant.BYTES])
1369 DEFAULT_VARIANT = Variant.BYTES
1371 type = str
1374 class StringField(Field):
1375 """Field definition for unicode string values."""
1377 VARIANTS = frozenset([Variant.STRING])
1379 DEFAULT_VARIANT = Variant.STRING
1381 type = unicode
1383 def validate_element(self, value):
1384 """Validate StringField allowing for str and unicode.
1386 Raises:
1387 ValidationError if a str value is not 7-bit ascii.
1389 # If value is str is it considered valid. Satisfies "required=True".
1390 if isinstance(value, str):
1391 try:
1392 unicode(value)
1393 except UnicodeDecodeError, err:
1394 try:
1395 name = self.name
1396 except AttributeError:
1397 validation_error = ValidationError(
1398 'Field encountered non-ASCII string %s: %s' % (value,
1399 err))
1400 else:
1401 validation_error = ValidationError(
1402 'Field %s encountered non-ASCII string %s: %s' % (self.name,
1403 value,
1404 err))
1405 validation_error.field_name = self.name
1406 raise validation_error
1407 else:
1408 super(StringField, self).validate_element(value)
1411 class MessageField(Field):
1412 """Field definition for sub-message values.
1414 Message fields contain instance of other messages. Instances stored
1415 on messages stored on message fields are considered to be owned by
1416 the containing message instance and should not be shared between
1417 owning instances.
1419 Message fields must be defined to reference a single type of message.
1420 Normally message field are defined by passing the referenced message
1421 class in to the constructor.
1423 It is possible to define a message field for a type that does not yet
1424 exist by passing the name of the message in to the constructor instead
1425 of a message class. Resolution of the actual type of the message is
1426 deferred until it is needed, for example, during message verification.
1427 Names provided to the constructor must refer to a class within the same
1428 python module as the class that is using it. Names refer to messages
1429 relative to the containing messages scope. For example, the two fields
1430 of OuterMessage refer to the same message type:
1432 class Outer(Message):
1434 inner_relative = MessageField('Inner', 1)
1435 inner_absolute = MessageField('Outer.Inner', 2)
1437 class Inner(Message):
1440 When resolving an actual type, MessageField will traverse the entire
1441 scope of nested messages to match a message name. This makes it easy
1442 for siblings to reference siblings:
1444 class Outer(Message):
1446 class Inner(Message):
1448 sibling = MessageField('Sibling', 1)
1450 class Sibling(Message):
1454 VARIANTS = frozenset([Variant.MESSAGE])
1456 DEFAULT_VARIANT = Variant.MESSAGE
1458 @util.positional(3)
1459 def __init__(self,
1460 message_type,
1461 number,
1462 required=False,
1463 repeated=False,
1464 variant=None):
1465 """Constructor.
1467 Args:
1468 message_type: Message type for field. Must be subclass of Message.
1469 number: Number of field. Must be unique per message class.
1470 required: Whether or not field is required. Mutually exclusive to
1471 'repeated'.
1472 repeated: Whether or not field is repeated. Mutually exclusive to
1473 'required'.
1474 variant: Wire-format variant hint.
1476 Raises:
1477 FieldDefinitionError when invalid message_type is provided.
1479 valid_type = (isinstance(message_type, basestring) or
1480 (message_type is not Message and
1481 isinstance(message_type, type) and
1482 issubclass(message_type, Message)))
1484 if not valid_type:
1485 raise FieldDefinitionError('Invalid message class: %s' % message_type)
1487 if isinstance(message_type, basestring):
1488 self.__type_name = message_type
1489 self.__type = None
1490 else:
1491 self.__type = message_type
1493 super(MessageField, self).__init__(number,
1494 required=required,
1495 repeated=repeated,
1496 variant=variant)
1498 @property
1499 def type(self):
1500 """Message type used for field."""
1501 if self.__type is None:
1502 message_type = find_definition(self.__type_name, self.message_definition())
1503 if not (message_type is not Message and
1504 isinstance(message_type, type) and
1505 issubclass(message_type, Message)):
1506 raise FieldDefinitionError('Invalid message class: %s' % message_type)
1507 self.__type = message_type
1508 return self.__type
1510 @property
1511 def message_type(self):
1512 """Underlying message type used for serialization.
1514 Will always be a sub-class of Message. This is different from type
1515 which represents the python value that message_type is mapped to for
1516 use by the user.
1518 return self.type
1520 def value_from_message(self, message):
1521 """Convert a message to a value instance.
1523 Used by deserializers to convert from underlying messages to
1524 value of expected user type.
1526 Args:
1527 message: A message instance of type self.message_type.
1529 Returns:
1530 Value of self.message_type.
1532 if not isinstance(message, self.message_type):
1533 raise DecodeError('Expected type %s, got %s: %r' %
1534 (self.message_type.__name__,
1535 type(message).__name__,
1536 message))
1537 return message
1539 def value_to_message(self, value):
1540 """Convert a value instance to a message.
1542 Used by serializers to convert Python user types to underlying
1543 messages for transmission.
1545 Args:
1546 value: A value of type self.type.
1548 Returns:
1549 An instance of type self.message_type.
1551 if not isinstance(value, self.type):
1552 raise EncodeError('Expected type %s, got %s: %r' %
1553 (self.type.__name__,
1554 type(value).__name__,
1555 value))
1556 return value
1559 class EnumField(Field):
1560 """Field definition for enum values.
1562 Enum fields may have default values that are delayed until the associated enum
1563 type is resolved. This is necessary to support certain circular references.
1565 For example:
1567 class Message1(Message):
1569 class Color(Enum):
1571 RED = 1
1572 GREEN = 2
1573 BLUE = 3
1575 # This field default value will be validated when default is accessed.
1576 animal = EnumField('Message2.Animal', 1, default='HORSE')
1578 class Message2(Message):
1580 class Animal(Enum):
1582 DOG = 1
1583 CAT = 2
1584 HORSE = 3
1586 # This fields default value will be validated right away since Color is
1587 # already fully resolved.
1588 color = EnumField(Message1.Color, 1, default='RED')
1591 VARIANTS = frozenset([Variant.ENUM])
1593 DEFAULT_VARIANT = Variant.ENUM
1595 def __init__(self, enum_type, number, **kwargs):
1596 """Constructor.
1598 Args:
1599 enum_type: Enum type for field. Must be subclass of Enum.
1600 number: Number of field. Must be unique per message class.
1601 required: Whether or not field is required. Mutually exclusive to
1602 'repeated'.
1603 repeated: Whether or not field is repeated. Mutually exclusive to
1604 'required'.
1605 variant: Wire-format variant hint.
1606 default: Default value for field if not found in stream.
1608 Raises:
1609 FieldDefinitionError when invalid enum_type is provided.
1611 valid_type = (isinstance(enum_type, basestring) or
1612 (enum_type is not Enum and
1613 isinstance(enum_type, type) and
1614 issubclass(enum_type, Enum)))
1616 if not valid_type:
1617 raise FieldDefinitionError('Invalid enum type: %s' % enum_type)
1619 if isinstance(enum_type, basestring):
1620 self.__type_name = enum_type
1621 self.__type = None
1622 else:
1623 self.__type = enum_type
1625 super(EnumField, self).__init__(number, **kwargs)
1627 def validate_default_element(self, value):
1628 """Validate default element of Enum field.
1630 Enum fields allow for delayed resolution of default values when the type
1631 of the field has not been resolved. The default value of a field may be
1632 a string or an integer. If the Enum type of the field has been resolved,
1633 the default value is validated against that type.
1635 Args:
1636 value: Value to validate.
1638 Raises:
1639 ValidationError if value is not expected message type.
1641 if isinstance(value, (basestring, int, long)):
1642 # Validation of the value does not happen for delayed resolution
1643 # enumerated types. Ignore if type is not yet resolved.
1644 if self.__type:
1645 self.__type(value)
1646 return
1648 super(EnumField, self).validate_default_element(value)
1650 @property
1651 def type(self):
1652 """Enum type used for field."""
1653 if self.__type is None:
1654 found_type = find_definition(self.__type_name, self.message_definition())
1655 if not (found_type is not Enum and
1656 isinstance(found_type, type) and
1657 issubclass(found_type, Enum)):
1658 raise FieldDefinitionError('Invalid enum type: %s' % found_type)
1660 self.__type = found_type
1661 return self.__type
1663 @property
1664 def default(self):
1665 """Default for enum field.
1667 Will cause resolution of Enum type and unresolved default value.
1669 try:
1670 return self.__resolved_default
1671 except AttributeError:
1672 resolved_default = super(EnumField, self).default
1673 if isinstance(resolved_default, (basestring, int, long)):
1674 resolved_default = self.type(resolved_default)
1675 self.__resolved_default = resolved_default
1676 return self.__resolved_default
1679 @util.positional(2)
1680 def find_definition(name, relative_to=None, importer=__import__):
1681 """Find definition by name in module-space.
1683 The find algorthm will look for definitions by name relative to a message
1684 definition or by fully qualfied name. If no definition is found relative
1685 to the relative_to parameter it will do the same search against the container
1686 of relative_to. If relative_to is a nested Message, it will search its
1687 message_definition(). If that message has no message_definition() it will
1688 search its module. If relative_to is a module, it will attempt to look for
1689 the containing module and search relative to it. If the module is a top-level
1690 module, it will look for the a message using a fully qualified name. If
1691 no message is found then, the search fails and DefinitionNotFoundError is
1692 raised.
1694 For example, when looking for any definition 'foo.bar.ADefinition' relative to
1695 an actual message definition abc.xyz.SomeMessage:
1697 find_definition('foo.bar.ADefinition', SomeMessage)
1699 It is like looking for the following fully qualified names:
1701 abc.xyz.SomeMessage. foo.bar.ADefinition
1702 abc.xyz. foo.bar.ADefinition
1703 abc. foo.bar.ADefinition
1704 foo.bar.ADefinition
1706 When resolving the name relative to Message definitions and modules, the
1707 algorithm searches any Messages or sub-modules found in its path.
1708 Non-Message values are not searched.
1710 A name that begins with '.' is considered to be a fully qualified name. The
1711 name is always searched for from the topmost package. For example, assume
1712 two message types:
1714 abc.xyz.SomeMessage
1715 xyz.SomeMessage
1717 Searching for '.xyz.SomeMessage' relative to 'abc' will resolve to
1718 'xyz.SomeMessage' and not 'abc.xyz.SomeMessage'. For this kind of name,
1719 the relative_to parameter is effectively ignored and always set to None.
1721 For more information about package name resolution, please see:
1723 http://code.google.com/apis/protocolbuffers/docs/proto.html#packages
1725 Args:
1726 name: Name of definition to find. May be fully qualified or relative name.
1727 relative_to: Search for definition relative to message definition or module.
1728 None will cause a fully qualified name search.
1729 importer: Import function to use for resolving modules.
1731 Returns:
1732 Enum or Message class definition associated with name.
1734 Raises:
1735 DefinitionNotFoundError if no definition is found in any search path.
1737 # Check parameters.
1738 if not (relative_to is None or
1739 isinstance(relative_to, types.ModuleType) or
1740 isinstance(relative_to, type) and issubclass(relative_to, Message)):
1741 raise TypeError('relative_to must be None, Message definition or module. '
1742 'Found: %s' % relative_to)
1744 name_path = name.split('.')
1746 # Handle absolute path reference.
1747 if not name_path[0]:
1748 relative_to = None
1749 name_path = name_path[1:]
1751 def search_path():
1752 """Performs a single iteration searching the path from relative_to.
1754 This is the function that searches up the path from a relative object.
1756 fully.qualified.object . relative.or.nested.Definition
1757 ---------------------------->
1760 this part of search --+
1762 Returns:
1763 Message or Enum at the end of name_path, else None.
1765 next = relative_to
1766 for node in name_path:
1767 # Look for attribute first.
1768 attribute = getattr(next, node, None)
1770 if attribute is not None:
1771 next = attribute
1772 else:
1773 # If module, look for sub-module.
1774 if next is None or isinstance(next, types.ModuleType):
1775 if next is None:
1776 module_name = node
1777 else:
1778 module_name = '%s.%s' % (next.__name__, node)
1780 try:
1781 fromitem = module_name.split('.')[-1]
1782 next = importer(module_name, '', '', [str(fromitem)])
1783 except ImportError:
1784 return None
1785 else:
1786 return None
1788 if (not isinstance(next, types.ModuleType) and
1789 not (isinstance(next, type) and
1790 issubclass(next, (Message, Enum)))):
1791 return None
1793 return next
1795 while True:
1796 found = search_path()
1797 if isinstance(found, type) and issubclass(found, (Enum, Message)):
1798 return found
1799 else:
1800 # Find next relative_to to search against.
1802 # fully.qualified.object . relative.or.nested.Definition
1803 # <---------------------
1806 # does this part of search
1807 if relative_to is None:
1808 # Fully qualified search was done. Nothing found. Fail.
1809 raise DefinitionNotFoundError('Could not find definition for %s'
1810 % (name,))
1811 else:
1812 if isinstance(relative_to, types.ModuleType):
1813 # Find parent module.
1814 module_path = relative_to.__name__.split('.')[:-1]
1815 if not module_path:
1816 relative_to = None
1817 else:
1818 # Should not raise ImportError. If it does... weird and
1819 # unexepected. Propagate.
1820 relative_to = importer(
1821 '.'.join(module_path), '', '', [module_path[-1]])
1822 elif (isinstance(relative_to, type) and
1823 issubclass(relative_to, Message)):
1824 parent = relative_to.message_definition()
1825 if parent is None:
1826 last_module_name = relative_to.__module__.split('.')[-1]
1827 relative_to = importer(
1828 relative_to.__module__, '', '', [last_module_name])
1829 else:
1830 relative_to = parent