|
31 | 31 | TypeVar, |
32 | 32 | Union, |
33 | 33 | ) |
| 34 | +from typing import Literal as TypingLiteral |
34 | 35 |
|
35 | | -from pydantic import Field |
| 36 | +from pydantic import ConfigDict, Field |
36 | 37 |
|
37 | 38 | from pyiceberg.expressions.literals import ( |
38 | 39 | AboveMax, |
@@ -249,13 +250,18 @@ def as_bound(self) -> Type[BoundReference[L]]: |
249 | 250 | return BoundReference[L] |
250 | 251 |
|
251 | 252 |
|
252 | | -class And(BooleanExpression, IcebergBaseModel): |
| 253 | +class And(IcebergBaseModel, BooleanExpression): |
253 | 254 | """AND operation expression - logical conjunction.""" |
254 | 255 |
|
255 | | - type: str = Field(default="and", alias="type") |
| 256 | + model_config = ConfigDict(arbitrary_types_allowed=True) |
| 257 | + |
| 258 | + type: TypingLiteral["and"] = Field(default="and", alias="type") |
256 | 259 | left: BooleanExpression |
257 | 260 | right: BooleanExpression |
258 | 261 |
|
| 262 | + def __init__(self, left: BooleanExpression, right: BooleanExpression, *rest: BooleanExpression) -> None: |
| 263 | + super().__init__(left=left, right=right) |
| 264 | + |
259 | 265 | def __new__(cls, left: BooleanExpression, right: BooleanExpression, *rest: BooleanExpression) -> BooleanExpression: # type: ignore |
260 | 266 | if rest: |
261 | 267 | return _build_balanced_tree(And, (left, right, *rest)) |
@@ -292,12 +298,6 @@ def __getnewargs__(self) -> Tuple[BooleanExpression, BooleanExpression]: |
292 | 298 | """Pickle the And class.""" |
293 | 299 | return (self.left, self.right) |
294 | 300 |
|
295 | | - class Config: |
296 | | - """Pydantic configuration for And expression serialization.""" |
297 | | - |
298 | | - arbitrary_types_allowed = True |
299 | | - json_encoders = {BooleanExpression: lambda v: v.model_dump(by_alias=True) if isinstance(v, IcebergBaseModel) else str(v)} |
300 | | - |
301 | 301 |
|
302 | 302 | class Or(BooleanExpression): |
303 | 303 | """OR operation expression - logical disjunction.""" |
|
0 commit comments