Skip to content
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

Shorter syntax for optional field #63

Closed
hongquan opened this issue May 27, 2019 · 5 comments
Closed

Shorter syntax for optional field #63

hongquan opened this issue May 27, 2019 · 5 comments

Comments

@hongquan
Copy link

In proto3, every fields are optional. But in Python code, to declare field as optional, I have to write long lines of code:

def optional_field(number: int) -> dataclasses.Field:
    return field(number, default=None)

@message
@dataclass
class DeviceToServerMessage:
    parking_report: Optional[DeviceDataRequest] = optional_field(1)
    firmware_update_check: Optional[FirmwareUpdateRequest] = optional_field(2)
    reg_request: Optional[DeviceRegistrationRequest] = optional_field(3)
    auth_request: Optional[DeviceAuthenticationRequest] = optional_field(4)
    # For mesh network
    mesh_src: Optional[str] = optional_field(13)

Not only do I have to wrap type with Optional, but also do I have to pass default=None to field() call.

Do you have any idea to make it shorter and look not duplicate?

@eigenein
Copy link
Owner

Good point, but I need to think about it a little longer to come up with a good solution.

The point is that Optional[...] and default=... are a bit different things. The former declares a field to be nullable, and the latter declares a default value when no value is provided. I also aimed to keep the standard @dataclass usage unchanged. For example, all of these examples are valid:

@dataclass
class Foo:
    bar: Optional[int] = 42  # nullable but default is not `None`

Foo(bar=None)  # still can be set to `None`
Foo()  # or use default `42`
Foo(bar=1)  # or still provide a different value

And this is not valid:

@dataclass
class Foo:
    bar: Optional[int]

Foo()  # `bar` must be provided

But I understand this is a common case to set optional an field to None upon (de-)serialization, so I need to look at different possibilities to minimise number of bad surprises to users

@hongquan
Copy link
Author

hongquan commented May 30, 2019

Could you pre-define the optional_field in pure_protobuf? I think it can be helpful if you plan to make a "code generator" in the future, to generate Python code from *.proto files.

I'm working in an IoT project. To ease the collaboration with firmware developers, I have to keep a *.proto file. They will use some tool to generate to C code and I handcraft the Python code based on it. It would reduce mistake if there is also a tool to generate Python code (in case the proto changes a lot and I lost track).

@eigenein
Copy link
Owner

True, I'll add the optional_field thingy. I've also created #64 to keep in mind the code generator, which is a really good suggestion

eigenein added a commit that referenced this issue Jul 2, 2019
New: #63 convenience method for an optional field
@eigenein
Copy link
Owner

eigenein commented Jul 2, 2019

Sorry for the slow action, the function is now added

@hongquan
Copy link
Author

hongquan commented Jul 2, 2019

Thank @eigenein

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants