-
Notifications
You must be signed in to change notification settings - Fork 219
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support using Google's wrapper types as RPC output values #40
Support using Google's wrapper types as RPC output values #40
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some minor suggestions on the code.
I assume that new test example would have failed before?
If you're up for it I think it would be useful to document the things you've identified as still to do in a new issue, to make it easier to pick up and finish.
betterproto/plugin.py
Outdated
} | ||
|
||
|
||
def get_ref_type(package: str, imports: set, type_name: str) -> str: | ||
def get_wrapper_type(type_name: str) -> (Any, str): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure about the trade off here in keeping WRAPPER_TYPES declarative as a simple mapping at the cost of not being able to actually use it directly as a mapping.
What about replacing WRAPPER_TYPES and get_wrapper_type here with:
WRAPPER_TYPES = {
goog_type.DESCRIPTOR.full_name: (goog_type, simple_name)
for goog_type, simple_name in (
(google.protobuf.wrappers_pb2.DoubleValue, "float"),
(google.protobuf.wrappers_pb2.FloatValue, "float"),
(google.protobuf.wrappers_pb2.Int64Value, "int"),
(google.protobuf.wrappers_pb2.UInt64Value, "int"),
(google.protobuf.wrappers_pb2.Int32Value, "int"),
(google.protobuf.wrappers_pb2.UInt32Value, "int"),
(google.protobuf.wrappers_pb2.BoolValue, "bool"),
(google.protobuf.wrappers_pb2.StringValue, "str"),
(google.protobuf.wrappers_pb2.BytesValue, "bytes"),
)
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see what you mean, good suggestion! That get_wrapper_type
a bit ugly indeed, and would be nice to not need it, while at the same time, I did not like the unchecked references to packages. Your idea solves both, although it embarrassingly took me a several re-reads to fully understand it.
To build on your idea, how about two maps? Same concept but less inlining..
WRAPPER_TYPES = {
google.protobuf.wrappers_pb2.DoubleValue: "float",
google.protobuf.wrappers_pb2.FloatValue: "float",
google.protobuf.wrappers_pb2.Int64Value: "int",
google.protobuf.wrappers_pb2.UInt64Value: "int",
google.protobuf.wrappers_pb2.Int32Value: "int",
google.protobuf.wrappers_pb2.UInt32Value: "int",
google.protobuf.wrappers_pb2.BoolValue: "bool",
google.protobuf.wrappers_pb2.StringValue: "str",
google.protobuf.wrappers_pb2.BytesValue: "bytes",
}
WRAPPERS = {w.DESCRIPTOR.full_name: w for w in WRAPPER_TYPES.keys()}
# usage
wrapper = WRAPPERS['google.protobuf.UInt64Value']
print(wrapper.__module__)
print(WRAPPER_TYPES[wrapper])
the only think i don't like about it is having two similar maps with similar names.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My preference is for the single WRAPPER_TYPES dict for conciseness, though I get that the idiom might not be as clear.
As you prefer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, I found out we could also just extract the desired type from instance().value , so we don't need the tuples in the map
wrappers = {
'google.protobuf.DoubleValue': google.protobuf.wrappers_pb2.DoubleValue,
'google.protobuf.FloatValue' : google.protobuf.wrappers_pb2.FloatValue,
'google.protobuf.Int64Value' : google.protobuf.wrappers_pb2.Int64Value,
'google.protobuf.UInt64Value' : google.protobuf.wrappers_pb2.UInt64Value,
'google.protobuf.Int32Value' : google.protobuf.wrappers_pb2.Int32Value,
'google.protobuf.UInt32Value' : google.protobuf.wrappers_pb2.UInt32Value,
'google.protobuf.BoolValue' : google.protobuf.wrappers_pb2.BoolValue,
'google.protobuf.StringValue' : google.protobuf.wrappers_pb2.StringValue,
'google.protobuf.BytesValue' : google.protobuf.wrappers_pb2.BytesValue,
}
# usage
wrapper = wrappers['google.protobuf.BytesValue']
mapped_type = type(wrapper().value) # string
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've implemented this concept. Please see 8f0caf1
The provided example indeed would not have worked before, because the generated call to the async def start_training_game(self) -> Optional[int]:
...
return await self._unary_unary(
"/anagon.ai.go.Go/StartTrainingGame", request, Optional[int],
) I'm currently also working on structuring the tests in such a way that these kinds of examples can be tested more easily, but for now i don't have a test for this..
yes, certainly! i'll do that |
**EDIT: **
|
Well, oops. The message above was ment for #47 ! This PR can actually be merged... sorry for the confusion |
This PR fixes #39
Well known types as Output
Adds support for returning Google's well-known wrapper types directly from Services.
Supported added for
BoolValue
BytesValue
DoubleValue
FloatValue
Int32Value
Int64Value
StringValue
UInt32Value
UInt64Value
Not included in this PR
Empty
— However, Importing well known types #9 can be fixed relatively easily now.Notes:
googletypes_service.proto
to the test-cases, so the output can be manually verified.Let me know if anything doesn't match style requirements, or some other changes need to be made.