Skip to content

Generated client cannot handle Well Known Types as RPC return values #39

@boukeversteegh

Description

@boukeversteegh

Hi!

I'm running into some trouble returning google.protobuf.Int32Value from a unary RPC call.

This is my service:

service Go {
    // ...
    rpc StartTrainingGame (TrainingGameRequest) returns (google.protobuf.Int32Value);
}

When I call that service (await self.client.start_training_game(**kwargs)), an exception is thrown

'_SpecialForm' object has no attribute 'FromString'.

Debugging reveals the following stack frame (proto.py:54, in grpclib)

    def decode(
        self,  # <grpclib.encoding.proto.ProtoCodec object at 0x000001CE2A687BC8>
        data: bytes,  # b'\x08\x04'
        message_type: Type['IProtoMessage'],  # typing.Union[int, NoneType]
    ) -> 'IProtoMessage':
        return message_type.FromString(data)

As is visible, message_type is expected to be IProtoMessage, with a method FromString on it. However, because the Well-Known type is converted to Union[int, NoneType], this method cannot be called there.

I suspect that the current implementation handles these well-known types separately, and this works well when they are embedded in a message, but not when they are the top-level return-value from an RPC call. I intended to use Google's wrappers mainly to be able to return primitive values from RPC-calls.

The generated Client shows the following:

    async def start_training_game(...) -> Optional[int]:
        ...
        return await self._unary_unary(
            "/anagon.ai.go.Go/StartTrainingGame", request, Optional[int],
        )

I suppose that the generated code should specify the type as the python-generated equivalent of Int32Value, instead of Optional[int].

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions