Handle fields that clash with Python reserved keywords
This commit is contained in:
parent
eff9021529
commit
ff8463cf12
@ -155,7 +155,7 @@ You can use it like so (enable async in the interactive shell first):
|
||||
EchoResponse(values=["hello", "hello"])
|
||||
|
||||
>>> async for response in service.echo_stream(value="hello", extra_times=1)
|
||||
print(response)
|
||||
print(response)
|
||||
|
||||
EchoStreamResponse(value="hello")
|
||||
EchoStreamResponse(value="hello")
|
||||
@ -296,13 +296,13 @@ $ pipenv run tests
|
||||
- [ ] Any support
|
||||
- [x] Enum strings
|
||||
- [ ] Well known types support (timestamp, duration, wrappers)
|
||||
- [ ] Support different casing (orig vs. camel vs. others?)
|
||||
- [x] Support different casing (orig vs. camel vs. others?)
|
||||
- [ ] Async service stubs
|
||||
- [x] Unary-unary
|
||||
- [x] Server streaming response
|
||||
- [ ] Client streaming request
|
||||
- [x] Renaming messages and fields to conform to Python name standards
|
||||
- [ ] Renaming clashes with language keywords and standard library top-level packages
|
||||
- [x] Renaming clashes with language keywords
|
||||
- [x] Python package
|
||||
- [x] Automate running tests
|
||||
- [ ] Cleanup!
|
||||
|
@ -26,6 +26,8 @@ import grpclib.client
|
||||
import grpclib.const
|
||||
import stringcase
|
||||
|
||||
from .casing import safe_snake_case
|
||||
|
||||
# Proto 3 data types
|
||||
TYPE_ENUM = "enum"
|
||||
TYPE_BOOL = "bool"
|
||||
@ -642,7 +644,7 @@ class Message(ABC):
|
||||
for field in dataclasses.fields(self):
|
||||
meta = FieldMetadata.get(field)
|
||||
v = getattr(self, field.name)
|
||||
cased_name = casing(field.name)
|
||||
cased_name = casing(field.name).rstrip("_")
|
||||
if meta.proto_type == "message":
|
||||
if isinstance(v, list):
|
||||
# Convert each item.
|
||||
@ -686,7 +688,7 @@ class Message(ABC):
|
||||
self._serialized_on_wire = True
|
||||
fields_by_name = {f.name: f for f in dataclasses.fields(self)}
|
||||
for key in value:
|
||||
snake_cased = stringcase.snakecase(key)
|
||||
snake_cased = safe_snake_case(key)
|
||||
if snake_cased in fields_by_name:
|
||||
field = fields_by_name[snake_cased]
|
||||
meta = FieldMetadata.get(field)
|
||||
|
41
betterproto/casing.py
Normal file
41
betterproto/casing.py
Normal file
@ -0,0 +1,41 @@
|
||||
import stringcase
|
||||
|
||||
|
||||
def safe_snake_case(value: str) -> str:
|
||||
"""Snake case a value taking into account Python keywords."""
|
||||
value = stringcase.snakecase(value)
|
||||
if value in [
|
||||
"and",
|
||||
"as",
|
||||
"assert",
|
||||
"break",
|
||||
"class",
|
||||
"continue",
|
||||
"def",
|
||||
"del",
|
||||
"elif",
|
||||
"else",
|
||||
"except",
|
||||
"finally",
|
||||
"for",
|
||||
"from",
|
||||
"global",
|
||||
"if",
|
||||
"import",
|
||||
"in",
|
||||
"is",
|
||||
"lambda",
|
||||
"nonlocal",
|
||||
"not",
|
||||
"or",
|
||||
"pass",
|
||||
"raise",
|
||||
"return",
|
||||
"try",
|
||||
"while",
|
||||
"with",
|
||||
"yield",
|
||||
]:
|
||||
# https://www.python.org/dev/peps/pep-0008/#descriptive-naming-styles
|
||||
value += "_"
|
||||
return value
|
@ -27,6 +27,8 @@ from google.protobuf.descriptor_pb2 import (
|
||||
ServiceDescriptorProto,
|
||||
)
|
||||
|
||||
from betterproto.casing import safe_snake_case
|
||||
|
||||
|
||||
def get_ref_type(package: str, imports: set, type_name: str) -> str:
|
||||
"""
|
||||
@ -255,7 +257,7 @@ def generate_code(request, response):
|
||||
data["properties"].append(
|
||||
{
|
||||
"name": f.name,
|
||||
"py_name": stringcase.snakecase(f.name),
|
||||
"py_name": safe_snake_case(f.name),
|
||||
"number": f.number,
|
||||
"comment": get_comment(proto_file, path + [2, i]),
|
||||
"proto_type": int(f.type),
|
||||
|
5
betterproto/tests/keywords.json
Normal file
5
betterproto/tests/keywords.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"for": 1,
|
||||
"with": 2,
|
||||
"as": 3
|
||||
}
|
7
betterproto/tests/keywords.proto
Normal file
7
betterproto/tests/keywords.proto
Normal file
@ -0,0 +1,7 @@
|
||||
syntax = "proto3";
|
||||
|
||||
message Test {
|
||||
int32 for = 1;
|
||||
int32 with = 2;
|
||||
int32 as = 3;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user