This is an automated email from the ASF dual-hosted git repository.
fokko pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg-python.git
The following commit(s) were added to refs/heads/main by this push:
new 21416d6b Serialize true false (#2538)
21416d6b is described below
commit 21416d6b0970a2dcafa43f3aa6dd3ad17891d444
Author: nathanbijleveld <[email protected]>
AuthorDate: Thu Oct 2 21:39:51 2025 +0200
Serialize true false (#2538)
<!--
Thanks for opening a pull request!
-->
<!-- In the case this PR will resolve an issue, please replace
${GITHUB_ISSUE_ID} below with the actual Github issue id. -->
Closes #2521
# Rationale for this change
Make true/false expression serializable
## Are these changes tested?
yes
## Are there any user-facing changes?
<!-- In the case of user-facing changes, please add the changelog label.
-->
---
pyiceberg/expressions/__init__.py | 20 +++++++++++++-------
tests/expressions/test_expressions.py | 2 ++
2 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/pyiceberg/expressions/__init__.py
b/pyiceberg/expressions/__init__.py
index 2adf898f..cbebbd01 100644
--- a/pyiceberg/expressions/__init__.py
+++ b/pyiceberg/expressions/__init__.py
@@ -39,7 +39,7 @@ from pyiceberg.expressions.literals import (
literal,
)
from pyiceberg.schema import Accessor, Schema
-from pyiceberg.typedef import L, StructProtocol
+from pyiceberg.typedef import IcebergRootModel, L, StructProtocol
from pyiceberg.types import DoubleType, FloatType, NestedField
from pyiceberg.utils.singleton import Singleton
@@ -361,10 +361,14 @@ class Not(BooleanExpression):
"""Pickle the Not class."""
return (self.child,)
+ """TRUE expression."""
+
-class AlwaysTrue(BooleanExpression, Singleton):
+class AlwaysTrue(BooleanExpression, Singleton, IcebergRootModel[str]):
"""TRUE expression."""
+ root: str = "true"
+
def __invert__(self) -> AlwaysFalse:
"""Transform the Expression into its negated version."""
return AlwaysFalse()
@@ -378,9 +382,11 @@ class AlwaysTrue(BooleanExpression, Singleton):
return "AlwaysTrue()"
-class AlwaysFalse(BooleanExpression, Singleton):
+class AlwaysFalse(BooleanExpression, Singleton, IcebergRootModel[str]):
"""FALSE expression."""
+ root: str = "false"
+
def __invert__(self) -> AlwaysTrue:
"""Transform the Expression into its negated version."""
return AlwaysTrue()
@@ -732,14 +738,14 @@ class LiteralPredicate(UnboundPredicate[L], ABC):
if isinstance(lit, AboveMax):
if isinstance(self, (LessThan, LessThanOrEqual, NotEqualTo)):
- return AlwaysTrue() # type: ignore
+ return AlwaysTrue()
elif isinstance(self, (GreaterThan, GreaterThanOrEqual, EqualTo)):
- return AlwaysFalse() # type: ignore
+ return AlwaysFalse()
elif isinstance(lit, BelowMin):
if isinstance(self, (GreaterThan, GreaterThanOrEqual, NotEqualTo)):
- return AlwaysTrue() # type: ignore
+ return AlwaysTrue()
elif isinstance(self, (LessThan, LessThanOrEqual, EqualTo)):
- return AlwaysFalse() # type: ignore
+ return AlwaysFalse()
return self.as_bound(bound_term, lit)
diff --git a/tests/expressions/test_expressions.py
b/tests/expressions/test_expressions.py
index 828d3270..ac5411ff 100644
--- a/tests/expressions/test_expressions.py
+++ b/tests/expressions/test_expressions.py
@@ -738,6 +738,7 @@ def test_not() -> None:
def test_always_true() -> None:
always_true = AlwaysTrue()
+ assert always_true.model_dump_json() == '"true"'
assert str(always_true) == "AlwaysTrue()"
assert repr(always_true) == "AlwaysTrue()"
assert always_true == eval(repr(always_true))
@@ -746,6 +747,7 @@ def test_always_true() -> None:
def test_always_false() -> None:
always_false = AlwaysFalse()
+ assert always_false.model_dump_json() == '"false"'
assert str(always_false) == "AlwaysFalse()"
assert repr(always_false) == "AlwaysFalse()"
assert always_false == eval(repr(always_false))