apache / apache/iceberg-python
Expression constructors are not mypy-compatible without the pydantic plugin
- Lingua principale
- Python
- Stelle
- 1.1k
- Fork
- 581
- Merge medio
- 1g 17h
- PR unite (30g)
- 78
Descrizione
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.
Guida per i contributori
Nessuna guida per i contributori indicizzata per questo repository
Valutazione
Questa issue non è ancora stata valutata.