Skip to content

Shorter optional fields #499

Open
Open
@MicaelJarniac

Description

@MicaelJarniac

Optional fields generate very long and repetitive code.

The idea is to use shorter and simpler code, and internally consider it as a field having optional=True, group=f"_{field_name}".

Related to #459.

Proto file

syntax = "proto3";

message Foo {
    optional uint32 bar = 1;
};

Currently generated code

from dataclasses import dataclass

import betterproto

@dataclass(eq=False, repr=False)
class Foo(betterproto.Message):
    bar: Optional[int] = betterproto.uint32_field(
        1, optional=True, group="_bar"
    )

Idea A

Read the type-hint of the field, and if it's a union of a type with None, consider it an optional field.

This might be a bad idea if unions of a type + None are used for something other than optional fields.

An example implementation of detecting optional fields can be found here: cattrs/converters.py.

from dataclasses import dataclass
from typing import Union, Optional

import betterproto

@dataclass(eq=False, repr=False)
class Foo(betterproto.Message):
    bar: Optional[int] = betterproto.uint32_field(1)

Idea B

Use a custom type-hint that indicates a field is optional, and is correctly understood by type-checkers as Optional.

from dataclasses import dataclass

import betterproto

@dataclass(eq=False, repr=False)
class Foo(betterproto.Message):
    bar: betterproto.OptionalField[int] = betterproto.uint32_field(1)

It could possibly be implemented something like this:
Annotated

from typing import Optional, TypeVar
from typing_extensions import Annotated

T = TypeVar("T")

optional_metadata = object()  # or another sentinel

OptionalField = Annotated[Optional[T], optional_metadata]

Idea C

Automatically add group=f"_{field_name}" if optional=True and no group specified.

from dataclasses import dataclass

import betterproto


@dataclass(eq=False, repr=False)
class Foo(betterproto.Message):
    bar: Optional[int] = betterproto.uint32_field(1, optional=True)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestmediumMedium effort issue, can fit in a single PR

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions