danielgtaylor / danielgtaylor/python-betterproto

Proposal to add default values in deserialisation

オープン
#356 コメント 5 件 リアクション 0 件 担当者 0 名 GitHub で見る
主要言語
Python
スター
1.8k
フォーク
234
PR マージ指標
30日以内にマージされた PR はありません

説明

[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.

コントリビューションガイド

コントリビューションガイドを開く

調査の方向性

issue ではソースファイルもテストも指定されていません。まず betterproto.Message における Python のデシリアライズ経路を追跡し、_get_field_default と内部属性がどのように扱われているかを確認してください。完了の条件は、デシリアライズされたメッセージが protobuf の明示的なデフォルト値を保持しつつ、現在のシリアライズおよび等価性の動作を維持することです。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
python
領域
backend-api-design
issue の種類
機能追加
難易度
5/5
見積もり時間
1週間以上
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
35/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。