danielgtaylor / danielgtaylor/python-betterproto

Proposal to add default values in deserialisation

Offen
#356 5 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
Vorherrschende Sprache
Python
Sterne
1.8k
Forks
234
PR-Merge-Kennzahlen
Keine gemergten PRs in 30 T.

Beschreibung

[Protobuf does not serialise default values](https://developers.google.com/protocol-buffers/docs/proto3#default), however the betterproto objects could retain them.

Consider:
```protobuf
enum MyType {
A = 0;
B = 1;
}

message MyMessage {
string name = 1;
MyType type = 2;
}
```

I create a new message with the default enum:
```
m = api.MyMessage(name='foo', type=api.MyType(0))
```

If I send this message, and the receiver creates a betterproto message, they get:
```
api.MyMessage(name='foo')
```

Fortunately betterproto has equality between these messages, even though in the latter type is not specified.

However, this is not particularly easy to find without a bit of digging. I believe it would be simpler to just add the default values when deserialising, which is actually pretty simple:

```python
def _fill_defaults(message: api.betterproto.Message) -> api.betterproto.Message:
message_keys = {}
for k in message.__dict__.keys():
if k not in ["_serialized_on_wire", "_unknown_fields", "_group_current"]:
current_value = getattr(message, k)
if not current_value:
message_keys[k] = message._get_field_default(k)
else:
message_keys[k] = current_value
return message.__class__(**message_keys)
```

I'm sure there is a neater way of handling the internal attributes e.g. `_serialise_on_wire`.

With the above, the receiver would have the same object as the sender, which is more intuitive.

Beitragsleitfaden

Beitragsleitfaden öffnen

Bewertung

Dieses Issue wurde noch nicht bewertet.

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.