danielgtaylor / danielgtaylor/python-betterproto

Functions are missing parameters when message name has sequential capital casing

Open
#184 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
1.8k
Forks
234
PR merge metrics
No merged PRs in 30d

Description

"sequential capital casing" is what I'm calling the capital letters `UIR` in name `EchoUIRequest`.

for protobuf example

```protobuf
message EchoUIRequest {
string value = 1;
// Number of extra times to echo
uint32 extra_times = 2;
}

service Echo {
rpc Echo(EchoUIRequest) returns (EchoResponse);
}
```

With `betterproto-2.0.0b2`, when bindings are generated when the message name has sequential capital letters, the function is missing its parameters.

e.g.
```python3
class EchoStub(betterproto.ServiceStub):
async def echo(self) -> "EchoResponse":
```
instead of
```python3
class EchoStub(betterproto.ServiceStub):
async def echo(
self, *, value: str = "", extra_times: int = 0
) -> "EchoResponse":
```

Using release `betterproto-1.2.5`, it works correctly.

## Repro:

Using `betterproto-2.0.0b2`

Given: test.proto
```protobuf
syntax = "proto3";

package echo;

message EchoRequest {
string value = 1;
// Number of extra times to echo
uint32 extra_times = 2;
}

message EchoUIRequest {
string value = 1;
// Number of extra times to echo
uint32 extra_times = 2;
}

message EchoResponse {
repeated string values = 1;
}

service Echo {
rpc EchoCorrect(EchoRequest) returns (EchoResponse);
rpc EchoIncorrect(EchoUIRequest) returns (EchoResponse);
}
```
When generated via `python3 -m grpc_tools.protoc -I . --python_betterproto_out=. test.proto`, the generated function `EchoStub.echo_incorrect()` is missing all its parameters, where `EchoStub.echo_correct()` has them.

`echo/__init__.py` contains:
```python3
# Generated by the protocol buffer compiler. DO NOT EDIT!
# sources: test.proto
# plugin: python-betterproto
from dataclasses import dataclass
from typing import List

import betterproto
import grpclib

@dataclass(eq=False, repr=False)
class EchoRequest(betterproto.Message):
value: str = betterproto.string_field(1)
# Number of extra times to echo
extra_times: int = betterproto.uint32_field(2)

def __post_init__(self) -> None:
super().__post_init__()

@dataclass(eq=False, repr=False)
class EchoUiRequest(betterproto.Message):
value: str = betterproto.string_field(1)
# Number of extra times to echo
extra_times: int = betterproto.uint32_field(2)

def __post_init__(self) -> None:
super().__post_init__()

@dataclass(eq=False, repr=False)
class EchoResponse(betterproto.Message):
values: List[str] = betterproto.string_field(1)

def __post_init__(self) -> None:
super().__post_init__()

class EchoStub(betterproto.ServiceStub):
async def echo_correct(
self, *, value: str = "", extra_times: int = 0
) -> "EchoResponse":

request = EchoRequest()
request.value = value
request.extra_times = extra_times

return await self._unary_unary("/echo.Echo/EchoCorrect", request, EchoResponse)

async def echo_incorrect(self) -> "EchoResponse":

request = EchoUiRequest()

return await self._unary_unary(
"/echo.Echo/EchoIncorrect", request, EchoResponse
)
```

Expected: `echo_correct` and `echo_incorrect` should be identical.

Note: v1 appears correct (`betterproto-1.2.5`), as `echo_correct()` and `echo_incorrect()` are identical.

```python3
# Generated by the protocol buffer compiler. DO NOT EDIT!
# sources: test.proto
# plugin: python-betterproto
from dataclasses import dataclass
from typing import List

import betterproto
import grpclib

@dataclass
class EchoRequest(betterproto.Message):
value: str = betterproto.string_field(1)
# Number of extra times to echo
extra_times: int = betterproto.uint32_field(2)

@dataclass
class EchoUIRequest(betterproto.Message):
value: str = betterproto.string_field(1)
# Number of extra times to echo
extra_times: int = betterproto.uint32_field(2)

@dataclass
class EchoResponse(betterproto.Message):
values: List[str] = betterproto.string_field(1)

class EchoStub(betterproto.ServiceStub):
async def echo_correct(
self, *, value: str = "", extra_times: int = 0
) -> EchoResponse:
request = EchoRequest()
request.value = value
request.extra_times = extra_times

return await self._unary_unary("/echo.Echo/EchoCorrect", request, EchoResponse,)

async def echo_incorrect(
self, *, value: str = "", extra_times: int = 0
) -> EchoResponse:
request = EchoUIRequest()
request.value = value
request.extra_times = extra_times

return await self._unary_unary(
"/echo.Echo/EchoIncorrect", request, EchoResponse,
)
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.