31 """Descriptors essentially contain exactly the information found in a .proto
32 file, in types that make this information accessible in Python.
35 __author__ =
'robinson@google.com (Will Robinson)'
42 _USE_C_DESCRIPTORS =
False
43 if api_implementation.Type() ==
'cpp':
48 _USE_C_DESCRIPTORS =
getattr(_message,
'_USE_C_DESCRIPTORS',
False)
52 """Base error for this module."""
56 """Error transforming between python proto type and corresponding C++ type."""
59 if _USE_C_DESCRIPTORS:
68 if isinstance(obj, cls._C_DESCRIPTOR_CLASS):
73 DescriptorMetaclass = type
77 """Wrapper class of threading.Lock(), which is allowed by 'with'."""
80 self = object.__new__(cls)
87 def __exit__(self, exc_type, exc_value, exc_tb):
91 _lock = threading.Lock()
96 """Descriptors base class.
98 This class is the base of all descriptor classes. It provides common options
99 related functionality.
102 has_options: True if the descriptor has non-default options. Usually it
103 is not necessary to read this -- just call GetOptions() which will
104 happily return the default instance. However, it's sometimes useful
105 for efficiency, and also useful inside the protobuf implementation to
106 avoid some bootstrapping issues.
109 if _USE_C_DESCRIPTORS:
112 _C_DESCRIPTOR_CLASS = ()
114 def __init__(self, options, serialized_options, options_class_name):
115 """Initialize the descriptor given its options message and the name of the
116 class of the options message. The name of the class is required in case
117 the options message is None and has to be created.
124 self.
has_options = (options
is not None)
or (serialized_options
is not None)
127 """Sets the descriptor's options
129 This function is used in generated proto2 files to update descriptor
130 options. It must not be used outside proto2.
139 """Retrieves descriptor options.
141 This method returns the options set or creates the default options for the
149 options_class =
getattr(descriptor_pb2,
151 except AttributeError:
152 raise RuntimeError(
'Unknown options class name %s!' %
166 """Common class for descriptors that can be nested."""
168 def __init__(self, options, options_class_name, name, full_name,
169 file, containing_type, serialized_start=None,
170 serialized_end=None, serialized_options=None):
174 options: Protocol message options or None
175 to use default message options.
176 options_class_name: (str) The class name of the above options.
178 name: (str) Name of this protocol message type.
179 full_name: (str) Fully-qualified name of this protocol message type,
180 which will include protocol "package" name and the name of any
182 file: (FileDescriptor) Reference to file info.
183 containing_type: if provided, this is a nested descriptor, with this
184 descriptor as parent, otherwise None.
185 serialized_start: The start index (inclusive) in block in the
186 file.serialized_pb that describes this descriptor.
187 serialized_end: The end index (exclusive) in block in the
188 file.serialized_pb that describes this descriptor.
189 serialized_options: Protocol message serilized options or None.
191 super(_NestedDescriptorBase, self).
__init__(
192 options, serialized_options, options_class_name)
205 """Copies this to the matching proto in descriptor_pb2.
208 proto: An empty proto instance from descriptor_pb2.
211 Error: If self couldnt be serialized, due to to few constructor arguments.
213 if (self.
file is not None and
216 proto.ParseFromString(self.
file.serialized_pb[
219 raise Error(
'Descriptor does not contain serialization.')
224 """Descriptor for a protocol message type.
226 A Descriptor instance has the following attributes:
228 name: (str) Name of this protocol message type.
229 full_name: (str) Fully-qualified name of this protocol message type,
230 which will include protocol "package" name and the name of any
233 containing_type: (Descriptor) Reference to the descriptor of the
234 type containing us, or None if this is top-level.
236 fields: (list of FieldDescriptors) Field descriptors for all
238 fields_by_number: (dict int -> FieldDescriptor) Same FieldDescriptor
239 objects as in |fields|, but indexed by "number" attribute in each
241 fields_by_name: (dict str -> FieldDescriptor) Same FieldDescriptor
242 objects as in |fields|, but indexed by "name" attribute in each
244 fields_by_camelcase_name: (dict str -> FieldDescriptor) Same
245 FieldDescriptor objects as in |fields|, but indexed by
246 "camelcase_name" attribute in each FieldDescriptor.
248 nested_types: (list of Descriptors) Descriptor references
249 for all protocol message types nested within this one.
250 nested_types_by_name: (dict str -> Descriptor) Same Descriptor
251 objects as in |nested_types|, but indexed by "name" attribute
254 enum_types: (list of EnumDescriptors) EnumDescriptor references
255 for all enums contained within this type.
256 enum_types_by_name: (dict str ->EnumDescriptor) Same EnumDescriptor
257 objects as in |enum_types|, but indexed by "name" attribute
258 in each EnumDescriptor.
259 enum_values_by_name: (dict str -> EnumValueDescriptor) Dict mapping
260 from enum value name to EnumValueDescriptor for that value.
262 extensions: (list of FieldDescriptor) All extensions defined directly
263 within this message type (NOT within a nested type).
264 extensions_by_name: (dict, string -> FieldDescriptor) Same FieldDescriptor
265 objects as |extensions|, but indexed by "name" attribute of each
268 is_extendable: Does this type define any extension ranges?
270 oneofs: (list of OneofDescriptor) The list of descriptors for oneof fields
272 oneofs_by_name: (dict str -> OneofDescriptor) Same objects as in |oneofs|,
273 but indexed by "name" attribute.
275 file: (FileDescriptor) Reference to file descriptor.
278 if _USE_C_DESCRIPTORS:
279 _C_DESCRIPTOR_CLASS = _message.Descriptor
281 def __new__(cls, name, full_name, filename, containing_type, fields,
282 nested_types, enum_types, extensions, options=None,
283 serialized_options=None,
284 is_extendable=True, extension_ranges=None, oneofs=None,
285 file=None, serialized_start=None, serialized_end=None,
287 _message.Message._CheckCalledFromGeneratedFile()
288 return _message.default_pool.FindMessageTypeByName(full_name)
293 def __init__(self, name, full_name, filename, containing_type, fields,
294 nested_types, enum_types, extensions, options=None,
295 serialized_options=None,
296 is_extendable=True, extension_ranges=None, oneofs=None,
297 file=None, serialized_start=None, serialized_end=None,
299 """Arguments to __init__() are as described in the description
300 of Descriptor fields above.
302 Note that filename is an obsolete argument, that is not used anymore.
303 Please use file.name to access this as an attribute.
306 options,
'MessageOptions', name, full_name, file,
307 containing_type, serialized_start=serialized_start,
308 serialized_end=serialized_end, serialized_options=serialized_options)
317 field.containing_type = self
323 for nested_type
in nested_types:
324 nested_type.containing_type = self
329 enum_type.containing_type = self
332 (v.name, v)
for t
in enum_types
for v
in t.values)
336 extension.extension_scope = self
340 self.
oneofs = oneofs
if oneofs
is not None else []
343 oneof.containing_type = self
344 self.
syntax = syntax
or "proto2"
350 (f.camelcase_name, f)
for f
in self.
fields)
354 """Returns the string name of an enum value.
356 This is just a small helper method to simplify a common operation.
359 enum: string name of the Enum.
360 value: int, value of the enum.
363 string name of the enum value.
366 KeyError if either the Enum doesn't exist or the value is not a valid
372 """Copies this to a descriptor_pb2.DescriptorProto.
375 proto: An empty descriptor_pb2.DescriptorProto.
394 """Descriptor for a single field in a .proto file.
396 A FieldDescriptor instance has the following attributes:
398 name: (str) Name of this field, exactly as it appears in .proto.
399 full_name: (str) Name of this field, including containing scope. This is
400 particularly relevant for extensions.
401 camelcase_name: (str) Camelcase name of this field.
402 index: (int) Dense, 0-indexed index giving the order that this
403 field textually appears within its message in the .proto file.
404 number: (int) Tag number declared for this field in the .proto file.
406 type: (One of the TYPE_* constants below) Declared type.
407 cpp_type: (One of the CPPTYPE_* constants below) C++ type used to
408 represent this field.
410 label: (One of the LABEL_* constants below) Tells whether this
411 field is optional, required, or repeated.
412 has_default_value: (bool) True if this field has a default value defined,
414 default_value: (Varies) Default value of this field. Only
415 meaningful for non-repeated scalar fields. Repeated fields
416 should always set this to [], and non-repeated composite
417 fields should always set this to None.
419 containing_type: (Descriptor) Descriptor of the protocol message
420 type that contains this field. Set by the Descriptor constructor
421 if we're passed into one.
422 Somewhat confusingly, for extension fields, this is the
423 descriptor of the EXTENDED message, not the descriptor
424 of the message containing this field. (See is_extension and
425 extension_scope below).
426 message_type: (Descriptor) If a composite field, a descriptor
427 of the message type contained in this field. Otherwise, this is None.
428 enum_type: (EnumDescriptor) If this field contains an enum, a
429 descriptor of that enum. Otherwise, this is None.
431 is_extension: True iff this describes an extension field.
432 extension_scope: (Descriptor) Only meaningful if is_extension is True.
433 Gives the message that immediately contains this extension field.
434 Will be None iff we're a top-level (file-level) extension field.
436 options: (descriptor_pb2.FieldOptions) Protocol message field options or
437 None to use default field options.
439 containing_oneof: (OneofDescriptor) If the field is a member of a oneof
440 union, contains its descriptor. Otherwise, None.
442 file: (FileDescriptor) Reference to file descriptor.
485 _PYTHON_TO_CPP_PROTO_TYPE_MAP = {
486 TYPE_DOUBLE: CPPTYPE_DOUBLE,
487 TYPE_FLOAT: CPPTYPE_FLOAT,
488 TYPE_ENUM: CPPTYPE_ENUM,
489 TYPE_INT64: CPPTYPE_INT64,
490 TYPE_SINT64: CPPTYPE_INT64,
491 TYPE_SFIXED64: CPPTYPE_INT64,
492 TYPE_UINT64: CPPTYPE_UINT64,
493 TYPE_FIXED64: CPPTYPE_UINT64,
494 TYPE_INT32: CPPTYPE_INT32,
495 TYPE_SFIXED32: CPPTYPE_INT32,
496 TYPE_SINT32: CPPTYPE_INT32,
497 TYPE_UINT32: CPPTYPE_UINT32,
498 TYPE_FIXED32: CPPTYPE_UINT32,
499 TYPE_BYTES: CPPTYPE_STRING,
500 TYPE_STRING: CPPTYPE_STRING,
501 TYPE_BOOL: CPPTYPE_BOOL,
502 TYPE_MESSAGE: CPPTYPE_MESSAGE,
503 TYPE_GROUP: CPPTYPE_MESSAGE
517 MAX_FIELD_NUMBER = (1 << 29) - 1
518 FIRST_RESERVED_FIELD_NUMBER = 19000
519 LAST_RESERVED_FIELD_NUMBER = 19999
521 if _USE_C_DESCRIPTORS:
522 _C_DESCRIPTOR_CLASS = _message.FieldDescriptor
524 def __new__(cls, name, full_name, index, number, type, cpp_type, label,
525 default_value, message_type, enum_type, containing_type,
526 is_extension, extension_scope, options=None,
527 serialized_options=None,
528 has_default_value=True, containing_oneof=None, json_name=None,
530 _message.Message._CheckCalledFromGeneratedFile()
532 return _message.default_pool.FindExtensionByName(full_name)
534 return _message.default_pool.FindFieldByName(full_name)
536 def __init__(self, name, full_name, index, number, type, cpp_type, label,
537 default_value, message_type, enum_type, containing_type,
538 is_extension, extension_scope, options=None,
539 serialized_options=None,
540 has_default_value=True, containing_oneof=None, json_name=None,
542 """The arguments are as described in the description of FieldDescriptor
545 Note that containing_type may be None, and may be set later if necessary
546 (to deal with circular references between message types, for example).
547 Likewise for extension_scope.
550 options, serialized_options,
'FieldOptions')
555 if json_name
is None:
572 if api_implementation.Type() ==
'cpp':
574 self.
_cdescriptor = _message.default_pool.FindExtensionByName(full_name)
576 self.
_cdescriptor = _message.default_pool.FindFieldByName(full_name)
588 """Converts from a Python proto type to a C++ Proto Type.
590 The Python ProtocolBuffer classes specify both the 'Python' datatype and the
591 'C++' datatype - and they're not the same. This helper method should
592 translate from one to another.
595 proto_type: the Python proto type (descriptor.FieldDescriptor.TYPE_*)
597 descriptor.FieldDescriptor.CPPTYPE_*, the C++ type.
599 TypeTransformationError: when the Python proto type isn't known.
602 return FieldDescriptor._PYTHON_TO_CPP_PROTO_TYPE_MAP[proto_type]
609 """Descriptor for an enum defined in a .proto file.
611 An EnumDescriptor instance has the following attributes:
613 name: (str) Name of the enum type.
614 full_name: (str) Full name of the type, including package name
615 and any enclosing type(s).
617 values: (list of EnumValueDescriptors) List of the values
619 values_by_name: (dict str -> EnumValueDescriptor) Same as |values|,
620 but indexed by the "name" field of each EnumValueDescriptor.
621 values_by_number: (dict int -> EnumValueDescriptor) Same as |values|,
622 but indexed by the "number" field of each EnumValueDescriptor.
623 containing_type: (Descriptor) Descriptor of the immediate containing
624 type of this enum, or None if this is an enum defined at the
625 top level in a .proto file. Set by Descriptor's constructor
626 if we're passed into one.
627 file: (FileDescriptor) Reference to file descriptor.
628 options: (descriptor_pb2.EnumOptions) Enum options message or
629 None to use default enum options.
632 if _USE_C_DESCRIPTORS:
633 _C_DESCRIPTOR_CLASS = _message.EnumDescriptor
635 def __new__(cls, name, full_name, filename, values,
636 containing_type=None, options=None,
637 serialized_options=None, file=None,
638 serialized_start=None, serialized_end=None):
639 _message.Message._CheckCalledFromGeneratedFile()
640 return _message.default_pool.FindEnumTypeByName(full_name)
642 def __init__(self, name, full_name, filename, values,
643 containing_type=None, options=None,
644 serialized_options=None, file=None,
645 serialized_start=None, serialized_end=None):
646 """Arguments are as described in the attribute description above.
648 Note that filename is an obsolete argument, that is not used anymore.
649 Please use file.name to access this as an attribute.
651 super(EnumDescriptor, self).
__init__(
652 options,
'EnumOptions', name, full_name, file,
653 containing_type, serialized_start=serialized_start,
654 serialized_end=serialized_end, serialized_options=serialized_options)
664 """Copies this to a descriptor_pb2.EnumDescriptorProto.
667 proto: An empty descriptor_pb2.EnumDescriptorProto.
675 """Descriptor for a single value within an enum.
677 name: (str) Name of this value.
678 index: (int) Dense, 0-indexed index giving the order that this
679 value appears textually within its enum in the .proto file.
680 number: (int) Actual number assigned to this enum value.
681 type: (EnumDescriptor) EnumDescriptor to which this value
682 belongs. Set by EnumDescriptor's constructor if we're
684 options: (descriptor_pb2.EnumValueOptions) Enum value options message or
685 None to use default enum value options options.
688 if _USE_C_DESCRIPTORS:
689 _C_DESCRIPTOR_CLASS = _message.EnumValueDescriptor
693 options=None, serialized_options=None):
694 _message.Message._CheckCalledFromGeneratedFile()
703 options=None, serialized_options=None):
704 """Arguments are as described in the attribute description above."""
706 options, serialized_options,
'EnumValueOptions')
714 """Descriptor for a oneof field.
716 name: (str) Name of the oneof field.
717 full_name: (str) Full name of the oneof field, including package name.
718 index: (int) 0-based index giving the order of the oneof field inside
720 containing_type: (Descriptor) Descriptor of the protocol message
721 type that contains this field. Set by the Descriptor constructor
722 if we're passed into one.
723 fields: (list of FieldDescriptor) The list of field descriptors this
727 if _USE_C_DESCRIPTORS:
728 _C_DESCRIPTOR_CLASS = _message.OneofDescriptor
731 cls, name, full_name, index, containing_type, fields, options=None,
732 serialized_options=None):
733 _message.Message._CheckCalledFromGeneratedFile()
734 return _message.default_pool.FindOneofByName(full_name)
737 self, name, full_name, index, containing_type, fields, options=None,
738 serialized_options=None):
739 """Arguments are as described in the attribute description above."""
741 options, serialized_options,
'OneofOptions')
751 """Descriptor for a service.
753 name: (str) Name of the service.
754 full_name: (str) Full name of the service, including package name.
755 index: (int) 0-indexed index giving the order that this services
756 definition appears withing the .proto file.
757 methods: (list of MethodDescriptor) List of methods provided by this
759 methods_by_name: (dict str -> MethodDescriptor) Same MethodDescriptor
760 objects as in |methods_by_name|, but indexed by "name" attribute in each
762 options: (descriptor_pb2.ServiceOptions) Service options message or
763 None to use default service options.
764 file: (FileDescriptor) Reference to file info.
767 if _USE_C_DESCRIPTORS:
768 _C_DESCRIPTOR_CLASS = _message.ServiceDescriptor
770 def __new__(cls, name, full_name, index, methods, options=None,
771 serialized_options=None, file=None,
772 serialized_start=None, serialized_end=None):
773 _message.Message._CheckCalledFromGeneratedFile()
774 return _message.default_pool.FindServiceByName(full_name)
776 def __init__(self, name, full_name, index, methods, options=None,
777 serialized_options=None, file=None,
778 serialized_start=None, serialized_end=None):
779 super(ServiceDescriptor, self).
__init__(
780 options,
'ServiceOptions', name, full_name, file,
781 None, serialized_start=serialized_start,
782 serialized_end=serialized_end, serialized_options=serialized_options)
788 method.containing_service = self
791 """Searches for the specified method, and returns its descriptor."""
795 """Copies this to a descriptor_pb2.ServiceDescriptorProto.
798 proto: An empty descriptor_pb2.ServiceDescriptorProto.
806 """Descriptor for a method in a service.
808 name: (str) Name of the method within the service.
809 full_name: (str) Full name of method.
810 index: (int) 0-indexed index of the method inside the service.
811 containing_service: (ServiceDescriptor) The service that contains this
813 input_type: The descriptor of the message that this method accepts.
814 output_type: The descriptor of the message that this method returns.
815 options: (descriptor_pb2.MethodOptions) Method options message or
816 None to use default method options.
819 if _USE_C_DESCRIPTORS:
820 _C_DESCRIPTOR_CLASS = _message.MethodDescriptor
822 def __new__(cls, name, full_name, index, containing_service,
823 input_type, output_type, options=None, serialized_options=None):
824 _message.Message._CheckCalledFromGeneratedFile()
825 return _message.default_pool.FindMethodByName(full_name)
827 def __init__(self, name, full_name, index, containing_service,
828 input_type, output_type, options=None, serialized_options=None):
829 """The arguments are as described in the description of MethodDescriptor
832 Note that containing_service may be None, and may be set later if necessary.
834 super(MethodDescriptor, self).
__init__(
835 options, serialized_options,
'MethodOptions')
845 """Descriptor for a file. Mimics the descriptor_pb2.FileDescriptorProto.
847 Note that enum_types_by_name, extensions_by_name, and dependencies
848 fields are only set by the message_factory module, and not by the
849 generated proto code.
851 name: name of file, relative to root of source tree.
852 package: name of the package
853 syntax: string indicating syntax of the file (can be "proto2" or "proto3")
854 serialized_pb: (str) Byte string of serialized
855 descriptor_pb2.FileDescriptorProto.
856 dependencies: List of other FileDescriptors this FileDescriptor depends on.
857 public_dependencies: A list of FileDescriptors, subset of the dependencies
858 above, which were declared as "public".
859 message_types_by_name: Dict of message names and their descriptors.
860 enum_types_by_name: Dict of enum names and their descriptors.
861 extensions_by_name: Dict of extension names and their descriptors.
862 services_by_name: Dict of services names and their descriptors.
863 pool: the DescriptorPool this descriptor belongs to. When not passed to the
864 constructor, the global default pool is used.
867 if _USE_C_DESCRIPTORS:
868 _C_DESCRIPTOR_CLASS = _message.FileDescriptor
871 serialized_options=None, serialized_pb=None,
872 dependencies=None, public_dependencies=None,
873 syntax=None, pool=None):
879 return _message.default_pool.AddSerializedFile(serialized_pb)
881 return super(FileDescriptor, cls).
__new__(cls)
884 serialized_options=None, serialized_pb=None,
885 dependencies=None, public_dependencies=None,
886 syntax=None, pool=None):
888 super(FileDescriptor, self).
__init__(
889 options, serialized_options,
'FileOptions')
893 pool = descriptor_pool.Default()
907 if (api_implementation.Type() ==
'cpp' and
912 """Copies this to a descriptor_pb2.FileDescriptorProto.
915 proto: An empty descriptor_pb2.FileDescriptorProto.
921 """Parses serialized options.
923 This helper function is used to parse serialized options in generated
924 proto2 files. It must not be used outside proto2.
926 message.ParseFromString(string)
931 """Converts name to camel-case and returns it."""
932 capitalize_next =
False
938 capitalize_next =
True
939 elif capitalize_next:
940 result.append(c.upper())
941 capitalize_next =
False
946 if result
and result[0].isupper():
947 result[0] = result[0].lower()
948 return ''.join(result)
952 """Returns the value of the field `options`, or None if it is not set."""
953 if descriptor_proto.HasField(
'options'):
954 return descriptor_proto.options
960 """Converts name to Json name and returns it."""
961 capitalize_next =
False
966 capitalize_next =
True
967 elif capitalize_next:
968 result.append(c.upper())
969 capitalize_next =
False
973 return ''.join(result)
978 """Make a protobuf Descriptor given a DescriptorProto protobuf.
980 Handles nested descriptors. Note that this is limited to the scope of defining
981 a message inside of another message. Composite fields can currently only be
982 resolved if the message is defined in the same scope as the field.
985 desc_proto: The descriptor_pb2.DescriptorProto protobuf message.
986 package: Optional package name for the new message Descriptor (string).
987 build_file_if_cpp: Update the C++ descriptor pool if api matches.
988 Set to False on recursion, so no duplicates are created.
989 syntax: The syntax/semantics that should be used. Set to "proto3" to get
990 proto3 field presence semantics.
992 A Descriptor for protobuf messages.
994 if api_implementation.Type() ==
'cpp' and build_file_if_cpp:
1000 file_descriptor_proto = descriptor_pb2.FileDescriptorProto()
1001 file_descriptor_proto.message_type.add().
MergeFrom(desc_proto)
1007 proto_name = binascii.hexlify(os.urandom(16)).decode(
'ascii')
1010 file_descriptor_proto.name = os.path.join(package.replace(
'.',
'/'),
1011 proto_name +
'.proto')
1012 file_descriptor_proto.package = package
1014 file_descriptor_proto.name = proto_name +
'.proto'
1016 _message.default_pool.Add(file_descriptor_proto)
1017 result = _message.default_pool.FindFileByName(file_descriptor_proto.name)
1019 if _USE_C_DESCRIPTORS:
1020 return result.message_types_by_name[desc_proto.name]
1022 full_message_name = [desc_proto.name]
1023 if package: full_message_name.insert(0, package)
1027 for enum_proto
in desc_proto.enum_type:
1028 full_name =
'.'.join(full_message_name + [enum_proto.name])
1030 enum_proto.name, full_name,
None, [
1032 for ii, enum_val
in enumerate(enum_proto.value)])
1033 enum_types[full_name] = enum_desc
1037 for nested_proto
in desc_proto.nested_type:
1038 full_name =
'.'.join(full_message_name + [nested_proto.name])
1042 package=
'.'.join(full_message_name),
1043 build_file_if_cpp=
False,
1045 nested_types[full_name] = nested_desc
1048 for field_proto
in desc_proto.field:
1049 full_name =
'.'.join(full_message_name + [field_proto.name])
1052 if field_proto.json_name:
1053 json_name = field_proto.json_name
1056 if field_proto.HasField(
'type_name'):
1057 type_name = field_proto.type_name
1058 full_type_name =
'.'.join(full_message_name +
1059 [type_name[type_name.rfind(
'.')+1:]])
1060 if full_type_name
in nested_types:
1061 nested_desc = nested_types[full_type_name]
1062 elif full_type_name
in enum_types:
1063 enum_desc = enum_types[full_type_name]
1066 field_proto.name, full_name, field_proto.number - 1,
1067 field_proto.number, field_proto.type,
1068 FieldDescriptor.ProtoTypeToCppProtoType(field_proto.type),
1069 field_proto.label,
None, nested_desc, enum_desc,
None,
False,
None,
1071 json_name=json_name)
1072 fields.append(field)
1074 desc_name =
'.'.join(full_message_name)
1075 return Descriptor(desc_proto.name, desc_name,
None,
None, fields,
1076 list(nested_types.values()), list(enum_types.values()), [],