Skip to content

Commit 284e479

Browse files
AniketsyFokko
andauthored
Make Not expression JSON serializable (#2593)
#2520 This PR makes the `Not` boolean expression in `pyiceberg` JSON serializable using Pydantic Please let me know if my approach or fix needs any improvements . I’m open to feedback and happy to make changes based on suggestions. Thank you ! --------- Co-authored-by: Fokko Driesprong <[email protected]>
1 parent 5dcbcb2 commit 284e479

File tree

2 files changed

+19
-4
lines changed

2 files changed

+19
-4
lines changed

pyiceberg/expressions/__init__.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -350,22 +350,31 @@ def __getnewargs__(self) -> Tuple[BooleanExpression, BooleanExpression]:
350350
return (self.left, self.right)
351351

352352

353-
class Not(BooleanExpression):
353+
class Not(IcebergBaseModel, BooleanExpression):
354354
"""NOT operation expression - logical negation."""
355355

356-
child: BooleanExpression
356+
model_config = ConfigDict(arbitrary_types_allowed=True)
357+
358+
type: TypingLiteral["not"] = Field(default="not")
359+
child: BooleanExpression = Field()
360+
361+
def __init__(self, child: BooleanExpression, **_: Any) -> None:
362+
super().__init__(child=child)
357363

358-
def __new__(cls, child: BooleanExpression) -> BooleanExpression: # type: ignore
364+
def __new__(cls, child: BooleanExpression, **_: Any) -> BooleanExpression: # type: ignore
359365
if child is AlwaysTrue():
360366
return AlwaysFalse()
361367
elif child is AlwaysFalse():
362368
return AlwaysTrue()
363369
elif isinstance(child, Not):
364370
return child.child
365371
obj = super().__new__(cls)
366-
obj.child = child
367372
return obj
368373

374+
def __str__(self) -> str:
375+
"""Return the string representation of the Not class."""
376+
return f"Not(child={self.child})"
377+
369378
def __repr__(self) -> str:
370379
"""Return the string representation of the Not class."""
371380
return f"Not(child={repr(self.child)})"

tests/expressions/test_expressions.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,12 @@ def test_not() -> None:
711711
assert not_ == pickle.loads(pickle.dumps(not_))
712712

713713

714+
def test_not_json_serialization_and_deserialization() -> None:
715+
not_expr = Not(GreaterThan("a", 22))
716+
json_str = not_expr.model_dump_json()
717+
assert json_str == """{"type":"not","child":{"term":"a","type":"gt","value":22}}"""
718+
719+
714720
def test_always_true() -> None:
715721
always_true = AlwaysTrue()
716722
assert always_true.model_dump_json() == '"true"'

0 commit comments

Comments
 (0)