danielgtaylor / danielgtaylor/python-betterproto

One-of pattern matching not supported by static type analysis tools

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

説明

According to the [Readme](https://github.com/danielgtaylor/python-betterproto/blob/master/README.md#one-of-support) it should be possible to access fields of a oneof-group by pattern matching so that static analysis tools can provide type hints:

```python3
test = Test()
match test:
case Test(on=value):
print(value) # value: bool
case Test(count=value):
print(value) # value: int
case Test(name=value):
print(value) # value: str
case _:
print("No value provided")
```

However, the tool `pyright` (used by the `pylance` extension for vscode) does not provide type hints for the second and third case. I first thought this was a bug in pyright, but [according to a pyright maintainer](https://github.com/microsoft/pyright/issues/8789#issuecomment-2299612496) this is actually intentional. Apparently, from the point of view of a type checker, the second and third case blocks are unreachable (this pattern even triggers a warning from pyright when configured accordingly).

## Possible solution

Let's assume we change the compiler to generate the following class:

```python3
@dataclass(eq=False, repr=False)
class Test(betterproto.Message):
on: Optional[bool] = betterproto.bool_field(1, group="foo")
count: Optional[int] = betterproto.int32_field(2, group="foo")
name: Optional[str] = betterproto.string_field(3, group="foo")
```

Then the following match statement is properly supported by pyright:

```python3
test = Test()
match test:
case Test(on=bool(value)):
print(value) # value: bool
case Test(count=int(value)):
print(value) # value: int
case Test(name=str(value)):
print(value) # value: str
case _:
print("No value provided")
```

I think one could argue that it is actually correct to mark these fields optional. What do you think?

## System Information
* python 3.11.9
* betterproto 2.0.0b7
* pylance v2024.8.1

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

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

調査の方向性

README の one-of サポートセクションと、oneof フィールドに対するコンパイラー出力から始めます。生成された Test アノテーションを pyright のパターンマッチングの例と比較し、生成された oneof フィールドが意図した型ヒントを提供しつつ、既存の oneof の動作を壊していないことを確認します。

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

評価

技術スタック
python
領域
tooling
issue の種類
機能追加
難易度
4/5
見積もり時間
3〜5日
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
35/100

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

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