def python_import(self) -> imp.Import:
        """Return the Python import for this type."""
        # If there is no naming object, this is a special case for operation.
        # FIXME(#34): OperationType does not work well. Fix or expunge it.
        if not self.api_naming:
            return imp.Import(
                package=self.package,
                module=self.module,
                alias=self.module_alias,
            )

        # If this is part of the proto package that we are generating,
        # rewrite the package to our structure.
        if self.proto_package.startswith(self.api_naming.proto_package):
            return imp.Import(
                package=self.api_naming.module_namespace +
                (self.api_naming.versioned_module_name, ) + self.subpackage +
                ('types', ),
                module=self.module,
                alias=self.module_alias,
            )

        # Return the standard import.
        return imp.Import(
            package=self.package,
            module=f'{self.module}_pb2',
            alias=self.module_alias if self.module_alias else self.module,
        )
Exemple #2
0
    def python_import(self) -> imp.Import:
        """Return the Python import for this type."""
        # If there is no naming object, then this is a special case for
        # Python types.
        #
        # FIXME: This does not attempt to do an isinstance check on PythonType
        # to avoid a circular dependency.
        # That part is fine, but a check for the absence of `api_naming` is
        # less than ideal; the condition works, but it is a weak correlation
        # that may not hold up over time.
        if not self.api_naming:
            return imp.Import(
                package=self.package,
                module=self.module,
                alias=self.module_alias,
            )

        # If this is part of the proto package that we are generating,
        # rewrite the package to our structure.
        if self.proto_package.startswith(self.api_naming.proto_package):
            return imp.Import(
                package=self.api_naming.module_namespace +
                (self.api_naming.versioned_module_name, ) + self.subpackage +
                ('types', ),
                module=self.module,
                alias=self.module_alias,
            )

        # Return the standard import.
        return imp.Import(
            package=self.package,
            module=f'{self.module}_pb2',
        )
Exemple #3
0
def test_service_python_modules_lro():
    service = make_service_with_method_options()
    assert service.python_modules == (
        imp.Import(package=('foo',), module='bar'),
        imp.Import(package=('foo',), module='baz'),
        imp.Import(package=('foo',), module='qux'),
        imp.Import(package=('google', 'api_core'), module='operation'),
    )
Exemple #4
0
def test_service_python_modules_lro():
    service = make_service_with_method_options()
    method = service.methods['DoBigThing']
    imports = {i.ident.python_import for i in method.ref_types}
    assert imports == {
        imp.Import(package=('foo', ), module='bar'),
        imp.Import(package=('foo', ), module='baz'),
        imp.Import(package=('foo', ), module='qux'),
        imp.Import(package=('google', 'api_core'), module='operation'),
    }
def test_str_eq():
    i1 = imp.Import(package=('foo', 'bar'), module='baz')
    i2 = imp.Import(package=('foo', 'bar'), module='baz')
    i3 = imp.Import(package=('foo', 'bar'), module='baz', alias='bacon')
    j1 = imp.Import(package=('foo', 'bar'), module='not_baz')
    k1 = imp.Import(package=('spam', 'eggs'), module='baz')
    assert i1 == i2
    assert i1 == i3
    assert i2 == i3
    assert i1 != j1
    assert i1 != k1
Exemple #6
0
def test_service_python_modules():
    service = make_service(methods=(
        get_method('DoThing', 'foo.bar.ThingRequest', 'foo.baz.ThingResponse'),
        get_method('Jump', 'foo.bacon.JumpRequest', 'foo.bacon.JumpResponse'),
        get_method('Yawn', 'a.b.v1.c.YawnRequest', 'x.y.v1.z.YawnResponse'),
    ))
    assert service.python_modules == (
        imp.Import(package=('a', 'b', 'v1'), module='c'),
        imp.Import(package=('foo',), module='bacon'),
        imp.Import(package=('foo',), module='bar'),
        imp.Import(package=('foo',), module='baz'),
        imp.Import(package=('x', 'y', 'v1'), module='z'),
    )
Exemple #7
0
def test_service_python_modules():
    service = make_service(methods=(
        get_method('DoThing', 'foo.bar.ThingRequest', 'foo.baz.ThingResponse'),
        get_method('Jump', 'foo.bacon.JumpRequest', 'foo.bacon.JumpResponse'),
        get_method('Yawn', 'a.b.v1.c.YawnRequest', 'x.y.v1.z.YawnResponse'),
    ))
    imports = set()
    for m in service.methods.values():
        imports = imports.union({i.ident.python_import for i in m.ref_types})
    assert imports == {
        imp.Import(package=('a', 'b', 'v1'), module='c'),
        imp.Import(package=('foo', ), module='bacon'),
        imp.Import(package=('foo', ), module='bar'),
        imp.Import(package=('foo', ), module='baz'),
        imp.Import(package=('x', 'y', 'v1'), module='z'),
    }
def test_python_modules_nested():
    fd = (
        make_file_pb2(
            name='dep.proto',
            package='google.dep',
            messages=(make_message_pb2(name='ImportedMessage', fields=()), ),
        ),
        make_file_pb2(
            name='common.proto',
            package='google.example.v1.common',
            messages=(make_message_pb2(name='Bar'), ),
        ),
        make_file_pb2(
            name='foo.proto',
            package='google.example.v1',
            messages=(
                make_message_pb2(
                    name='GetFooRequest',
                    fields=(
                        make_field_pb2(name='primitive', number=2, type=1),
                        make_field_pb2(
                            name='foo',
                            number=3,
                            type=1,
                            type_name='.google.example.v1.GetFooRequest.Foo',
                        ),
                    ),
                    nested_type=(make_message_pb2(
                        name='Foo',
                        fields=(make_field_pb2(
                            name='imported_message',
                            number=1,
                            type_name='.google.dep.ImportedMessage'), ),
                    ), ),
                ),
                make_message_pb2(
                    name='GetFooResponse',
                    fields=(make_field_pb2(
                        name='foo',
                        number=1,
                        type_name='.google.example.v1.GetFooRequest.Foo',
                    ), ),
                ),
            ),
            services=(descriptor_pb2.ServiceDescriptorProto(
                name='FooService',
                method=(descriptor_pb2.MethodDescriptorProto(
                    name='GetFoo',
                    input_type='google.example.v1.GetFooRequest',
                    output_type='google.example.v1.GetFooResponse',
                ), ),
            ), ),
        ),
    )

    api_schema = api.API.build(fd, package='google.example.v1')

    assert api_schema.protos['foo.proto'].python_modules == (imp.Import(
        package=('google', 'dep'), module='dep_pb2'), )
Exemple #9
0
def test_service_python_modules_signature():
    service = make_service_with_method_options(
        in_fields=(
            descriptor_pb2.FieldDescriptorProto(name='secs', type=5),
            descriptor_pb2.FieldDescriptorProto(
                name='d',
                type=14,  # enum
                type_name='a.b.c.v2.D',
            ),
        ),
        method_signature='secs,d',
    )
    # type=5 is int, so nothing is added.
    assert service.python_modules == (
        imp.Import(package=('a', 'b', 'c'), module='v2'),
        imp.Import(package=('foo',), module='bar'),
        imp.Import(package=('foo',), module='baz'),
        imp.Import(package=('foo',), module='qux'),
        imp.Import(package=('google', 'api_core'), module='operation'),
    )
Exemple #10
0
def test_service_python_modules_signature():
    service = make_service_with_method_options(
        in_fields=(
            # type=5 is int, so nothing is added.
            descriptor_pb2.FieldDescriptorProto(name='secs', type=5),
            descriptor_pb2.FieldDescriptorProto(
                name='d',
                type=14,  # enum
                type_name='a.b.c.v2.D',
            ),
        ),
        method_signature='secs,d',
    )

    # Ensure that the service will have the expected imports.
    method = service.methods['DoBigThing']
    imports = {i.ident.python_import for i in method.ref_types}
    assert imports == {
        imp.Import(package=('a', 'b', 'c'), module='v2'),
        imp.Import(package=('foo', ), module='bar'),
        imp.Import(package=('foo', ), module='baz'),
        imp.Import(package=('foo', ), module='qux'),
        imp.Import(package=('google', 'api_core'), module='operation'),
        imp.Import(package=('google', 'api_core'), module='operation_async'),
    }
def test_proto_names_import_collision_flattening():
    lro_proto = api.Proto.build(make_file_pb2(
        name='operations.proto',
        package='google.longrunning',
        messages=(make_message_pb2(name='Operation'), ),
    ),
                                file_to_generate=False,
                                naming=make_naming())

    fd = (
        make_file_pb2(
            name='mollusc.proto',
            package='google.animalia.mollusca',
            messages=(
                make_message_pb2(name='Mollusc', ),
                make_message_pb2(name='MolluscResponse', ),
                make_message_pb2(name='MolluscMetadata', ),
            ),
        ),
        make_file_pb2(
            name='squid.proto',
            package='google.animalia.mollusca',
            messages=(
                make_message_pb2(
                    name='IdentifySquidRequest',
                    fields=(make_field_pb2(
                        name='mollusc',
                        number=1,
                        type_name='.google.animalia.mollusca.Mollusc'), ),
                ),
                make_message_pb2(
                    name='IdentifySquidResponse',
                    fields=(),
                ),
            ),
            services=(descriptor_pb2.ServiceDescriptorProto(
                name='SquidIdentificationService',
                method=(descriptor_pb2.MethodDescriptorProto(
                    name='IdentifyMollusc',
                    input_type='google.animalia.mollusca.IdentifySquidRequest',
                    output_type='google.longrunning.Operation',
                ), ),
            ), ),
        ),
    )

    method_options = fd[1].service[0].method[0].options
    # Notice that a signature field collides with the name of an imported module
    method_options.Extensions[client_pb2.method_signature].append('mollusc')
    method_options.Extensions[operations_pb2.operation_info].MergeFrom(
        operations_pb2.OperationInfo(
            response_type='google.animalia.mollusca.MolluscResponse',
            metadata_type='google.animalia.mollusca.MolluscMetadata',
        ))
    api_schema = api.API.build(fd,
                               package='google.animalia.mollusca',
                               prior_protos={
                                   'google/longrunning/operations.proto':
                                   lro_proto,
                               })

    actual_imports = {
        ref_type.ident.python_import
        for service in api_schema.services.values()
        for method in service.methods.values() for ref_type in method.ref_types
    }

    expected_imports = {
        imp.Import(
            package=('google', 'animalia', 'mollusca', 'types'),
            module='mollusc',
            alias='gam_mollusc',
        ),
        imp.Import(
            package=('google', 'animalia', 'mollusca', 'types'),
            module='squid',
        ),
        imp.Import(
            package=('google', 'api_core'),
            module='operation',
        ),
        imp.Import(
            package=('google', 'api_core'),
            module='operation_async',
        ),
    }

    assert expected_imports == actual_imports

    method = (api_schema.
              services['google.animalia.mollusca.SquidIdentificationService'].
              methods['IdentifyMollusc'])

    actual_response_import = method.lro.response_type.ident.python_import
    expected_response_import = imp.Import(
        package=('google', 'animalia', 'mollusca', 'types'),
        module='mollusc',
        alias='gam_mollusc',
    )
    assert actual_response_import == expected_response_import
def test_str_alias():
    i = imp.Import(package=('foo', 'bar'), module='baz', alias='bacon')
    assert str(i) == 'from foo.bar import baz as bacon'
def test_str_no_package():
    i = imp.Import(package=(), module='baz')
    assert str(i) == 'import baz'
def test_str():
    i = imp.Import(package=('foo', 'bar'), module='baz')
    assert str(i) == 'from foo.bar import baz'
def test_api_build():
    # Put together a couple of minimal protos.
    fd = (
        make_file_pb2(
            name='dep.proto',
            package='google.dep',
            messages=(make_message_pb2(name='ImportedMessage', fields=()), ),
        ),
        make_file_pb2(
            name='common.proto',
            package='google.example.v1.common',
            messages=(make_message_pb2(name='Bar'), ),
        ),
        make_file_pb2(
            name='foo.proto',
            package='google.example.v1',
            messages=(
                make_message_pb2(name='Foo', fields=()),
                make_message_pb2(
                    name='GetFooRequest',
                    fields=(
                        make_field_pb2(
                            name='imported_message',
                            number=1,
                            type_name='.google.dep.ImportedMessage'),
                        make_field_pb2(name='primitive', number=2, type=1),
                    )),
                make_message_pb2(name='GetFooResponse',
                                 fields=(make_field_pb2(
                                     name='foo',
                                     number=1,
                                     type_name='.google.example.v1.Foo'), )),
            ),
            services=(descriptor_pb2.ServiceDescriptorProto(
                name='FooService',
                method=(descriptor_pb2.MethodDescriptorProto(
                    name='GetFoo',
                    input_type='google.example.v1.GetFooRequest',
                    output_type='google.example.v1.GetFooResponse',
                ), ),
            ), ),
        ),
    )

    # Create an API with those protos.
    api_schema = api.API.build(fd, package='google.example.v1')

    # Establish that the API has the data expected.
    assert isinstance(api_schema, api.API)
    assert len(api_schema.all_protos) == 3
    assert len(api_schema.protos) == 2
    assert 'google.dep.ImportedMessage' not in api_schema.messages
    assert 'google.example.v1.common.Bar' in api_schema.messages
    assert 'google.example.v1.Foo' in api_schema.messages
    assert 'google.example.v1.GetFooRequest' in api_schema.messages
    assert 'google.example.v1.GetFooResponse' in api_schema.messages
    assert 'google.example.v1.FooService' in api_schema.services
    assert len(api_schema.enums) == 0
    assert api_schema.protos['foo.proto'].python_modules == (imp.Import(
        package=('google', 'dep'), module='dep_pb2'), )

    assert api_schema.requires_package(('google', 'example', 'v1'))
    assert not api_schema.requires_package(('elgoog', 'example', 'v1'))

    # Establish that the subpackages work.
    assert 'common' in api_schema.subpackages
    sub = api_schema.subpackages['common']
    assert len(sub.protos) == 1
    assert 'google.example.v1.common.Bar' in sub.messages
    assert 'google.example.v1.Foo' not in sub.messages
def test_str_untyped_api_core():
    i = imp.Import(package=('foo', 'api_core'), module='baz', alias='bacon')
    assert str(i) == 'from foo.api_core import baz as bacon  # type: ignore'
Exemple #17
0
def test_str_untyped_pb2():
    i = imp.Import(package=('foo', 'bar'), module='baz_pb2', alias='bacon')
    assert str(i) == 'from foo.bar import baz_pb2 as bacon  # type: ignore'