danielgtaylor / danielgtaylor/python-betterproto
Shorter optional fields
- Lingua principale
- Python
- Stelle
- 1.8k
- Fork
- 234
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Descrizione
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
```proto
syntax = "proto3";
message Foo {
optional uint32 bar = 1;
};
```
### Currently generated code
```py
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`](https://github.com/python-attrs/cattrs/blob/e1db1f24fc884e152f8d19ee02de24d87e97e55a/src/cattrs/converters.py#L109-L110).
```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`.
```py
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`](https://docs.python.org/3/library/typing.html#typing.Annotated)
```py
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.
```py
from dataclasses import dataclass
import betterproto
@dataclass(eq=False, repr=False)
class Foo(betterproto.Message):
bar: Optional[int] = betterproto.uint32_field(1, optional=True)
```
Guida per i contributori
Apri la guida per i contributori
Direzione di ricerca
Inizia tracciando il percorso del generatore che produce campi Python per i campi opzionali di proto3; l’issue non indica file o test del repository. Esamina l’esempio referenziato cattrs/converters.py e confronta Ideas A, B e C prima di scegliere un approccio. Il lavoro è completato quando i campi opzionali generano codice più breve, preservando al contempo la tipizzazione corretta con Optional e il rilevamento della presenza.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- python
- Ambito
- tooling
- Tipo di issue
- Funzionalità
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Stato di attività
- Ferma
- Chiarezza
- Abbastanza chiara
- Idoneità per principianti
- 30/100