Пример #1
0
    def _load_enum(
        self,
        enum: descriptor_pb2.EnumDescriptorProto,
        address: metadata.Address,
        path: Tuple[int],
    ) -> wrappers.EnumType:
        """Load enum descriptions from EnumDescriptorProtos."""
        address = address.child(enum.name, path)

        # Put together wrapped objects for the enum values.
        values = []
        for enum_value, i in zip(enum.value, range(0, sys.maxsize)):
            values.append(
                wrappers.EnumValueType(
                    enum_value_pb=enum_value,
                    meta=metadata.Metadata(
                        address=address,
                        documentation=self.docs.get(path + (2, i), self.EMPTY),
                    ),
                ))

        # Load the enum itself.
        self.proto_enums[address.proto] = wrappers.EnumType(
            enum_pb=enum,
            meta=metadata.Metadata(
                address=address,
                documentation=self.docs.get(path, self.EMPTY),
            ),
            values=values,
        )
        return self.proto_enums[address.proto]
Пример #2
0
    def _load_enum(self, enum: descriptor_pb2.EnumDescriptorProto,
                   address: metadata.Address, path: Tuple[int]) -> None:
        """Load enum descriptions from EnumDescriptorProtos."""
        # Put together wrapped objects for the enum values.
        values = []
        for enum_value, i in zip(enum.value, range(0, sys.maxsize)):
            values.append(
                wrappers.EnumValueType(
                    enum_value_pb=enum_value,
                    meta=metadata.Metadata(
                        address=address,
                        documentation=self.docs.get(path + (2, i), self.EMPTY),
                    ),
                ))

        # Load the enum itself.
        ident = f'{str(address)}.{enum.name}'
        self.enums[ident] = wrappers.EnumType(
            enum_pb=enum,
            meta=metadata.Metadata(
                address=address,
                documentation=self.docs.get(path, self.EMPTY),
            ),
            values=values,
        )
Пример #3
0
    def _client_output(self, enable_asyncio: bool):
        """Return the output from the client layer.

        This takes into account transformations made by the outer GAPIC
        client to transform the output from the transport.

        Returns:
            Union[~.MessageType, ~.PythonType]:
                A description of the return type.
        """
        # Void messages ultimately return None.
        if self.void:
            return PrimitiveType.build(None)

        # If this method is an LRO, return a PythonType instance representing
        # that.
        if self.lro:
            return PythonType(meta=metadata.Metadata(
                address=metadata.Address(
                    name='AsyncOperation' if enable_asyncio else 'Operation',
                    module='operation_async'
                    if enable_asyncio else 'operation',
                    package=('google', 'api_core'),
                    collisions=self.lro.response_type.ident.collisions,
                ),
                documentation=utils.doc(
                    'An object representing a long-running operation. \n\n'
                    'The result type for the operation will be '
                    ':class:`{ident}` {doc}'.format(
                        doc=self.lro.response_type.meta.doc,
                        ident=self.lro.response_type.ident.sphinx,
                    ), ),
            ))

        # If this method is paginated, return that method's pager class.
        if self.paged_result_field:
            return PythonType(meta=metadata.Metadata(
                address=metadata.Address(
                    name=f'{self.name}AsyncPager'
                    if enable_asyncio else f'{self.name}Pager',
                    package=self.ident.api_naming.module_namespace +
                    (self.ident.api_naming.versioned_module_name, ) +
                    self.ident.subpackage + (
                        'services',
                        utils.to_snake_case(self.ident.parent[-1]),
                    ),
                    module='pagers',
                    collisions=self.input.ident.collisions,
                ),
                documentation=utils.doc(
                    f'{self.output.meta.doc}\n\n'
                    'Iterating over this object will yield results and '
                    'resolve additional pages automatically.', ),
            ))

        # Return the usual output.
        return self.output
def make_method(
        name: str, input_message: wrappers.MessageType = None,
        output_message: wrappers.MessageType = None,
        package: str = 'foo.bar.v1', module: str = 'baz',
        **kwargs) -> wrappers.Method:
    # Use default input and output messages if they are not provided.
    input_message = input_message or make_message('MethodInput')
    output_message = output_message or make_message('MethodOutput')

    # Create the method pb2.
    method_pb = descriptor_pb2.MethodDescriptorProto(
        name=name,
        input_type=str(input_message.meta.address),
        output_type=str(output_message.meta.address),
    )

    # Instantiate the wrapper class.
    return wrappers.Method(
        method_pb=method_pb,
        input=input_message,
        output=output_message,
        meta=metadata.Metadata(address=metadata.Address(
            package=package,
            module=module,
        )),
    )
Пример #5
0
def make_field(name: str = 'my_field',
               number: int = 1,
               repeated: bool = False,
               message: wrappers.MessageType = None,
               enum: wrappers.EnumType = None,
               meta: metadata.Metadata = None,
               **kwargs) -> wrappers.Field:
    T = desc.FieldDescriptorProto.Type

    if message:
        kwargs.setdefault('type_name', str(message.meta.address))
        kwargs['type'] = 'TYPE_MESSAGE'
    elif enum:
        kwargs.setdefault('type_name', str(enum.meta.address))
        kwargs['type'] = 'TYPE_ENUM'
    else:
        kwargs.setdefault('type', T.Value('TYPE_BOOL'))

    if isinstance(kwargs['type'], str):
        kwargs['type'] = T.Value(kwargs['type'])

    label = kwargs.pop('label', 3 if repeated else 1)
    field_pb = desc.FieldDescriptorProto(name=name,
                                         label=label,
                                         number=number,
                                         **kwargs)
    return wrappers.Field(
        field_pb=field_pb,
        enum=enum,
        message=message,
        meta=meta or metadata.Metadata(),
    )
Пример #6
0
    def _load_service(
        self,
        service: descriptor_pb2.ServiceDescriptorProto,
        address: metadata.Address,
        path: Tuple[int],
    ) -> wrappers.Service:
        """Load comments for a service and its methods."""
        address = address.child(service.name, path)

        # Put together a dictionary of the service's methods.
        methods = self._get_methods(
            service.method,
            service_address=address,
            path=path + (2, ),
        )

        # Load the comments for the service itself.
        self.proto_services[address.proto] = wrappers.Service(
            meta=metadata.Metadata(
                address=address,
                documentation=self.docs.get(path, self.EMPTY),
            ),
            methods=methods,
            service_pb=service,
        )
        return self.proto_services[address.proto]
Пример #7
0
def make_enum(
    name: str,
    package: str = 'foo.bar.v1',
    module: str = 'baz',
    values: typing.Tuple[str, int] = (),
    meta: metadata.Metadata = None,
) -> wrappers.EnumType:
    enum_value_pbs = [
        desc.EnumValueDescriptorProto(name=i[0], number=i[1]) for i in values
    ]
    enum_pb = desc.EnumDescriptorProto(
        name=name,
        value=enum_value_pbs,
    )
    return wrappers.EnumType(
        enum_pb=enum_pb,
        values=[
            wrappers.EnumValueType(enum_value_pb=evpb)
            for evpb in enum_value_pbs
        ],
        meta=meta or metadata.Metadata(address=metadata.Address(
            name=name,
            package=tuple(package.split('.')),
            module=module,
        )),
    )
Пример #8
0
    def proto(self) -> Proto:
        """Return a Proto dataclass object."""
        # Create a "context-naïve" proto.
        # This has everything but is ignorant of naming collisions in the
        # ultimate file that will be written.
        naive = Proto(
            all_enums=self.proto_enums,
            all_messages=self.proto_messages,
            file_pb2=self.file_descriptor,
            file_to_generate=self.file_to_generate,
            services=self.proto_services,
            meta=metadata.Metadata(address=self.address, ),
        )

        # If this is not a file being generated, we do not need to
        # do anything else.
        if not self.file_to_generate:
            return naive

        # Return a context-aware proto object.
        return dataclasses.replace(
            naive,
            all_enums=collections.OrderedDict(
                (k, v.with_context(collisions=naive.names))
                for k, v in naive.all_enums.items()),
            all_messages=collections.OrderedDict(
                (k, v.with_context(collisions=naive.names))
                for k, v in naive.all_messages.items()),
            services=collections.OrderedDict(
                # Note: services bind to themselves because services get their
                # own output files.
                (k, v.with_context(collisions=v.names))
                for k, v in naive.services.items()),
            meta=naive.meta.with_context(collisions=naive.names),
        )
Пример #9
0
def get_message(
    dot_path: str,
    *,
    fields: typing.Tuple[desc.FieldDescriptorProto] = (),
) -> wrappers.MessageType:
    # Pass explicit None through (for lro_metadata).
    if dot_path is None:
        return None

    # Note: The `dot_path` here is distinct from the canonical proto path
    # because it includes the module, which the proto path does not.
    #
    # So, if trying to test the DescriptorProto message here, the path
    # would be google.protobuf.descriptor.DescriptorProto (whereas the proto
    # path is just google.protobuf.DescriptorProto).
    pieces = dot_path.split('.')
    pkg, module, name = pieces[:-2], pieces[-2], pieces[-1]

    return wrappers.MessageType(
        fields={
            i.name: wrappers.Field(
                field_pb=i,
                enum=get_enum(i.type_name) if i.type_name else None,
            )
            for i in fields
        },
        nested_messages={},
        nested_enums={},
        message_pb=desc.DescriptorProto(name=name, field=fields),
        meta=metadata.Metadata(address=metadata.Address(
            name=name,
            package=tuple(pkg),
            module=module,
        )),
    )
Пример #10
0
def test_operation_meta():
    lro_response = wrappers.MessageType(
        fields={},
        message_pb=descriptor_pb2.DescriptorProto(name='LroResponse'),
        meta=metadata.Metadata(address=metadata.Address(module='foo')),
    )
    operation = wrappers.OperationType(lro_response=lro_response)
    assert 'representing a long-running operation' in operation.meta.doc
    assert ':class:`~.foo_pb2.LroResponse`' in operation.meta.doc
def test_message_docstring():
    L = descriptor_pb2.SourceCodeInfo.Location

    meta = metadata.Metadata(documentation=L(
        leading_comments='Lorem ipsum',
        trailing_comments='dolor set amet',
    ))
    message = make_message('Name', meta=meta)
    assert message.meta.doc == 'Lorem ipsum'
Пример #12
0
    def _load_message(
        self,
        message_pb: descriptor_pb2.DescriptorProto,
        address: metadata.Address,
        path: Tuple[int],
    ) -> wrappers.MessageType:
        """Load message descriptions from DescriptorProtos."""
        address = address.child(message_pb.name, path)

        # Load all nested items.
        #
        # Note: This occurs before piecing together this message's fields
        # because if nested types are present, they are generally the
        # type of one of this message's fields, and they need to be in
        # the registry for the field's message or enum attributes to be
        # set correctly.
        nested_enums = self._load_children(
            message_pb.enum_type,
            address=address,
            loader=self._load_enum,
            path=path + (4, ),
        )
        nested_messages = self._load_children(
            message_pb.nested_type,
            address=address,
            loader=self._load_message,
            path=path + (3, ),
        )
        # self._load_children(message.oneof_decl, loader=self._load_field,
        #                     address=nested_addr, info=info.get(8, {}))

        # Create a dictionary of all the fields for this message.
        fields = self._get_fields(
            message_pb.field,
            address=address,
            path=path + (2, ),
        )
        fields.update(
            self._get_fields(
                message_pb.extension,
                address=address,
                path=path + (6, ),
            ))

        # Create a message correspoding to this descriptor.
        self.proto_messages[address.proto] = wrappers.MessageType(
            fields=fields,
            message_pb=message_pb,
            nested_enums=nested_enums,
            nested_messages=nested_messages,
            meta=metadata.Metadata(
                address=address,
                documentation=self.docs.get(path, self.EMPTY),
            ),
        )
        return self.proto_messages[address.proto]
def make_method(
        name: str,
        input_message: wrappers.MessageType = None,
        output_message: wrappers.MessageType = None,
        package: typing.Union[typing.Tuple[str], str] = 'foo.bar.v1',
        module: str = 'baz',
        http_rule: http_pb2.HttpRule = None,
        signatures: typing.Sequence[str] = (),
        is_deprecated: bool = False,
        routing_rule: routing_pb2.RoutingRule = None,
        **kwargs
) -> wrappers.Method:
    # Use default input and output messages if they are not provided.
    input_message = input_message or make_message('MethodInput')
    output_message = output_message or make_message('MethodOutput')

    # Create the method pb2.
    method_pb = desc.MethodDescriptorProto(
        name=name,
        input_type=str(input_message.meta.address),
        output_type=str(output_message.meta.address),
        **kwargs
    )

    if routing_rule:
        ext_key = routing_pb2.routing
        method_pb.options.Extensions[ext_key].MergeFrom(routing_rule)

    # If there is an HTTP rule, process it.
    if http_rule:
        ext_key = annotations_pb2.http
        method_pb.options.Extensions[ext_key].MergeFrom(http_rule)

    # If there are signatures, include them.
    for sig in signatures:
        ext_key = client_pb2.method_signature
        method_pb.options.Extensions[ext_key].append(sig)

    if isinstance(package, str):
        package = tuple(package.split('.'))

    if is_deprecated:
        method_pb.options.deprecated = True

    # Instantiate the wrapper class.
    return wrappers.Method(
        method_pb=method_pb,
        input=input_message,
        output=output_message,
        meta=metadata.Metadata(address=metadata.Address(
            name=name,
            package=package,
            module=module,
            parent=(f'{name}Service',),
        )),
    )
Пример #14
0
    def _get_methods(
        self,
        methods: Sequence[descriptor_pb2.MethodDescriptorProto],
        address: metadata.Address,
        path: Tuple[int, ...],
    ) -> Mapping[str, wrappers.Method]:
        """Return a dictionary of wrapped methods for the given service.

        Args:
            methods (Sequence[~.descriptor_pb2.MethodDescriptorProto]): A
                sequence of protobuf method objects.
            address (~.metadata.Address): An address object denoting the
                location of these methods.
            path (Tuple[int]): The source location path thus far, as understood
                by ``SourceCodeInfo.Location``.

        Returns:
            Mapping[str, ~.wrappers.Method]: A ordered mapping of
                :class:`~.wrappers.Method` objects.
        """
        # Iterate over the methods and collect them into a dictionary.
        answer: Dict[str, wrappers.Method] = collections.OrderedDict()
        for meth_pb, i in zip(methods, range(0, sys.maxsize)):
            lro = None

            # If the output type is google.longrunning.Operation, we use
            # a specialized object in its place.
            if meth_pb.output_type.endswith('google.longrunning.Operation'):
                op = meth_pb.options.Extensions[operations_pb2.operation_info]
                if not op.response_type or not op.metadata_type:
                    raise TypeError(
                        f'rpc {meth_pb.name} returns a google.longrunning.'
                        'Operation, but is missing a response type or '
                        'metadata type.', )
                lro = wrappers.OperationInfo(
                    response_type=self.api_messages[address.resolve(
                        op.response_type, )],
                    metadata_type=self.api_messages[address.resolve(
                        op.metadata_type, )],
                )

            # Create the method wrapper object.
            answer[meth_pb.name] = wrappers.Method(
                input=self.api_messages[meth_pb.input_type.lstrip('.')],
                lro=lro,
                method_pb=meth_pb,
                meta=metadata.Metadata(
                    address=address.child(meth_pb.name, path + (i, )),
                    documentation=self.docs.get(path + (i, ), self.EMPTY),
                ),
                output=self.api_messages[meth_pb.output_type.lstrip('.')],
            )

        # Done; return the answer.
        return answer
Пример #15
0
def make_doc_meta(
    *,
    leading: str = '',
    trailing: str = '',
    detached: typing.List[str] = [],
) -> desc.SourceCodeInfo.Location:
    return metadata.Metadata(documentation=desc.SourceCodeInfo.Location(
        leading_comments=leading,
        trailing_comments=trailing,
        leading_detached_comments=detached,
    ), )
def make_field(name: str, repeated: bool = False,
               meta: metadata.Metadata = None, **kwargs) -> wrappers.Method:
    field_pb = descriptor_pb2.FieldDescriptorProto(
        name=name,
        label=3 if repeated else 1,
        **kwargs
    )
    return wrappers.Field(
        field_pb=field_pb,
        meta=meta or metadata.Metadata(),
    )
Пример #17
0
def test_message_pb2_sphinx_ident():
    meta = metadata.Metadata(
        address=metadata.Address(name='Timestamp',
                                 package=('google', 'protobuf'),
                                 module='timestamp',
                                 api_naming=naming.NewNaming(
                                     proto_package="foo.bar")))
    message = make_message("Timestamp",
                           package='google.protobuf',
                           module='timestamp',
                           meta=meta)
    assert message.ident.sphinx == 'google.protobuf.timestamp_pb2.Timestamp'
Пример #18
0
def get_enum(dot_path: str) -> wrappers.EnumType:
    pieces = dot_path.split('.')
    pkg, module, name = pieces[:-2], pieces[-2], pieces[-1]
    return wrappers.EnumType(
        enum_pb=desc.EnumDescriptorProto(name=name),
        meta=metadata.Metadata(address=metadata.Address(
            name=name,
            package=tuple(pkg),
            module=module,
        )),
        values=[],
    )
Пример #19
0
    def _get_fields(
        self,
        field_pbs: Sequence[descriptor_pb2.FieldDescriptorProto],
        address: metadata.Address,
        path: Tuple[int, ...],
        oneofs: Optional[Dict[str, wrappers.Oneof]] = None
    ) -> Dict[str, wrappers.Field]:
        """Return a dictionary of wrapped fields for the given message.

        Args:
            field_pbs (Sequence[~.descriptor_pb2.FieldDescriptorProto]): A
                sequence of protobuf field objects.
            address (~.metadata.Address): An address object denoting the
                location of these fields.
            path (Tuple[int]): The source location path thus far, as
                understood by ``SourceCodeInfo.Location``.

        Returns:
            Mapping[str, ~.wrappers.Field]: A ordered mapping of
                :class:`~.wrappers.Field` objects.
        """
        # Iterate over the fields and collect them into a dictionary.
        #
        # The saving of the enum and message types rely on protocol buffers'
        # naming rules to trust that they will never collide.
        #
        # Note: If this field is a recursive reference to its own message,
        # then the message will not be in `api_messages` yet (because the
        # message wrapper is not yet created, because it needs this object
        # first) and this will be None. This case is addressed in the
        # `_load_message` method.
        answer: Dict[str, wrappers.Field] = collections.OrderedDict()
        for i, field_pb in enumerate(field_pbs):
            is_oneof = oneofs and field_pb.HasField('oneof_index')
            oneof_name = nth((oneofs or {}).keys(),
                             field_pb.oneof_index) if is_oneof else None

            field = wrappers.Field(
                field_pb=field_pb,
                enum=self.api_enums.get(field_pb.type_name.lstrip('.')),
                message=self.api_messages.get(field_pb.type_name.lstrip('.')),
                meta=metadata.Metadata(
                    address=address.child(field_pb.name, path + (i, )),
                    documentation=self.docs.get(path + (i, ), self.EMPTY),
                ),
                oneof=oneof_name,
            )
            answer[field.name] = field

        # Done; return the answer.
        return answer
Пример #20
0
def test_mock_value_original_type_message():
    subfields = collections.OrderedDict((
        ('foo', make_field(name='foo', type='TYPE_INT32')),
        ('bar', make_field(name='bar', type='TYPE_STRING'))
    ))
    message = wrappers.MessageType(
        fields=subfields,
        message_pb=descriptor_pb2.DescriptorProto(name='Message', field=[
            i.field_pb for i in subfields.values()
        ]),
        meta=metadata.Metadata(address=metadata.Address(
            module='bogus',
            name='Message',
        )),
        nested_enums={},
        nested_messages={},
    )

    field = make_field(
        type='TYPE_MESSAGE',
        type_name='bogus.Message',
        message=message,
    )

    mock = field.mock_value_original_type

    assert mock == {"foo": 324, "bar": "bar_value"}

    # Messages by definition aren't primitive
    with pytest.raises(TypeError):
        field.primitive_mock()

    # Special case for map entries
    entry_msg = make_message(
        name='MessageEntry',
        fields=(
            make_field(name='key', type='TYPE_STRING'),
            make_field(name='value', type='TYPE_STRING'),
        ),
        options=descriptor_pb2.MessageOptions(map_entry=True),
    )
    entry_field = make_field(
        name="messages",
        type_name="stuff.MessageEntry",
        message=entry_msg,
        label=3,
        type='TYPE_MESSAGE',
    )

    assert entry_field.mock_value_original_type == {}
 def __init__(self,
              *,
              fields={},
              type="",
              options=False,
              ident=False,
              resource_path=False,
              meta=None):
     self.fields = fields
     self.type = type
     self.options = options
     self.ident = ident
     self.resource_path = resource_path
     self.meta = meta or metadata.Metadata()
Пример #22
0
    def _get_methods(
        self,
        methods: List[descriptor_pb2.MethodDescriptorProto],
        address: metadata.Address,
        path: Tuple[int],
    ) -> Mapping[str, wrappers.Method]:
        """Return a dictionary of wrapped methods for the given service.

        Args:
            methods (Sequence[~.descriptor_pb2.MethodDescriptorProto]): A
                sequence of protobuf method objects.
            address (~.metadata.Address): An address object denoting the
                location of these methods.
            path (Tuple[int]): The source location path thus far, as understood
                by ``SourceCodeInfo.Location``.

        Returns:
            Mapping[str, ~.wrappers.Method]: A ordered mapping of
                :class:`~.wrappers.Method` objects.
        """
        # Iterate over the methods and collect them into a dictionary.
        answer = collections.OrderedDict()
        for meth_pb, i in zip(methods, range(0, sys.maxsize)):
            types = meth_pb.options.Extensions[operations_pb2.operation_types]

            # If the output type is google.longrunning.Operation, we use
            # a specialized object in its place.
            output_type = self.all_messages[meth_pb.output_type.lstrip('.')]
            if meth_pb.output_type.endswith('google.longrunning.Operation'):
                output_type = self._get_operation_type(
                    response_type=self.all_messages[address.resolve(
                        types.response)],
                    metadata_type=self.all_messages.get(
                        address.resolve(types.metadata), ),
                )

            # Create the method wrapper object.
            answer[meth_pb.name] = wrappers.Method(
                input=self.all_messages[meth_pb.input_type.lstrip('.')],
                method_pb=meth_pb,
                meta=metadata.Metadata(
                    address=address,
                    documentation=self.docs.get(path + (i, ), self.EMPTY),
                ),
                output=output_type,
            )

        # Done; return the answer.
        return answer
def make_field(name: str,
               repeated: bool = False,
               message: wrappers.MessageType = None,
               meta: metadata.Metadata = None,
               **kwargs) -> wrappers.Method:
    if message:
        kwargs['type_name'] = str(message.meta.address)
    field_pb = descriptor_pb2.FieldDescriptorProto(name=name,
                                                   label=3 if repeated else 1,
                                                   **kwargs)
    return wrappers.Field(
        field_pb=field_pb,
        message=message,
        meta=meta or metadata.Metadata(),
    )
def make_message(name: str, package: str = 'foo.bar.v1', module: str = 'baz',
        fields: Sequence[wrappers.Field] = (),
        ) -> wrappers.MessageType:
    message_pb = descriptor_pb2.DescriptorProto(
        name=name,
        field=[i.field_pb for i in fields],
    )
    return wrappers.MessageType(
        message_pb=message_pb,
        fields=collections.OrderedDict((i.name, i) for i in fields),
        meta=metadata.Metadata(address=metadata.Address(
            package=tuple(package.split('.')),
            module=module,
        )),
    )
Пример #25
0
    def build(cls, primitive_type: Optional[type]):
        """Return a PrimitiveType object for the given Python primitive type.

        Args:
            primitive_type (cls): A Python primitive type, such as
                :class:`int` or :class:`str`. Despite not being a type,
                ``None`` is also accepted here.

        Returns:
            ~.PrimitiveType: The instantiated PrimitiveType object.
        """
        # Primitives have no import, and no module to reference, so the
        # address just uses the name of the class (e.g. "int", "str").
        return cls(meta=metadata.Metadata(address=metadata.Address(
            name='None' if primitive_type is None else primitive_type.__name__,
        )), python_type=primitive_type)
 def meta(self) -> metadata.Metadata:
     """Return a Metadata object."""
     return metadata.Metadata(
         address=metadata.Address(
             module='operation',
             package=('google', 'api_core'),
         ),
         documentation=descriptor_pb2.SourceCodeInfo.Location(
             leading_comments='An object representing a long-running '
             'operation. \n\n'
             'The result type for the operation will be '
             ':class:`~.{module}.{name}`: {doc}'.format(
                 doc=self.lro_response.meta.doc,
                 module=self.lro_response.python_module,
                 name=self.lro_response.name,
             ), ),
     )
Пример #27
0
    def _get_methods(self,
                     methods: Sequence[descriptor_pb2.MethodDescriptorProto],
                     service_address: metadata.Address, path: Tuple[int, ...],
                     ) -> Mapping[str, wrappers.Method]:
        """Return a dictionary of wrapped methods for the given service.

        Args:
            methods (Sequence[~.descriptor_pb2.MethodDescriptorProto]): A
                sequence of protobuf method objects.
            service_address (~.metadata.Address): An address object for the
                service, denoting the location of these methods.
            path (Tuple[int]): The source location path thus far, as understood
                by ``SourceCodeInfo.Location``.

        Returns:
            Mapping[str, ~.wrappers.Method]: A ordered mapping of
                :class:`~.wrappers.Method` objects.
        """
        # Iterate over the methods and collect them into a dictionary.
        answer: Dict[str, wrappers.Method] = collections.OrderedDict()
        for i, meth_pb in enumerate(methods):
            retry, timeout = self._get_retry_and_timeout(
                service_address,
                meth_pb
            )

            # Create the method wrapper object.
            answer[meth_pb.name] = wrappers.Method(
                input=self.api_messages[meth_pb.input_type.lstrip('.')],
                lro=self._maybe_get_lro(service_address, meth_pb),
                extended_lro=self._maybe_get_extended_lro(
                    service_address,
                    meth_pb,
                ),
                method_pb=meth_pb,
                meta=metadata.Metadata(
                    address=service_address.child(meth_pb.name, path + (i,)),
                    documentation=self.docs.get(path + (i,), self.EMPTY),
                ),
                output=self.api_messages[meth_pb.output_type.lstrip('.')],
                retry=retry,
                timeout=timeout,
            )

        # Done; return the answer.
        return answer
Пример #28
0
 def meta(self) -> metadata.Metadata:
     """Return a Metadata object."""
     return metadata.Metadata(
         address=metadata.Address(
             name='Operation',
             module='operation',
             package=('google', 'api_core'),
             collisions=self.lro_response.meta.address.collisions,
         ),
         documentation=descriptor_pb2.SourceCodeInfo.Location(
             leading_comments='An object representing a long-running '
             'operation. \n\n'
             'The result type for the operation will be '
             ':class:`{ident}`: {doc}'.format(
                 doc=self.lro_response.meta.doc,
                 ident=self.lro_response.ident.sphinx,
             ), ),
     )
Пример #29
0
    def _get_fields(
        self,
        field_pbs: List[descriptor_pb2.FieldDescriptorProto],
        address: metadata.Address,
        path: Tuple[int],
    ) -> Mapping[str, wrappers.Field]:
        """Return a dictionary of wrapped fields for the given message.

        Args:
            fields (Sequence[~.descriptor_pb2.FieldDescriptorProto]): A
                sequence of protobuf field objects.
            address (~.metadata.Address): An address object denoting the
                location of these fields.
            path (Tuple[int]): The source location path thus far, as
                understood by ``SourceCodeInfo.Location``.

        Returns:
            Mapping[str, ~.wrappers.Field]: A ordered mapping of
                :class:`~.wrappers.Field` objects.
        """
        # Iterate over the fields and collect them into a dictionary.
        #
        # The saving of the enum and message types rely on protocol buffers'
        # naming rules to trust that they will never collide.
        #
        # Note: If this field is a recursive reference to its own message,
        # then the message will not be in `all_messages` yet (because the
        # message wrapper is not yet created, because it needs this object
        # first) and this will be None. This case is addressed in the
        # `_load_message` method.
        answer = collections.OrderedDict()
        for field_pb, i in zip(field_pbs, range(0, sys.maxsize)):
            answer[field_pb.name] = wrappers.Field(
                field_pb=field_pb,
                enum=self.all_enums.get(field_pb.type_name.lstrip('.')),
                message=self.all_messages.get(field_pb.type_name.lstrip('.')),
                meta=metadata.Metadata(
                    address=address,
                    documentation=self.docs.get(path + (i, ), self.EMPTY),
                ),
            )

        # Done; return the answer.
        return answer
Пример #30
0
def test_mock_value_enum():
    values = [
        descriptor_pb2.EnumValueDescriptorProto(name='UNSPECIFIED', number=0),
        descriptor_pb2.EnumValueDescriptorProto(name='SPECIFIED', number=1),
    ]
    enum = wrappers.EnumType(
        values=[wrappers.EnumValueType(enum_value_pb=i) for i in values],
        enum_pb=descriptor_pb2.EnumDescriptorProto(value=values),
        meta=metadata.Metadata(address=metadata.Address(
            module='bogus',
            name='Enumerable',
        )),
    )
    field = make_field(
        type='TYPE_ENUM',
        type_name='bogus.Enumerable',
        enum=enum,
    )
    assert field.mock_value == 'bogus.Enumerable.SPECIFIED'