Skip to content

Conversation

@leenr
Copy link
Contributor

@leenr leenr commented Dec 13, 2020

Example messages.proto:

syntax = "proto3";

import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";

package things.messages;

message DoThingRequest {
  string name = 1;
  repeated string comments = 2;
  google.protobuf.Timestamp when = 3;
  google.protobuf.Duration duration = 4;
}

message DoThingResponse {
  repeated string names = 1;
}

Example service.proto:

syntax = "proto3";

import "messages.proto";

package things.service;

service Test {
  rpc DoThing (things.messages.DoThingRequest) returns (things.messages.DoThingResponse);
}

Using current master (1d54ef8):

$ protoc --python_betterproto_out=.local/servicemethod_imports_issue/output_master_1d54ef8 --proto_path=.local/servicemethod_imports_issue/proto .local/servicemethod_imports_issue/proto/*.proto
Writing __init__.py
Writing things/__init__.py
Writing things/messages/__init__.py
Writing things/service/__init__.py

$ head -n20 .local/servicemethod_imports_issue/output_master_1d54ef8/things/service/__init__.py
# Generated by the protocol buffer compiler.  DO NOT EDIT!
# sources: service.proto
# plugin: python-betterproto
from dataclasses import dataclass
from typing import Dict, Optional

import betterproto
from betterproto.grpc.grpclib_server import ServiceBase
import grpclib


class TestStub(betterproto.ServiceStub):
    async def do_thing(
        self,
        *,
        name: str = "",
        comments: Optional[List[str]] = None,
        when: datetime = None,
        duration: timedelta = None,
    ) -> "_messages__.DoThingResponse":

Notice List, datetime and timedelta being used in type annotation, but not listed in imports.


Using version from this PR:

$ protoc --python_betterproto_out=.local/servicemethod_imports_issue/output_fix_b854d38 --proto_path=.local/servicemethod_imports_issue/proto .local/servicemethod_imports_issue/proto/*.proto
Writing __init__.py
Writing things/__init__.py
Writing things/messages/__init__.py
Writing things/service/__init__.py

$ head -n21 .local/servicemethod_imports_issue/output_fix_b854d38/things/service/__init__.py
# Generated by the protocol buffer compiler.  DO NOT EDIT!
# sources: service.proto
# plugin: python-betterproto
from dataclasses import dataclass
from datetime import datetime, timedelta
from typing import Dict, List, Optional

import betterproto
from betterproto.grpc.grpclib_server import ServiceBase
import grpclib


class TestStub(betterproto.ServiceStub):
    async def do_thing(
        self,
        *,
        name: str = "",
        comments: Optional[List[str]] = None,
        when: datetime = None,
        duration: timedelta = None,
    ) -> "_messages__.DoThingResponse":

I've also implemented a copy of test's "things service" (service), separated in two protobuf packages: one with messages, other with service definition, and added Duration and Timestamp fields to DoThingRequest message.
It fails on current master (1d54ef8), but succeeds with the changes from this PR.

…hod type annotations

It can happen, for example, when repeated field is used in the
request message for the service method and request message is in
different package than the service definition.
Copy link
Collaborator

@nat-n nat-n left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix :)

for f in self.py_input_message.fields:
if f.default_value_string == "None":
self.output_file.typing_imports.add("Optional")
f.add_imports_to(self.output_file)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do I understand correctly that this line is the actual fix?

Copy link
Contributor Author

@leenr leenr Jan 25, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, along with the other changes.

I've deleted adding "Optional" import two lines above because there already is the code to add it in the FieldCompiler class:

if "Optional[" in annotation:
    imports.add("Optional")

@huan
Copy link

huan commented Feb 27, 2021

Looking forward to having this PR merged!

It will fix my wechaty/grpc#120

@nat-n nat-n merged commit 2f62189 into danielgtaylor:master Mar 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants