-
Notifications
You must be signed in to change notification settings - Fork 217
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
One-of pattern matching not supported by static type analysis tools #601
Comments
This was just changed, this seems not ideal. |
What does the default implementation do when accessing an unset field? I'm slightly more inclined to follow that behaviour but I've been thinking about this. The change would need to be made quickly to minimise disruption in this regard. |
As of version 2.0.0b7, accessing an ordinary unset field gives the default value, whereas accessing an unset field which is part of a oneof group raises an AttributeError: message Empty {}
message Test {
oneof foo {
bool on = 1;
}
int32 i = 2;
Empty e = 3;
} test = Test()
print(test.i) # 0
print(test.e) # Empty()
print(test.on) # AttributeError The intention behind raising an AttributeError was to make the match-case-pattern for accessing oneof groups work, so that static analysis tools can detect errors. Following the default behavior in the oneof-case would mean to simply rollback that change. But in both cases there would be no way to access a oneof group in a type checked manner. This is why I like the idea to fix the pattern instead of rolling back. |
Just for clarification: The pattern shown in the opening post is correctly working as intended. It is just incompatible with typical assumptions made by type checkers (e.g. fields are always set). So all four cases are practically reachable for the Python interpreter. They are just unreachable from a type checker's point of view. |
I meant the google implementation |
Oh, I see. The google implementation gives the default value. Apparently, you are supposed to use the test = Test()
print(test.on) # False
print(test.HasField("on")) # False |
Yeah ok. I think doing this the way you've suggested makes the most sense then |
According to the Readme it should be possible to access fields of a oneof-group by pattern matching so that static analysis tools can provide type hints:
However, the tool
pyright
(used by thepylance
extension for vscode) does not provide type hints for the second and third case. I first thought this was a bug in pyright, but according to a pyright maintainer this is actually intentional. Apparently, from the point of view of a type checker, the second and third case blocks are unreachable (this pattern even triggers a warning from pyright when configured accordingly).Possible solution
Let's assume we change the compiler to generate the following class:
Then the following match statement is properly supported by pyright:
I think one could argue that it is actually correct to mark these fields optional. What do you think?
System Information
The text was updated successfully, but these errors were encountered: