You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iceberg.apache.org by bl...@apache.org on 2022/11/19 22:34:42 UTC

[iceberg] branch master updated: Python: Fix type nits from expression refactor (#6225)

This is an automated email from the ASF dual-hosted git repository.

blue pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iceberg.git


The following commit(s) were added to refs/heads/master by this push:
     new 7b5c64c541 Python: Fix type nits from expression refactor (#6225)
7b5c64c541 is described below

commit 7b5c64c541cfee3151ea35ccc5be9488d9e68f4c
Author: Fokko Driesprong <fo...@apache.org>
AuthorDate: Sat Nov 19 23:34:37 2022 +0100

    Python: Fix type nits from expression refactor (#6225)
---
 python/pyiceberg/expressions/__init__.py     | 44 +++++++++++++++-------------
 python/pyiceberg/expressions/literals.py     |  2 +-
 python/pyiceberg/expressions/visitors.py     | 18 ++++++------
 python/pyiceberg/typedef.py                  |  2 +-
 python/tests/expressions/test_expressions.py |  2 +-
 5 files changed, 36 insertions(+), 32 deletions(-)

diff --git a/python/pyiceberg/expressions/__init__.py b/python/pyiceberg/expressions/__init__.py
index d6ae395c17..37ca9ba3d1 100644
--- a/python/pyiceberg/expressions/__init__.py
+++ b/python/pyiceberg/expressions/__init__.py
@@ -70,6 +70,10 @@ class Bound(ABC):
 class Unbound(ABC):
     """Represents an unbound value expression"""
 
+    @abstractmethod
+    def bind(self, schema: Schema, case_sensitive: bool = True) -> Bound:
+        ...
+
     @property
     @abstractmethod
     def as_bound(self) -> Type[Bound]:
@@ -128,7 +132,7 @@ class UnboundTerm(Term, Unbound, ABC):
 
     @abstractmethod
     def bind(self, schema: Schema, case_sensitive: bool = True) -> BoundTerm:
-        ...  # pragma: no cover
+        ...
 
 
 class Reference(UnboundTerm):
@@ -513,7 +517,7 @@ class In(SetPredicate[L]):
         else:
             return super().__new__(cls)
 
-    def __invert__(self) -> NotIn:
+    def __invert__(self) -> NotIn[L]:
         return NotIn[L](self.term, self.literals)
 
     @property
@@ -532,7 +536,7 @@ class NotIn(SetPredicate[L], ABC):
         else:
             return super().__new__(cls)
 
-    def __invert__(self) -> In:
+    def __invert__(self) -> In[L]:
         return In[L](self.term, self.literals)
 
     def __eq__(self, other: Any) -> bool:
@@ -589,17 +593,17 @@ class BoundLiteralPredicate(BoundPredicate[L], ABC):
 
 class BoundEqualTo(BoundLiteralPredicate[L]):
     def __invert__(self) -> BoundNotEqualTo[L]:
-        return BoundNotEqualTo(self.term, self.literal)
+        return BoundNotEqualTo[L](self.term, self.literal)
 
 
 class BoundNotEqualTo(BoundLiteralPredicate[L]):
     def __invert__(self) -> BoundEqualTo[L]:
-        return BoundEqualTo(self.term, self.literal)
+        return BoundEqualTo[L](self.term, self.literal)
 
 
 class BoundGreaterThanOrEqual(BoundLiteralPredicate[L]):
     def __invert__(self) -> BoundLessThan[L]:
-        return BoundLessThan(self.term, self.literal)
+        return BoundLessThan[L](self.term, self.literal)
 
 
 class BoundGreaterThan(BoundLiteralPredicate[L]):
@@ -609,17 +613,17 @@ class BoundGreaterThan(BoundLiteralPredicate[L]):
 
 class BoundLessThan(BoundLiteralPredicate[L]):
     def __invert__(self) -> BoundGreaterThanOrEqual[L]:
-        return BoundGreaterThanOrEqual(self.term, self.literal)
+        return BoundGreaterThanOrEqual[L](self.term, self.literal)
 
 
 class BoundLessThanOrEqual(BoundLiteralPredicate[L]):
     def __invert__(self) -> BoundGreaterThan[L]:
-        return BoundGreaterThan(self.term, self.literal)
+        return BoundGreaterThan[L](self.term, self.literal)
 
 
 class EqualTo(LiteralPredicate[L]):
     def __invert__(self) -> NotEqualTo:
-        return NotEqualTo(self.term, self.literal)
+        return NotEqualTo[L](self.term, self.literal)
 
     @property
     def as_bound(self) -> Type[BoundEqualTo[L]]:
@@ -627,17 +631,17 @@ class EqualTo(LiteralPredicate[L]):
 
 
 class NotEqualTo(LiteralPredicate[L]):
-    def __invert__(self) -> EqualTo:
-        return EqualTo(self.term, self.literal)
+    def __invert__(self) -> EqualTo[L]:
+        return EqualTo[L](self.term, self.literal)
 
     @property
     def as_bound(self) -> Type[BoundNotEqualTo[L]]:
         return BoundNotEqualTo[L]
 
 
-class LessThan(LiteralPredicate):
-    def __invert__(self) -> GreaterThanOrEqual:
-        return GreaterThanOrEqual(self.term, self.literal)
+class LessThan(LiteralPredicate[L]):
+    def __invert__(self) -> GreaterThanOrEqual[L]:
+        return GreaterThanOrEqual[L](self.term, self.literal)
 
     @property
     def as_bound(self) -> Type[BoundLessThan[L]]:
@@ -645,8 +649,8 @@ class LessThan(LiteralPredicate):
 
 
 class GreaterThanOrEqual(LiteralPredicate[L]):
-    def __invert__(self) -> LessThan:
-        return LessThan(self.term, self.literal)
+    def __invert__(self) -> LessThan[L]:
+        return LessThan[L](self.term, self.literal)
 
     @property
     def as_bound(self) -> Type[BoundGreaterThanOrEqual[L]]:
@@ -654,8 +658,8 @@ class GreaterThanOrEqual(LiteralPredicate[L]):
 
 
 class GreaterThan(LiteralPredicate[L]):
-    def __invert__(self) -> LessThanOrEqual:
-        return LessThanOrEqual(self.term, self.literal)
+    def __invert__(self) -> LessThanOrEqual[L]:
+        return LessThanOrEqual[L](self.term, self.literal)
 
     @property
     def as_bound(self) -> Type[BoundGreaterThan[L]]:
@@ -663,8 +667,8 @@ class GreaterThan(LiteralPredicate[L]):
 
 
 class LessThanOrEqual(LiteralPredicate[L]):
-    def __invert__(self) -> GreaterThan:
-        return GreaterThan(self.term, self.literal)
+    def __invert__(self) -> GreaterThan[L]:
+        return GreaterThan[L](self.term, self.literal)
 
     @property
     def as_bound(self) -> Type[BoundLessThanOrEqual[L]]:
diff --git a/python/pyiceberg/expressions/literals.py b/python/pyiceberg/expressions/literals.py
index ada6fcc8eb..c0ce0188bb 100644
--- a/python/pyiceberg/expressions/literals.py
+++ b/python/pyiceberg/expressions/literals.py
@@ -118,7 +118,7 @@ def literal(value: L) -> Literal[L]:
     if isinstance(value, float):
         return DoubleLiteral(value)
     elif isinstance(value, bool):
-        return BooleanLiteral(value)  # type: ignore
+        return BooleanLiteral(value)
     elif isinstance(value, int):
         return LongLiteral(value)
     elif isinstance(value, str):
diff --git a/python/pyiceberg/expressions/visitors.py b/python/pyiceberg/expressions/visitors.py
index 283e7d2317..f1c0e00288 100644
--- a/python/pyiceberg/expressions/visitors.py
+++ b/python/pyiceberg/expressions/visitors.py
@@ -91,8 +91,8 @@ class BooleanExpressionVisitor(Generic[T], ABC):
         """Visit method for an And boolean expression
 
         Args:
-            left_result (R): The result of visiting the left side of the expression
-            right_result (R): The result of visiting the right side of the expression
+            left_result (T): The result of visiting the left side of the expression
+            right_result (T): The result of visiting the right side of the expression
         """
 
     @abstractmethod
@@ -100,12 +100,12 @@ class BooleanExpressionVisitor(Generic[T], ABC):
         """Visit method for an Or boolean expression
 
         Args:
-            left_result (R): The result of visiting the left side of the expression
-            right_result (R): The result of visiting the right side of the expression
+            left_result (T): The result of visiting the left side of the expression
+            right_result (T): The result of visiting the right side of the expression
         """
 
     @abstractmethod
-    def visit_unbound_predicate(self, predicate: UnboundPredicate) -> T:
+    def visit_unbound_predicate(self, predicate: UnboundPredicate[L]) -> T:
         """Visit method for an unbound predicate in an expression tree
 
         Args:
@@ -231,7 +231,7 @@ class BindVisitor(BooleanExpressionVisitor[BooleanExpression]):
     def visit_or(self, left_result: BooleanExpression, right_result: BooleanExpression) -> BooleanExpression:
         return Or(left=left_result, right=right_result)
 
-    def visit_unbound_predicate(self, predicate: UnboundPredicate) -> BooleanExpression:
+    def visit_unbound_predicate(self, predicate: UnboundPredicate[L]) -> BooleanExpression:
         return predicate.bind(self.schema, case_sensitive=self.case_sensitive)
 
     def visit_bound_predicate(self, predicate: BoundPredicate[L]) -> BooleanExpression:
@@ -307,10 +307,10 @@ class BoundBooleanExpressionVisitor(BooleanExpressionVisitor[T], ABC):
     def visit_or(self, left_result: T, right_result: T) -> T:
         """Visit a bound Or predicate"""
 
-    def visit_unbound_predicate(self, predicate: UnboundPredicate):
+    def visit_unbound_predicate(self, predicate: UnboundPredicate[L]):
         """Visit an unbound predicate
         Args:
-            predicate (UnboundPredicate): An unbound predicate
+            predicate (UnboundPredicate[L]): An unbound predicate
         Raises:
             TypeError: This always raises since an unbound predicate is not expected in a bound boolean expression
         """
@@ -412,7 +412,7 @@ class _RewriteNotVisitor(BooleanExpressionVisitor[BooleanExpression]):
     def visit_or(self, left_result: BooleanExpression, right_result: BooleanExpression) -> BooleanExpression:
         return Or(left=left_result, right=right_result)
 
-    def visit_unbound_predicate(self, predicate: UnboundPredicate) -> BooleanExpression:
+    def visit_unbound_predicate(self, predicate: UnboundPredicate[L]) -> BooleanExpression:
         return predicate
 
     def visit_bound_predicate(self, predicate: BoundPredicate[L]) -> BooleanExpression:
diff --git a/python/pyiceberg/typedef.py b/python/pyiceberg/typedef.py
index b038bfb17c..d676d68fee 100644
--- a/python/pyiceberg/typedef.py
+++ b/python/pyiceberg/typedef.py
@@ -40,4 +40,4 @@ Properties = Dict[str, str]
 RecursiveDict = Dict[str, Union[str, "RecursiveDict"]]
 
 # Represents the literal value
-L = TypeVar("L", str, bool, int, float, bytes, UUID, Decimal)
+L = TypeVar("L", str, bool, int, float, bytes, UUID, Decimal, covariant=True)
diff --git a/python/tests/expressions/test_expressions.py b/python/tests/expressions/test_expressions.py
index 2772ac2c34..d0f910cd3d 100644
--- a/python/tests/expressions/test_expressions.py
+++ b/python/tests/expressions/test_expressions.py
@@ -203,7 +203,7 @@ def test_ref_binding_case_insensitive_failure(table_schema_simple: Schema):
 
 
 def test_in_to_eq():
-    assert In("x", (34.56,)) == EqualTo(Reference("x"), 34.56)
+    assert In("x", (34.56,)) == EqualTo("x", 34.56)
 
 
 def test_empty_bind_in(table_schema_simple: Schema):