From 3efd6d780a61f19de7763de053e5bc0d05ebf84c Mon Sep 17 00:00:00 2001 From: BharatDeva <278575558+BharatDeva@users.noreply.github.com> Date: Mon, 20 Jul 2026 22:32:32 -0500 Subject: [PATCH 1/2] Fix residual NotNaN for null partition values --- pyiceberg/expressions/visitors.py | 6 +++--- tests/expressions/test_residual_evaluator.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pyiceberg/expressions/visitors.py b/pyiceberg/expressions/visitors.py index 4781aee82d..209a57a325 100644 --- a/pyiceberg/expressions/visitors.py +++ b/pyiceberg/expressions/visitors.py @@ -1874,10 +1874,10 @@ def visit_is_nan(self, term: BoundTerm) -> BooleanExpression: def visit_not_nan(self, term: BoundTerm) -> BooleanExpression: val = term.eval(self.struct) - if isinstance(val, SupportsFloat) and not math.isnan(val): - return self.visit_true() - else: + if isinstance(val, SupportsFloat) and math.isnan(val): return self.visit_false() + else: + return self.visit_true() def visit_less_than(self, term: BoundTerm, literal: LiteralValue) -> BooleanExpression: if term.eval(self.struct) < literal.value: diff --git a/tests/expressions/test_residual_evaluator.py b/tests/expressions/test_residual_evaluator.py index 375639ee7b..29dbfcea8d 100644 --- a/tests/expressions/test_residual_evaluator.py +++ b/tests/expressions/test_residual_evaluator.py @@ -211,7 +211,7 @@ def test_is_not_nan() -> None: res_eval = residual_evaluator_of(spec=spec, expr=predicate, case_sensitive=True, schema=schema) residual = res_eval.residual_for(Record(None)) - assert residual == AlwaysFalse() + assert residual == AlwaysTrue() residual = res_eval.residual_for(Record(2)) assert residual == AlwaysTrue() @@ -223,7 +223,7 @@ def test_is_not_nan() -> None: res_eval = residual_evaluator_of(spec=spec, expr=predicate, case_sensitive=True, schema=schema) residual = res_eval.residual_for(Record(None)) - assert residual == AlwaysFalse() + assert residual == AlwaysTrue() residual = res_eval.residual_for(Record(2)) assert residual == AlwaysTrue() From bbeaee9d752c0169d5cca7c7a17bd9acb17cf439 Mon Sep 17 00:00:00 2001 From: Kevin Liu Date: Fri, 21 Aug 2026 10:16:05 -0700 Subject: [PATCH 2/2] test: cover residual NotNaN with NaN values --- tests/expressions/test_residual_evaluator.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/expressions/test_residual_evaluator.py b/tests/expressions/test_residual_evaluator.py index 29dbfcea8d..fbd6a993be 100644 --- a/tests/expressions/test_residual_evaluator.py +++ b/tests/expressions/test_residual_evaluator.py @@ -213,6 +213,9 @@ def test_is_not_nan() -> None: residual = res_eval.residual_for(Record(None)) assert residual == AlwaysTrue() + residual = res_eval.residual_for(Record(float("nan"))) + assert residual == AlwaysFalse() + residual = res_eval.residual_for(Record(2)) assert residual == AlwaysTrue() @@ -225,6 +228,9 @@ def test_is_not_nan() -> None: residual = res_eval.residual_for(Record(None)) assert residual == AlwaysTrue() + residual = res_eval.residual_for(Record(float("nan"))) + assert residual == AlwaysFalse() + residual = res_eval.residual_for(Record(2)) assert residual == AlwaysTrue()