apache / apache/iceberg-python
Expression constructors are not mypy-compatible without the pydantic plugin
- 主要語言
- Python
- 星號
- 1.1k
- 分支
- 581
- 平均合併
- 1 天 17 小時
- 30 天內合併 PR
- 78
描述
Constructing expression predicates like `EqualTo("col", value)` produces mypy errors because the Pydantic model field declarations use `UnboundTerm` as the type for `term`, and without the pydantic mypy plugin active, mypy generates `__init__` signatures from the field types rather than from the explicit `__init__` overrides.
**Example:**
```python
from pyiceberg import expressions as ice
expr = ice.EqualTo("my_column", 42)
```
**mypy output (v1.19.1, pyiceberg 0.11.0, no pydantic mypy plugin):**
```
error: Argument 1 to "EqualTo" has incompatible type "str"; expected "UnboundTerm" [arg-type]
```
**Root cause:**
The base classes define explicit `__init__` methods that accept `str | UnboundTerm`:
- [`UnboundPredicate.__init__`](https://github.com/apache/iceberg-python/blob/main/pyiceberg/expressions/__init__.py#L500): `def __init__(self, term: str | UnboundTerm, **kwargs: Any) -> None`
- [`LiteralPredicate.__init__`](https://github.com/apache/iceberg-python/blob/main/pyiceberg/expressions/__init__.py#L864): `def __init__(self, term: str | UnboundTerm, literal: Any | None = None, **kwargs: Any) -> None`
- [`UnaryPredicate.__init__`](https://github.com/apache/iceberg-python/blob/main/pyiceberg/expressions/__init__.py#L520): `def __init__(self, term: str | UnboundTerm, **_: Any) -> None`
But since these classes extend `IcebergBaseModel` (Pydantic `BaseModel`), mypy ignores the explicit `__init__` and instead generates the constructor signature from the field declaration `term: UnboundTerm`, which does not include `str`.
This affects all predicate constructors: `EqualTo`, `NotEqualTo`, `GreaterThan`, `GreaterThanOrEqual`, `LessThan`, `LessThanOrEqual`, `IsNull`, `NotNull`, `IsNaN`, `NotNaN`, `In`, `NotIn`, `StartsWith`, `NotStartsWith`.
**Workaround:**
Downstream projects can either enable the pydantic mypy plugin or suppress type checking for the affected call sites.
**Possible fix:**
Widen the field type annotation on `UnboundPredicate` from `term: UnboundTerm` to `term: str | UnboundTerm` with a validator that coerces `str` to `UnboundTerm`. This way the type seen by mypy (from the field declaration) matches what the constructor actually accepts at runtime, regardless of whether the pydantic mypy plugin is enabled.
貢獻指南
這個儲存庫沒有索引到貢獻指南
研究方向
從 pyiceberg/expressions/__init__.py 中的 UnboundPredicate、LiteralPredicate 和 UnaryPredicate 建構函式及其 term 欄位宣告開始。檢查現有的 validator 行為,然後驗證不使用 Pydantic 外掛程式的 mypy 是否接受列出的 predicate 建構函式,以及字串 term 在執行階段是否仍會被正確強制轉換。
由索引模型根據 Issue 內容生成。
評估
- 技術堆疊
- python
- 領域
- developer-experience
- Issue 類型
- 缺陷
- 難度
- 3/5
- 預估耗時
- 1-2 天
- 活躍度
- 冷清
- 描述清晰度
- 基本清楚
- 新手友好度
- 65/100