Skip to content

expressions

AlwaysFalse

Bases: BooleanExpression, Singleton, IcebergRootModel[bool]

FALSE expression.

Source code in pyiceberg/expressions/__init__.py
class AlwaysFalse(BooleanExpression, Singleton, IcebergRootModel[bool]):
    """FALSE expression."""

    root: bool = False

    def __invert__(self) -> AlwaysTrue:
        """Transform the Expression into its negated version."""
        return AlwaysTrue()

    def __str__(self) -> str:
        """Return the string representation of the AlwaysFalse class."""
        return "AlwaysFalse()"

    def __repr__(self) -> str:
        """Return the string representation of the AlwaysFalse class."""
        return "AlwaysFalse()"

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> AlwaysTrue:
    """Transform the Expression into its negated version."""
    return AlwaysTrue()

__repr__()

Return the string representation of the AlwaysFalse class.

Source code in pyiceberg/expressions/__init__.py
def __repr__(self) -> str:
    """Return the string representation of the AlwaysFalse class."""
    return "AlwaysFalse()"

__str__()

Return the string representation of the AlwaysFalse class.

Source code in pyiceberg/expressions/__init__.py
def __str__(self) -> str:
    """Return the string representation of the AlwaysFalse class."""
    return "AlwaysFalse()"

AlwaysTrue

Bases: BooleanExpression, Singleton, IcebergRootModel[bool]

TRUE expression.

Source code in pyiceberg/expressions/__init__.py
class AlwaysTrue(BooleanExpression, Singleton, IcebergRootModel[bool]):
    """TRUE expression."""

    root: bool = True

    def __invert__(self) -> AlwaysFalse:
        """Transform the Expression into its negated version."""
        return AlwaysFalse()

    def __str__(self) -> str:
        """Return the string representation of the AlwaysTrue class."""
        return "AlwaysTrue()"

    def __repr__(self) -> str:
        """Return the string representation of the AlwaysTrue class."""
        return "AlwaysTrue()"

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> AlwaysFalse:
    """Transform the Expression into its negated version."""
    return AlwaysFalse()

__repr__()

Return the string representation of the AlwaysTrue class.

Source code in pyiceberg/expressions/__init__.py
def __repr__(self) -> str:
    """Return the string representation of the AlwaysTrue class."""
    return "AlwaysTrue()"

__str__()

Return the string representation of the AlwaysTrue class.

Source code in pyiceberg/expressions/__init__.py
def __str__(self) -> str:
    """Return the string representation of the AlwaysTrue class."""
    return "AlwaysTrue()"

And

Bases: BooleanExpression

AND operation expression - logical conjunction.

Source code in pyiceberg/expressions/__init__.py
class And(BooleanExpression):
    """AND operation expression - logical conjunction."""

    model_config = ConfigDict(arbitrary_types_allowed=True)

    type: TypingLiteral["and"] = Field(default="and", alias="type")
    left: SerializableBooleanExpression = Field()
    right: SerializableBooleanExpression = Field()

    def __init__(self, left: BooleanExpression, right: BooleanExpression, *rest: BooleanExpression, **_: Any) -> None:
        if isinstance(self, And) and not hasattr(self, "left") and not hasattr(self, "right"):
            super().__init__(left=left, right=right)

    def __new__(cls, left: BooleanExpression, right: BooleanExpression, *rest: BooleanExpression, **_: Any) -> BooleanExpression:
        if rest:
            return _build_balanced_tree(And, (left, right, *rest))
        if left is AlwaysFalse() or right is AlwaysFalse():
            return AlwaysFalse()
        elif left is AlwaysTrue():
            return right
        elif right is AlwaysTrue():
            return left
        else:
            return super().__new__(cls)

    def __eq__(self, other: Any) -> bool:
        """Return the equality of two instances of the And class."""
        return self.left == other.left and self.right == other.right if isinstance(other, And) else False

    def __str__(self) -> str:
        """Return the string representation of the And class."""
        return f"And(left={str(self.left)}, right={str(self.right)})"

    def __repr__(self) -> str:
        """Return the string representation of the And class."""
        return f"And(left={repr(self.left)}, right={repr(self.right)})"

    def __invert__(self) -> BooleanExpression:
        """Transform the Expression into its negated version."""
        # De Morgan's law: not (A and B) = (not A) or (not B)
        return Or(~self.left, ~self.right)

    def __getnewargs__(self) -> tuple[BooleanExpression, BooleanExpression]:
        """Pickle the And class."""
        return (self.left, self.right)

__eq__(other)

Return the equality of two instances of the And class.

Source code in pyiceberg/expressions/__init__.py
def __eq__(self, other: Any) -> bool:
    """Return the equality of two instances of the And class."""
    return self.left == other.left and self.right == other.right if isinstance(other, And) else False

__getnewargs__()

Pickle the And class.

Source code in pyiceberg/expressions/__init__.py
def __getnewargs__(self) -> tuple[BooleanExpression, BooleanExpression]:
    """Pickle the And class."""
    return (self.left, self.right)

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> BooleanExpression:
    """Transform the Expression into its negated version."""
    # De Morgan's law: not (A and B) = (not A) or (not B)
    return Or(~self.left, ~self.right)

__repr__()

Return the string representation of the And class.

Source code in pyiceberg/expressions/__init__.py
def __repr__(self) -> str:
    """Return the string representation of the And class."""
    return f"And(left={repr(self.left)}, right={repr(self.right)})"

__str__()

Return the string representation of the And class.

Source code in pyiceberg/expressions/__init__.py
def __str__(self) -> str:
    """Return the string representation of the And class."""
    return f"And(left={str(self.left)}, right={str(self.right)})"

BooleanExpression

Bases: IcebergBaseModel, ABC

An expression that evaluates to a boolean.

Source code in pyiceberg/expressions/__init__.py
class BooleanExpression(IcebergBaseModel, ABC):
    """An expression that evaluates to a boolean."""

    @abstractmethod
    def __invert__(self) -> BooleanExpression:
        """Transform the Expression into its negated version."""

    def __and__(self, other: BooleanExpression) -> BooleanExpression:
        """Perform and operation on another expression."""
        if not isinstance(other, BooleanExpression):
            raise ValueError(f"Expected BooleanExpression, got: {other}")

        return And(self, other)

    def __or__(self, other: BooleanExpression) -> BooleanExpression:
        """Perform or operation on another expression."""
        if not isinstance(other, BooleanExpression):
            raise ValueError(f"Expected BooleanExpression, got: {other}")

        return Or(self, other)

    @model_validator(mode="wrap")
    @classmethod
    def handle_primitive_type(cls, v: Any, handler: ValidatorFunctionWrapHandler) -> BooleanExpression:
        """Apply custom deserialization logic before validation."""
        # Already a BooleanExpression? return as-is so we keep the concrete subclass.
        if isinstance(v, BooleanExpression):
            return v

        # Handle different input formats
        if isinstance(v, bool):
            return AlwaysTrue() if v is True else AlwaysFalse()

        if isinstance(v, dict) and (field_type := v.get("type")):
            # Unary
            if field_type == "is-null":
                return IsNull(**v)
            elif field_type == "not-null":
                return NotNull(**v)
            elif field_type == "is-nan":
                return IsNaN(**v)
            elif field_type == "not-nan":
                return NotNaN(**v)

            # Literal
            elif field_type == "lt":
                return LessThan(**v)
            elif field_type == "lt-eq":
                return LessThanOrEqual(**v)
            elif field_type == "gt":
                return GreaterThan(**v)
            elif field_type == "gt-eq":
                return GreaterThanOrEqual(**v)
            elif field_type == "eq":
                return EqualTo(**v)
            elif field_type == "not-eq":
                return NotEqualTo(**v)
            elif field_type == "starts-with":
                return StartsWith(**v)
            elif field_type == "not-starts-with":
                return NotStartsWith(**v)

            # Set
            elif field_type == "in":
                return In(**v)
            elif field_type == "not-in":
                return NotIn(**v)

            # Other
            elif field_type == "and":
                return And(**v)
            elif field_type == "or":
                return Or(**v)
            elif field_type == "not":
                return Not(**v)

        return handler(v)

__and__(other)

Perform and operation on another expression.

Source code in pyiceberg/expressions/__init__.py
def __and__(self, other: BooleanExpression) -> BooleanExpression:
    """Perform and operation on another expression."""
    if not isinstance(other, BooleanExpression):
        raise ValueError(f"Expected BooleanExpression, got: {other}")

    return And(self, other)

__invert__() abstractmethod

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
@abstractmethod
def __invert__(self) -> BooleanExpression:
    """Transform the Expression into its negated version."""

__or__(other)

Perform or operation on another expression.

Source code in pyiceberg/expressions/__init__.py
def __or__(self, other: BooleanExpression) -> BooleanExpression:
    """Perform or operation on another expression."""
    if not isinstance(other, BooleanExpression):
        raise ValueError(f"Expected BooleanExpression, got: {other}")

    return Or(self, other)

handle_primitive_type(v, handler) classmethod

Apply custom deserialization logic before validation.

Source code in pyiceberg/expressions/__init__.py
@model_validator(mode="wrap")
@classmethod
def handle_primitive_type(cls, v: Any, handler: ValidatorFunctionWrapHandler) -> BooleanExpression:
    """Apply custom deserialization logic before validation."""
    # Already a BooleanExpression? return as-is so we keep the concrete subclass.
    if isinstance(v, BooleanExpression):
        return v

    # Handle different input formats
    if isinstance(v, bool):
        return AlwaysTrue() if v is True else AlwaysFalse()

    if isinstance(v, dict) and (field_type := v.get("type")):
        # Unary
        if field_type == "is-null":
            return IsNull(**v)
        elif field_type == "not-null":
            return NotNull(**v)
        elif field_type == "is-nan":
            return IsNaN(**v)
        elif field_type == "not-nan":
            return NotNaN(**v)

        # Literal
        elif field_type == "lt":
            return LessThan(**v)
        elif field_type == "lt-eq":
            return LessThanOrEqual(**v)
        elif field_type == "gt":
            return GreaterThan(**v)
        elif field_type == "gt-eq":
            return GreaterThanOrEqual(**v)
        elif field_type == "eq":
            return EqualTo(**v)
        elif field_type == "not-eq":
            return NotEqualTo(**v)
        elif field_type == "starts-with":
            return StartsWith(**v)
        elif field_type == "not-starts-with":
            return NotStartsWith(**v)

        # Set
        elif field_type == "in":
            return In(**v)
        elif field_type == "not-in":
            return NotIn(**v)

        # Other
        elif field_type == "and":
            return And(**v)
        elif field_type == "or":
            return Or(**v)
        elif field_type == "not":
            return Not(**v)

    return handler(v)

Bound

Represents a bound value expression.

Source code in pyiceberg/expressions/__init__.py
class Bound:
    """Represents a bound value expression."""

BoundEqualTo

Bases: BoundLiteralPredicate

Source code in pyiceberg/expressions/__init__.py
class BoundEqualTo(BoundLiteralPredicate):
    def __invert__(self) -> BoundNotEqualTo:
        """Transform the Expression into its negated version."""
        return BoundNotEqualTo(self.term, self.literal)

    @property
    def as_unbound(self) -> type[EqualTo]:
        return EqualTo

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> BoundNotEqualTo:
    """Transform the Expression into its negated version."""
    return BoundNotEqualTo(self.term, self.literal)

BoundGreaterThan

Bases: BoundLiteralPredicate

Source code in pyiceberg/expressions/__init__.py
class BoundGreaterThan(BoundLiteralPredicate):
    def __invert__(self) -> BoundLessThanOrEqual:
        """Transform the Expression into its negated version."""
        return BoundLessThanOrEqual(self.term, self.literal)

    @property
    def as_unbound(self) -> type[GreaterThan]:
        return GreaterThan

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> BoundLessThanOrEqual:
    """Transform the Expression into its negated version."""
    return BoundLessThanOrEqual(self.term, self.literal)

BoundGreaterThanOrEqual

Bases: BoundLiteralPredicate

Source code in pyiceberg/expressions/__init__.py
class BoundGreaterThanOrEqual(BoundLiteralPredicate):
    def __invert__(self) -> BoundLessThan:
        """Transform the Expression into its negated version."""
        return BoundLessThan(self.term, self.literal)

    @property
    def as_unbound(self) -> type[GreaterThanOrEqual]:
        return GreaterThanOrEqual

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> BoundLessThan:
    """Transform the Expression into its negated version."""
    return BoundLessThan(self.term, self.literal)

BoundIn

Bases: BoundSetPredicate

Source code in pyiceberg/expressions/__init__.py
class BoundIn(BoundSetPredicate):
    def __new__(cls, term: BoundTerm, literals: set[LiteralValue]) -> BooleanExpression:  # pylint: disable=W0221
        count = len(literals)
        if count == 0:
            return AlwaysFalse()
        elif count == 1:
            return BoundEqualTo(term, next(iter(literals)))
        else:
            return super().__new__(cls)

    def __invert__(self) -> BoundNotIn:
        """Transform the Expression into its negated version."""
        return BoundNotIn(self.term, self.literals)

    def __eq__(self, other: Any) -> bool:
        """Return the equality of two instances of the BoundIn class."""
        return self.term == other.term and self.literals == other.literals if isinstance(other, self.__class__) else False

    @property
    def as_unbound(self) -> type[In]:
        return In

__eq__(other)

Return the equality of two instances of the BoundIn class.

Source code in pyiceberg/expressions/__init__.py
def __eq__(self, other: Any) -> bool:
    """Return the equality of two instances of the BoundIn class."""
    return self.term == other.term and self.literals == other.literals if isinstance(other, self.__class__) else False

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> BoundNotIn:
    """Transform the Expression into its negated version."""
    return BoundNotIn(self.term, self.literals)

BoundIsNaN

Bases: BoundUnaryPredicate

Source code in pyiceberg/expressions/__init__.py
class BoundIsNaN(BoundUnaryPredicate):
    def __new__(cls, term: BoundTerm) -> BooleanExpression:  # pylint: disable=W0221
        bound_type = term.ref().field.field_type
        if isinstance(bound_type, (FloatType, DoubleType)):
            return super().__new__(cls)
        return AlwaysFalse()

    def __invert__(self) -> BoundNotNaN:
        """Transform the Expression into its negated version."""
        return BoundNotNaN(self.term)

    @property
    def as_unbound(self) -> type[IsNaN]:
        return IsNaN

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> BoundNotNaN:
    """Transform the Expression into its negated version."""
    return BoundNotNaN(self.term)

BoundIsNull

Bases: BoundUnaryPredicate

Source code in pyiceberg/expressions/__init__.py
class BoundIsNull(BoundUnaryPredicate):
    def __new__(cls, term: BoundTerm) -> BooleanExpression:  # pylint: disable=W0221
        if term.ref().field.required:
            return AlwaysFalse()
        return super().__new__(cls)

    def __invert__(self) -> BoundNotNull:
        """Transform the Expression into its negated version."""
        return BoundNotNull(self.term)

    @property
    def as_unbound(self) -> type[IsNull]:
        return IsNull

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> BoundNotNull:
    """Transform the Expression into its negated version."""
    return BoundNotNull(self.term)

BoundLessThan

Bases: BoundLiteralPredicate

Source code in pyiceberg/expressions/__init__.py
class BoundLessThan(BoundLiteralPredicate):
    def __invert__(self) -> BoundGreaterThanOrEqual:
        """Transform the Expression into its negated version."""
        return BoundGreaterThanOrEqual(self.term, self.literal)

    @property
    def as_unbound(self) -> type[LessThan]:
        return LessThan

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> BoundGreaterThanOrEqual:
    """Transform the Expression into its negated version."""
    return BoundGreaterThanOrEqual(self.term, self.literal)

BoundLessThanOrEqual

Bases: BoundLiteralPredicate

Source code in pyiceberg/expressions/__init__.py
class BoundLessThanOrEqual(BoundLiteralPredicate):
    def __invert__(self) -> BoundGreaterThan:
        """Transform the Expression into its negated version."""
        return BoundGreaterThan(self.term, self.literal)

    @property
    def as_unbound(self) -> type[LessThanOrEqual]:
        return LessThanOrEqual

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> BoundGreaterThan:
    """Transform the Expression into its negated version."""
    return BoundGreaterThan(self.term, self.literal)

BoundLiteralPredicate

Bases: BoundPredicate, ABC

Source code in pyiceberg/expressions/__init__.py
class BoundLiteralPredicate(BoundPredicate, ABC):
    literal: LiteralValue

    def __init__(self, term: BoundTerm, literal: LiteralValue):  # pylint: disable=W0621
        super().__init__(term=term, literal=literal)

    def __eq__(self, other: Any) -> bool:
        """Return the equality of two instances of the BoundLiteralPredicate class."""
        if isinstance(other, self.__class__):
            return self.term == other.term and self.literal == other.literal
        return False

    def __str__(self) -> str:
        """Return the string representation of the BoundLiteralPredicate class."""
        return f"{self.__class__.__name__}(term={str(self.term)}, literal={repr(self.literal)})"

    def __repr__(self) -> str:
        """Return the string representation of the BoundLiteralPredicate class."""
        return f"{str(self.__class__.__name__)}(term={repr(self.term)}, literal={repr(self.literal)})"

    @property
    @abstractmethod
    def as_unbound(self) -> type[LiteralPredicate]: ...

__eq__(other)

Return the equality of two instances of the BoundLiteralPredicate class.

Source code in pyiceberg/expressions/__init__.py
def __eq__(self, other: Any) -> bool:
    """Return the equality of two instances of the BoundLiteralPredicate class."""
    if isinstance(other, self.__class__):
        return self.term == other.term and self.literal == other.literal
    return False

__repr__()

Return the string representation of the BoundLiteralPredicate class.

Source code in pyiceberg/expressions/__init__.py
def __repr__(self) -> str:
    """Return the string representation of the BoundLiteralPredicate class."""
    return f"{str(self.__class__.__name__)}(term={repr(self.term)}, literal={repr(self.literal)})"

__str__()

Return the string representation of the BoundLiteralPredicate class.

Source code in pyiceberg/expressions/__init__.py
def __str__(self) -> str:
    """Return the string representation of the BoundLiteralPredicate class."""
    return f"{self.__class__.__name__}(term={str(self.term)}, literal={repr(self.literal)})"

BoundNotEqualTo

Bases: BoundLiteralPredicate

Source code in pyiceberg/expressions/__init__.py
class BoundNotEqualTo(BoundLiteralPredicate):
    def __invert__(self) -> BoundEqualTo:
        """Transform the Expression into its negated version."""
        return BoundEqualTo(self.term, self.literal)

    @property
    def as_unbound(self) -> type[NotEqualTo]:
        return NotEqualTo

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> BoundEqualTo:
    """Transform the Expression into its negated version."""
    return BoundEqualTo(self.term, self.literal)

BoundNotIn

Bases: BoundSetPredicate

Source code in pyiceberg/expressions/__init__.py
class BoundNotIn(BoundSetPredicate):
    def __new__(  # pylint: disable=W0221
        cls,
        term: BoundTerm,
        literals: set[LiteralValue],
    ) -> BooleanExpression:
        count = len(literals)
        if count == 0:
            return AlwaysTrue()
        elif count == 1:
            return BoundNotEqualTo(term, next(iter(literals)))
        else:
            return super().__new__(cls)

    def __invert__(self) -> BoundIn:
        """Transform the Expression into its negated version."""
        return BoundIn(self.term, self.literals)

    @property
    def as_unbound(self) -> type[NotIn]:
        return NotIn

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> BoundIn:
    """Transform the Expression into its negated version."""
    return BoundIn(self.term, self.literals)

BoundNotNaN

Bases: BoundUnaryPredicate

Source code in pyiceberg/expressions/__init__.py
class BoundNotNaN(BoundUnaryPredicate):
    def __new__(cls, term: BoundTerm) -> BooleanExpression:  # pylint: disable=W0221
        bound_type = term.ref().field.field_type
        if isinstance(bound_type, (FloatType, DoubleType)):
            return super().__new__(cls)
        return AlwaysTrue()

    def __invert__(self) -> BoundIsNaN:
        """Transform the Expression into its negated version."""
        return BoundIsNaN(self.term)

    @property
    def as_unbound(self) -> type[NotNaN]:
        return NotNaN

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> BoundIsNaN:
    """Transform the Expression into its negated version."""
    return BoundIsNaN(self.term)

BoundNotNull

Bases: BoundUnaryPredicate

Source code in pyiceberg/expressions/__init__.py
class BoundNotNull(BoundUnaryPredicate):
    def __new__(cls, term: BoundTerm) -> BooleanExpression:  # pylint: disable=W0221
        if term.ref().field.required:
            return AlwaysTrue()
        return super().__new__(cls)

    def __invert__(self) -> BoundIsNull:
        """Transform the Expression into its negated version."""
        return BoundIsNull(self.term)

    @property
    def as_unbound(self) -> type[NotNull]:
        return NotNull

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> BoundIsNull:
    """Transform the Expression into its negated version."""
    return BoundIsNull(self.term)

BoundNotStartsWith

Bases: BoundLiteralPredicate

Source code in pyiceberg/expressions/__init__.py
class BoundNotStartsWith(BoundLiteralPredicate):
    def __invert__(self) -> BoundStartsWith:
        """Transform the Expression into its negated version."""
        return BoundStartsWith(self.term, self.literal)

    @property
    def as_unbound(self) -> type[NotStartsWith]:
        return NotStartsWith

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> BoundStartsWith:
    """Transform the Expression into its negated version."""
    return BoundStartsWith(self.term, self.literal)

BoundPredicate

Bases: Bound, BooleanExpression, ABC

Source code in pyiceberg/expressions/__init__.py
class BoundPredicate(Bound, BooleanExpression, ABC):
    model_config = ConfigDict(arbitrary_types_allowed=True)

    term: BoundTerm

    def __init__(self, term: BoundTerm, **kwargs: Any) -> None:
        super().__init__(term=term, **kwargs)

    def __eq__(self, other: Any) -> bool:
        """Return the equality of two instances of the BoundPredicate class."""
        if isinstance(other, self.__class__):
            return self.term == other.term
        return False

    def __str__(self) -> str:
        """Return the string representation of the BoundPredicate class."""
        return f"{self.__class__.__name__}(term={str(self.term)})"

    @property
    @abstractmethod
    def as_unbound(self) -> type[UnboundPredicate]: ...

__eq__(other)

Return the equality of two instances of the BoundPredicate class.

Source code in pyiceberg/expressions/__init__.py
def __eq__(self, other: Any) -> bool:
    """Return the equality of two instances of the BoundPredicate class."""
    if isinstance(other, self.__class__):
        return self.term == other.term
    return False

__str__()

Return the string representation of the BoundPredicate class.

Source code in pyiceberg/expressions/__init__.py
def __str__(self) -> str:
    """Return the string representation of the BoundPredicate class."""
    return f"{self.__class__.__name__}(term={str(self.term)})"

BoundReference

Bases: BoundTerm

A reference bound to a field in a schema.

Parameters:

Name Type Description Default
field NestedField

A referenced field in an Iceberg schema.

required
accessor Accessor

An Accessor object to access the value at the field's position.

required
Source code in pyiceberg/expressions/__init__.py
class BoundReference(BoundTerm):
    """A reference bound to a field in a schema.

    Args:
        field (NestedField): A referenced field in an Iceberg schema.
        accessor (Accessor): An Accessor object to access the value at the field's position.
    """

    field: NestedField
    accessor: Accessor

    def __init__(self, field: NestedField, accessor: Accessor):
        self.field = field
        self.accessor = accessor

    def eval(self, struct: StructProtocol) -> Any:
        """Return the value at the referenced field's position in an object that abides by the StructProtocol.

        Args:
            struct (StructProtocol): A row object that abides by the StructProtocol and returns values given a position.
        Returns:
            Any: The value at the referenced field's position in `struct`.
        """
        return self.accessor.get(struct)

    def __eq__(self, other: Any) -> bool:
        """Return the equality of two instances of the BoundReference class."""
        return self.field == other.field if isinstance(other, BoundReference) else False

    def __repr__(self) -> str:
        """Return the string representation of the BoundReference class."""
        return f"BoundReference(field={repr(self.field)}, accessor={repr(self.accessor)})"

    def ref(self) -> BoundReference:
        return self

    def __hash__(self) -> int:
        """Return hash value of the BoundReference class."""
        return hash(str(self))

__eq__(other)

Return the equality of two instances of the BoundReference class.

Source code in pyiceberg/expressions/__init__.py
def __eq__(self, other: Any) -> bool:
    """Return the equality of two instances of the BoundReference class."""
    return self.field == other.field if isinstance(other, BoundReference) else False

__hash__()

Return hash value of the BoundReference class.

Source code in pyiceberg/expressions/__init__.py
def __hash__(self) -> int:
    """Return hash value of the BoundReference class."""
    return hash(str(self))

__repr__()

Return the string representation of the BoundReference class.

Source code in pyiceberg/expressions/__init__.py
def __repr__(self) -> str:
    """Return the string representation of the BoundReference class."""
    return f"BoundReference(field={repr(self.field)}, accessor={repr(self.accessor)})"

eval(struct)

Return the value at the referenced field's position in an object that abides by the StructProtocol.

Parameters:

Name Type Description Default
struct StructProtocol

A row object that abides by the StructProtocol and returns values given a position.

required

Returns: Any: The value at the referenced field's position in struct.

Source code in pyiceberg/expressions/__init__.py
def eval(self, struct: StructProtocol) -> Any:
    """Return the value at the referenced field's position in an object that abides by the StructProtocol.

    Args:
        struct (StructProtocol): A row object that abides by the StructProtocol and returns values given a position.
    Returns:
        Any: The value at the referenced field's position in `struct`.
    """
    return self.accessor.get(struct)

BoundSetPredicate

Bases: BoundPredicate, ABC

Source code in pyiceberg/expressions/__init__.py
class BoundSetPredicate(BoundPredicate, ABC):
    literals: set[LiteralValue]

    def __init__(self, term: BoundTerm, literals: set[LiteralValue]) -> None:
        literal_set = _to_literal_set(literals)
        super().__init__(term=term, literals=literal_set)

    @cached_property
    def value_set(self) -> set[Any]:
        return {lit.value for lit in self.literals}

    def __str__(self) -> str:
        """Return the string representation of the BoundSetPredicate class."""
        # Sort to make it deterministic
        return f"{str(self.__class__.__name__)}({str(self.term)}, {{{', '.join(sorted([str(literal) for literal in self.literals]))}}})"

    def __repr__(self) -> str:
        """Return the string representation of the BoundSetPredicate class."""
        # Sort to make it deterministic
        return f"{str(self.__class__.__name__)}({repr(self.term)}, {{{', '.join(sorted([repr(literal) for literal in self.literals]))}}})"

    def __eq__(self, other: Any) -> bool:
        """Return the equality of two instances of the BoundSetPredicate class."""
        return self.term == other.term and self.literals == other.literals if isinstance(other, self.__class__) else False

    def __getnewargs__(self) -> tuple[BoundTerm, set[LiteralValue]]:
        """Pickle the BoundSetPredicate class."""
        return (self.term, self.literals)

    @property
    @abstractmethod
    def as_unbound(self) -> type[SetPredicate]: ...

__eq__(other)

Return the equality of two instances of the BoundSetPredicate class.

Source code in pyiceberg/expressions/__init__.py
def __eq__(self, other: Any) -> bool:
    """Return the equality of two instances of the BoundSetPredicate class."""
    return self.term == other.term and self.literals == other.literals if isinstance(other, self.__class__) else False

__getnewargs__()

Pickle the BoundSetPredicate class.

Source code in pyiceberg/expressions/__init__.py
def __getnewargs__(self) -> tuple[BoundTerm, set[LiteralValue]]:
    """Pickle the BoundSetPredicate class."""
    return (self.term, self.literals)

__repr__()

Return the string representation of the BoundSetPredicate class.

Source code in pyiceberg/expressions/__init__.py
def __repr__(self) -> str:
    """Return the string representation of the BoundSetPredicate class."""
    # Sort to make it deterministic
    return f"{str(self.__class__.__name__)}({repr(self.term)}, {{{', '.join(sorted([repr(literal) for literal in self.literals]))}}})"

__str__()

Return the string representation of the BoundSetPredicate class.

Source code in pyiceberg/expressions/__init__.py
def __str__(self) -> str:
    """Return the string representation of the BoundSetPredicate class."""
    # Sort to make it deterministic
    return f"{str(self.__class__.__name__)}({str(self.term)}, {{{', '.join(sorted([str(literal) for literal in self.literals]))}}})"

BoundStartsWith

Bases: BoundLiteralPredicate

Source code in pyiceberg/expressions/__init__.py
class BoundStartsWith(BoundLiteralPredicate):
    def __invert__(self) -> BoundNotStartsWith:
        """Transform the Expression into its negated version."""
        return BoundNotStartsWith(self.term, self.literal)

    @property
    def as_unbound(self) -> type[StartsWith]:
        return StartsWith

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> BoundNotStartsWith:
    """Transform the Expression into its negated version."""
    return BoundNotStartsWith(self.term, self.literal)

BoundTerm

Bases: Term, Bound, ABC

Represents a bound term.

Source code in pyiceberg/expressions/__init__.py
class BoundTerm(Term, Bound, ABC):
    """Represents a bound term."""

    @abstractmethod
    def ref(self) -> BoundReference:
        """Return the bound reference."""

    @abstractmethod
    def eval(self, struct: StructProtocol) -> Any:  # pylint: disable=W0613
        """Return the value at the referenced field's position in an object that abides by the StructProtocol."""

eval(struct) abstractmethod

Return the value at the referenced field's position in an object that abides by the StructProtocol.

Source code in pyiceberg/expressions/__init__.py
@abstractmethod
def eval(self, struct: StructProtocol) -> Any:  # pylint: disable=W0613
    """Return the value at the referenced field's position in an object that abides by the StructProtocol."""

ref() abstractmethod

Return the bound reference.

Source code in pyiceberg/expressions/__init__.py
@abstractmethod
def ref(self) -> BoundReference:
    """Return the bound reference."""

BoundUnaryPredicate

Bases: BoundPredicate, ABC

Source code in pyiceberg/expressions/__init__.py
class BoundUnaryPredicate(BoundPredicate, ABC):
    def __repr__(self) -> str:
        """Return the string representation of the BoundUnaryPredicate class."""
        return f"{str(self.__class__.__name__)}(term={repr(self.term)})"

    @property
    @abstractmethod
    def as_unbound(self) -> type[UnaryPredicate]: ...

    def __getnewargs__(self) -> tuple[BoundTerm]:
        """Pickle the BoundUnaryPredicate class."""
        return (self.term,)

__getnewargs__()

Pickle the BoundUnaryPredicate class.

Source code in pyiceberg/expressions/__init__.py
def __getnewargs__(self) -> tuple[BoundTerm]:
    """Pickle the BoundUnaryPredicate class."""
    return (self.term,)

__repr__()

Return the string representation of the BoundUnaryPredicate class.

Source code in pyiceberg/expressions/__init__.py
def __repr__(self) -> str:
    """Return the string representation of the BoundUnaryPredicate class."""
    return f"{str(self.__class__.__name__)}(term={repr(self.term)})"

EqualTo

Bases: LiteralPredicate

Source code in pyiceberg/expressions/__init__.py
class EqualTo(LiteralPredicate):
    type: TypingLiteral["eq"] = Field(default="eq", alias="type")

    def __invert__(self) -> NotEqualTo:
        """Transform the Expression into its negated version."""
        return NotEqualTo(self.term, self.literal)

    @property
    def as_bound(self) -> type[BoundEqualTo]:  # type: ignore
        return BoundEqualTo

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> NotEqualTo:
    """Transform the Expression into its negated version."""
    return NotEqualTo(self.term, self.literal)

GreaterThan

Bases: LiteralPredicate

Source code in pyiceberg/expressions/__init__.py
class GreaterThan(LiteralPredicate):
    type: TypingLiteral["gt"] = Field(default="gt", alias="type")

    def __invert__(self) -> LessThanOrEqual:
        """Transform the Expression into its negated version."""
        return LessThanOrEqual(self.term, self.literal)

    @property
    def as_bound(self) -> type[BoundGreaterThan]:  # type: ignore
        return BoundGreaterThan

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> LessThanOrEqual:
    """Transform the Expression into its negated version."""
    return LessThanOrEqual(self.term, self.literal)

GreaterThanOrEqual

Bases: LiteralPredicate

Source code in pyiceberg/expressions/__init__.py
class GreaterThanOrEqual(LiteralPredicate):
    type: TypingLiteral["gt-eq"] = Field(default="gt-eq", alias="type")

    def __invert__(self) -> LessThan:
        """Transform the Expression into its negated version."""
        return LessThan(self.term, self.literal)

    @property
    def as_bound(self) -> type[BoundGreaterThanOrEqual]:  # type: ignore
        return BoundGreaterThanOrEqual

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> LessThan:
    """Transform the Expression into its negated version."""
    return LessThan(self.term, self.literal)

In

Bases: SetPredicate

Source code in pyiceberg/expressions/__init__.py
class In(SetPredicate):
    type: TypingLiteral["in"] = Field(default="in", alias="type")

    def __new__(  # pylint: disable=W0221
        cls, term: str | UnboundTerm, literals: Iterable[Any] | Iterable[LiteralValue] | None = None, **kwargs: Any
    ) -> In:
        if literals is None and "values" in kwargs:
            literals = kwargs["values"]

        if literals is None:
            literals_set: set[LiteralValue] = set()
        else:
            literals_set = _to_literal_set(literals)
        count = len(literals_set)
        if count == 0:
            return AlwaysFalse()
        elif count == 1:
            return EqualTo(term, next(iter(literals_set)))
        else:
            return super().__new__(cls)

    def __invert__(self) -> NotIn:
        """Transform the Expression into its negated version."""
        return NotIn(self.term, self.literals)

    @property
    def as_bound(self) -> type[BoundIn]:  # type: ignore
        return BoundIn

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> NotIn:
    """Transform the Expression into its negated version."""
    return NotIn(self.term, self.literals)

IsNaN

Bases: UnaryPredicate

Source code in pyiceberg/expressions/__init__.py
class IsNaN(UnaryPredicate):
    type: TypingLiteral["is-nan"] = Field(default="is-nan")

    def __invert__(self) -> NotNaN:
        """Transform the Expression into its negated version."""
        return NotNaN(self.term)

    @property
    def as_bound(self) -> type[BoundIsNaN]:  # type: ignore
        return BoundIsNaN

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> NotNaN:
    """Transform the Expression into its negated version."""
    return NotNaN(self.term)

IsNull

Bases: UnaryPredicate

Source code in pyiceberg/expressions/__init__.py
class IsNull(UnaryPredicate):
    type: TypingLiteral["is-null"] = Field(default="is-null")

    def __invert__(self) -> NotNull:
        """Transform the Expression into its negated version."""
        return NotNull(self.term)

    @property
    def as_bound(self) -> type[BoundIsNull]:  # type: ignore
        return BoundIsNull

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> NotNull:
    """Transform the Expression into its negated version."""
    return NotNull(self.term)

LessThan

Bases: LiteralPredicate

Source code in pyiceberg/expressions/__init__.py
class LessThan(LiteralPredicate):
    type: TypingLiteral["lt"] = Field(default="lt", alias="type")

    def __invert__(self) -> GreaterThanOrEqual:
        """Transform the Expression into its negated version."""
        return GreaterThanOrEqual(self.term, self.literal)

    @property
    def as_bound(self) -> type[BoundLessThan]:  # type: ignore
        return BoundLessThan

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> GreaterThanOrEqual:
    """Transform the Expression into its negated version."""
    return GreaterThanOrEqual(self.term, self.literal)

LessThanOrEqual

Bases: LiteralPredicate

Source code in pyiceberg/expressions/__init__.py
class LessThanOrEqual(LiteralPredicate):
    type: TypingLiteral["lt-eq"] = Field(default="lt-eq", alias="type")

    def __invert__(self) -> GreaterThan:
        """Transform the Expression into its negated version."""
        return GreaterThan(self.term, self.literal)

    @property
    def as_bound(self) -> type[BoundLessThanOrEqual]:  # type: ignore
        return BoundLessThanOrEqual

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> GreaterThan:
    """Transform the Expression into its negated version."""
    return GreaterThan(self.term, self.literal)

LiteralPredicate

Bases: UnboundPredicate, ABC

Source code in pyiceberg/expressions/__init__.py
class LiteralPredicate(UnboundPredicate, ABC):
    type: TypingLiteral["lt", "lt-eq", "gt", "gt-eq", "eq", "not-eq", "starts-with", "not-starts-with"] = Field(alias="type")
    term: UnboundTerm
    value: LiteralValue = Field()
    model_config = ConfigDict(populate_by_name=True, frozen=True, arbitrary_types_allowed=True)

    def __init__(self, term: str | UnboundTerm, literal: Any | None = None, **kwargs: Any) -> None:
        if literal is None and "value" in kwargs:
            literal = kwargs["value"]

        super().__init__(term=_to_unbound_term(term), value=_to_literal(literal))

    @property
    def literal(self) -> LiteralValue:
        return self.value

    def bind(self, schema: Schema, case_sensitive: bool = True) -> BoundLiteralPredicate:
        bound_term = self.term.bind(schema, case_sensitive)
        lit = self.literal.to(bound_term.ref().field.field_type)

        if isinstance(lit, AboveMax):
            if isinstance(self, (LessThan, LessThanOrEqual, NotEqualTo)):
                return AlwaysTrue()
            elif isinstance(self, (GreaterThan, GreaterThanOrEqual, EqualTo)):
                return AlwaysFalse()
        elif isinstance(lit, BelowMin):
            if isinstance(self, (GreaterThan, GreaterThanOrEqual, NotEqualTo)):
                return AlwaysTrue()
            elif isinstance(self, (LessThan, LessThanOrEqual, EqualTo)):
                return AlwaysFalse()

        return self.as_bound(bound_term, lit)  # type: ignore

    def __eq__(self, other: Any) -> bool:
        """Return the equality of two instances of the LiteralPredicate class."""
        if isinstance(other, self.__class__):
            return self.term == other.term and self.literal == other.literal
        return False

    def __str__(self) -> str:
        """Return the string representation of the LiteralPredicate class."""
        return f"{str(self.__class__.__name__)}(term={repr(self.term)}, literal={repr(self.literal)})"

    def __repr__(self) -> str:
        """Return the string representation of the LiteralPredicate class."""
        return f"{str(self.__class__.__name__)}(term={repr(self.term)}, literal={repr(self.literal)})"

    @property
    @abstractmethod
    def as_bound(self) -> type[BoundLiteralPredicate]: ...  # type: ignore

__eq__(other)

Return the equality of two instances of the LiteralPredicate class.

Source code in pyiceberg/expressions/__init__.py
def __eq__(self, other: Any) -> bool:
    """Return the equality of two instances of the LiteralPredicate class."""
    if isinstance(other, self.__class__):
        return self.term == other.term and self.literal == other.literal
    return False

__repr__()

Return the string representation of the LiteralPredicate class.

Source code in pyiceberg/expressions/__init__.py
def __repr__(self) -> str:
    """Return the string representation of the LiteralPredicate class."""
    return f"{str(self.__class__.__name__)}(term={repr(self.term)}, literal={repr(self.literal)})"

__str__()

Return the string representation of the LiteralPredicate class.

Source code in pyiceberg/expressions/__init__.py
def __str__(self) -> str:
    """Return the string representation of the LiteralPredicate class."""
    return f"{str(self.__class__.__name__)}(term={repr(self.term)}, literal={repr(self.literal)})"

Not

Bases: BooleanExpression

NOT operation expression - logical negation.

Source code in pyiceberg/expressions/__init__.py
class Not(BooleanExpression):
    """NOT operation expression - logical negation."""

    model_config = ConfigDict(arbitrary_types_allowed=True)

    type: TypingLiteral["not"] = Field(default="not")
    child: SerializableBooleanExpression = Field()

    def __init__(self, child: BooleanExpression, **_: Any) -> None:
        super().__init__(child=child)

    def __new__(cls, child: BooleanExpression, **_: Any) -> BooleanExpression:
        if child is AlwaysTrue():
            return AlwaysFalse()
        elif child is AlwaysFalse():
            return AlwaysTrue()
        elif isinstance(child, Not):
            return child.child
        else:
            return super().__new__(cls)

    def __str__(self) -> str:
        """Return the string representation of the Not class."""
        return f"Not(child={self.child})"

    def __repr__(self) -> str:
        """Return the string representation of the Not class."""
        return f"Not(child={repr(self.child)})"

    def __eq__(self, other: Any) -> bool:
        """Return the equality of two instances of the Not class."""
        return self.child == other.child if isinstance(other, Not) else False

    def __invert__(self) -> BooleanExpression:
        """Transform the Expression into its negated version."""
        return self.child

    def __getnewargs__(self) -> tuple[BooleanExpression]:
        """Pickle the Not class."""
        return (self.child,)

__eq__(other)

Return the equality of two instances of the Not class.

Source code in pyiceberg/expressions/__init__.py
def __eq__(self, other: Any) -> bool:
    """Return the equality of two instances of the Not class."""
    return self.child == other.child if isinstance(other, Not) else False

__getnewargs__()

Pickle the Not class.

Source code in pyiceberg/expressions/__init__.py
def __getnewargs__(self) -> tuple[BooleanExpression]:
    """Pickle the Not class."""
    return (self.child,)

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> BooleanExpression:
    """Transform the Expression into its negated version."""
    return self.child

__repr__()

Return the string representation of the Not class.

Source code in pyiceberg/expressions/__init__.py
def __repr__(self) -> str:
    """Return the string representation of the Not class."""
    return f"Not(child={repr(self.child)})"

__str__()

Return the string representation of the Not class.

Source code in pyiceberg/expressions/__init__.py
def __str__(self) -> str:
    """Return the string representation of the Not class."""
    return f"Not(child={self.child})"

NotEqualTo

Bases: LiteralPredicate

Source code in pyiceberg/expressions/__init__.py
class NotEqualTo(LiteralPredicate):
    type: TypingLiteral["not-eq"] = Field(default="not-eq", alias="type")

    def __invert__(self) -> EqualTo:
        """Transform the Expression into its negated version."""
        return EqualTo(self.term, self.literal)

    @property
    def as_bound(self) -> type[BoundNotEqualTo]:  # type: ignore
        return BoundNotEqualTo

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> EqualTo:
    """Transform the Expression into its negated version."""
    return EqualTo(self.term, self.literal)

NotIn

Bases: SetPredicate, ABC

Source code in pyiceberg/expressions/__init__.py
class NotIn(SetPredicate, ABC):
    type: TypingLiteral["not-in"] = Field(default="not-in", alias="type")

    def __new__(  # pylint: disable=W0221
        cls, term: str | UnboundTerm, literals: Iterable[Any] | Iterable[LiteralValue] | None = None, **kwargs: Any
    ) -> NotIn:
        if literals is None and "values" in kwargs:
            literals = kwargs["values"]

        if literals is None:
            literals_set: set[LiteralValue] = set()
        else:
            literals_set = _to_literal_set(literals)
        count = len(literals_set)
        if count == 0:
            return AlwaysTrue()
        elif count == 1:
            return NotEqualTo(term, next(iter(literals_set)))
        else:
            return super().__new__(cls)

    def __invert__(self) -> In:
        """Transform the Expression into its negated version."""
        return In(self.term, self.literals)

    @property
    def as_bound(self) -> type[BoundNotIn]:  # type: ignore
        return BoundNotIn

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> In:
    """Transform the Expression into its negated version."""
    return In(self.term, self.literals)

NotNaN

Bases: UnaryPredicate

Source code in pyiceberg/expressions/__init__.py
class NotNaN(UnaryPredicate):
    type: TypingLiteral["not-nan"] = Field(default="not-nan")

    def __invert__(self) -> IsNaN:
        """Transform the Expression into its negated version."""
        return IsNaN(self.term)

    @property
    def as_bound(self) -> type[BoundNotNaN]:  # type: ignore
        return BoundNotNaN

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> IsNaN:
    """Transform the Expression into its negated version."""
    return IsNaN(self.term)

NotNull

Bases: UnaryPredicate

Source code in pyiceberg/expressions/__init__.py
class NotNull(UnaryPredicate):
    type: TypingLiteral["not-null"] = Field(default="not-null")

    def __invert__(self) -> IsNull:
        """Transform the Expression into its negated version."""
        return IsNull(self.term)

    @property
    def as_bound(self) -> type[BoundNotNull]:  # type: ignore
        return BoundNotNull

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> IsNull:
    """Transform the Expression into its negated version."""
    return IsNull(self.term)

NotStartsWith

Bases: LiteralPredicate

Source code in pyiceberg/expressions/__init__.py
class NotStartsWith(LiteralPredicate):
    type: TypingLiteral["not-starts-with"] = Field(default="not-starts-with", alias="type")

    def __invert__(self) -> StartsWith:
        """Transform the Expression into its negated version."""
        return StartsWith(self.term, self.literal)

    @property
    def as_bound(self) -> type[BoundNotStartsWith]:  # type: ignore
        return BoundNotStartsWith

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> StartsWith:
    """Transform the Expression into its negated version."""
    return StartsWith(self.term, self.literal)

Or

Bases: BooleanExpression

OR operation expression - logical disjunction.

Source code in pyiceberg/expressions/__init__.py
class Or(BooleanExpression):
    """OR operation expression - logical disjunction."""

    model_config = ConfigDict(arbitrary_types_allowed=True)

    type: TypingLiteral["or"] = Field(default="or", alias="type")
    left: SerializableBooleanExpression = Field()
    right: SerializableBooleanExpression = Field()

    def __init__(self, left: BooleanExpression, right: BooleanExpression, *rest: BooleanExpression, **_: Any) -> None:
        if isinstance(self, Or) and not hasattr(self, "left") and not hasattr(self, "right"):
            super().__init__(left=left, right=right)

    def __new__(cls, left: BooleanExpression, right: BooleanExpression, *rest: BooleanExpression, **_: Any) -> BooleanExpression:
        if rest:
            return _build_balanced_tree(Or, (left, right, *rest))
        if left is AlwaysTrue() or right is AlwaysTrue():
            return AlwaysTrue()
        elif left is AlwaysFalse():
            return right
        elif right is AlwaysFalse():
            return left
        else:
            return super().__new__(cls)

    def __str__(self) -> str:
        """Return the string representation of the Or class."""
        return f"{str(self.__class__.__name__)}(left={repr(self.left)}, right={repr(self.right)})"

    def __eq__(self, other: Any) -> bool:
        """Return the equality of two instances of the Or class."""
        return self.left == other.left and self.right == other.right if isinstance(other, Or) else False

    def __repr__(self) -> str:
        """Return the string representation of the Or class."""
        return f"Or(left={repr(self.left)}, right={repr(self.right)})"

    def __invert__(self) -> BooleanExpression:
        """Transform the Expression into its negated version."""
        # De Morgan's law: not (A or B) = (not A) and (not B)
        return And(~self.left, ~self.right)

    def __getnewargs__(self) -> tuple[BooleanExpression, BooleanExpression]:
        """Pickle the Or class."""
        return (self.left, self.right)

__eq__(other)

Return the equality of two instances of the Or class.

Source code in pyiceberg/expressions/__init__.py
def __eq__(self, other: Any) -> bool:
    """Return the equality of two instances of the Or class."""
    return self.left == other.left and self.right == other.right if isinstance(other, Or) else False

__getnewargs__()

Pickle the Or class.

Source code in pyiceberg/expressions/__init__.py
def __getnewargs__(self) -> tuple[BooleanExpression, BooleanExpression]:
    """Pickle the Or class."""
    return (self.left, self.right)

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> BooleanExpression:
    """Transform the Expression into its negated version."""
    # De Morgan's law: not (A or B) = (not A) and (not B)
    return And(~self.left, ~self.right)

__repr__()

Return the string representation of the Or class.

Source code in pyiceberg/expressions/__init__.py
def __repr__(self) -> str:
    """Return the string representation of the Or class."""
    return f"Or(left={repr(self.left)}, right={repr(self.right)})"

__str__()

Return the string representation of the Or class.

Source code in pyiceberg/expressions/__init__.py
def __str__(self) -> str:
    """Return the string representation of the Or class."""
    return f"{str(self.__class__.__name__)}(left={repr(self.left)}, right={repr(self.right)})"

Reference

Bases: UnboundTerm, IcebergRootModel[str]

A reference not yet bound to a field in a schema.

Parameters:

Name Type Description Default
name str

The name of the field.

required
Note

An unbound reference is sometimes referred to as a "named" reference.

Source code in pyiceberg/expressions/__init__.py
class Reference(UnboundTerm, IcebergRootModel[str]):
    """A reference not yet bound to a field in a schema.

    Args:
        name (str): The name of the field.

    Note:
        An unbound reference is sometimes referred to as a "named" reference.
    """

    root: str = Field()

    def __init__(self, name: str) -> None:
        super().__init__(name)

    def __repr__(self) -> str:
        """Return the string representation of the Reference class."""
        return f"Reference(name={repr(self.root)})"

    def __str__(self) -> str:
        """Return the string representation of the Reference class."""
        return f"Reference(name={repr(self.root)})"

    def bind(self, schema: Schema, case_sensitive: bool = True) -> BoundReference:
        """Bind the reference to an Iceberg schema.

        Args:
            schema (Schema): An Iceberg schema.
            case_sensitive (bool): Whether to consider case when binding the reference to the field.

        Raises:
            ValueError: If an empty name is provided.

        Returns:
            BoundReference: A reference bound to the specific field in the Iceberg schema.
        """
        field = schema.find_field(name_or_id=self.name, case_sensitive=case_sensitive)
        accessor = schema.accessor_for_field(field.field_id)
        return self.as_bound(field=field, accessor=accessor)

    @property
    def name(self) -> str:
        return self.root

    @property
    def as_bound(self) -> type[BoundReference]:
        return BoundReference

__repr__()

Return the string representation of the Reference class.

Source code in pyiceberg/expressions/__init__.py
def __repr__(self) -> str:
    """Return the string representation of the Reference class."""
    return f"Reference(name={repr(self.root)})"

__str__()

Return the string representation of the Reference class.

Source code in pyiceberg/expressions/__init__.py
def __str__(self) -> str:
    """Return the string representation of the Reference class."""
    return f"Reference(name={repr(self.root)})"

bind(schema, case_sensitive=True)

Bind the reference to an Iceberg schema.

Parameters:

Name Type Description Default
schema Schema

An Iceberg schema.

required
case_sensitive bool

Whether to consider case when binding the reference to the field.

True

Raises:

Type Description
ValueError

If an empty name is provided.

Returns:

Name Type Description
BoundReference BoundReference

A reference bound to the specific field in the Iceberg schema.

Source code in pyiceberg/expressions/__init__.py
def bind(self, schema: Schema, case_sensitive: bool = True) -> BoundReference:
    """Bind the reference to an Iceberg schema.

    Args:
        schema (Schema): An Iceberg schema.
        case_sensitive (bool): Whether to consider case when binding the reference to the field.

    Raises:
        ValueError: If an empty name is provided.

    Returns:
        BoundReference: A reference bound to the specific field in the Iceberg schema.
    """
    field = schema.find_field(name_or_id=self.name, case_sensitive=case_sensitive)
    accessor = schema.accessor_for_field(field.field_id)
    return self.as_bound(field=field, accessor=accessor)

SetPredicate

Bases: UnboundPredicate, ABC

Source code in pyiceberg/expressions/__init__.py
class SetPredicate(UnboundPredicate, ABC):
    model_config = ConfigDict(arbitrary_types_allowed=True)

    type: TypingLiteral["in", "not-in"] = Field(default="in")
    literals: set[LiteralValue] = Field(alias="values")

    def __init__(
        self, term: str | UnboundTerm, literals: Iterable[Any] | Iterable[LiteralValue] | None = None, **kwargs: Any
    ) -> None:
        if literals is None and "values" in kwargs:
            literals = kwargs["values"]

        if literals is None:
            literal_set: set[LiteralValue] = set()
        else:
            literal_set = _to_literal_set(literals)
        super().__init__(term=_to_unbound_term(term), values=literal_set)

    def bind(self, schema: Schema, case_sensitive: bool = True) -> BoundSetPredicate:
        bound_term = self.term.bind(schema, case_sensitive)
        literal_set = self.literals
        return self.as_bound(bound_term, {lit.to(bound_term.ref().field.field_type) for lit in literal_set})  # type: ignore

    def __str__(self) -> str:
        """Return the string representation of the SetPredicate class."""
        # Sort to make it deterministic
        return f"{str(self.__class__.__name__)}({str(self.term)}, {{{', '.join(sorted([str(literal) for literal in self.literals]))}}})"

    def __repr__(self) -> str:
        """Return the string representation of the SetPredicate class."""
        # Sort to make it deterministic
        return f"{str(self.__class__.__name__)}({repr(self.term)}, {{{', '.join(sorted([repr(literal) for literal in self.literals]))}}})"

    def __eq__(self, other: Any) -> bool:
        """Return the equality of two instances of the SetPredicate class."""
        return self.term == other.term and self.literals == other.literals if isinstance(other, self.__class__) else False

    def __getnewargs__(self) -> tuple[UnboundTerm, set[Any]]:
        """Pickle the SetPredicate class."""
        return (self.term, self.literals)

    @property
    @abstractmethod
    def as_bound(self) -> type[BoundSetPredicate]:  # type: ignore
        return BoundSetPredicate

__eq__(other)

Return the equality of two instances of the SetPredicate class.

Source code in pyiceberg/expressions/__init__.py
def __eq__(self, other: Any) -> bool:
    """Return the equality of two instances of the SetPredicate class."""
    return self.term == other.term and self.literals == other.literals if isinstance(other, self.__class__) else False

__getnewargs__()

Pickle the SetPredicate class.

Source code in pyiceberg/expressions/__init__.py
def __getnewargs__(self) -> tuple[UnboundTerm, set[Any]]:
    """Pickle the SetPredicate class."""
    return (self.term, self.literals)

__repr__()

Return the string representation of the SetPredicate class.

Source code in pyiceberg/expressions/__init__.py
def __repr__(self) -> str:
    """Return the string representation of the SetPredicate class."""
    # Sort to make it deterministic
    return f"{str(self.__class__.__name__)}({repr(self.term)}, {{{', '.join(sorted([repr(literal) for literal in self.literals]))}}})"

__str__()

Return the string representation of the SetPredicate class.

Source code in pyiceberg/expressions/__init__.py
def __str__(self) -> str:
    """Return the string representation of the SetPredicate class."""
    # Sort to make it deterministic
    return f"{str(self.__class__.__name__)}({str(self.term)}, {{{', '.join(sorted([str(literal) for literal in self.literals]))}}})"

StartsWith

Bases: LiteralPredicate

Source code in pyiceberg/expressions/__init__.py
class StartsWith(LiteralPredicate):
    type: TypingLiteral["starts-with"] = Field(default="starts-with", alias="type")

    def __invert__(self) -> NotStartsWith:
        """Transform the Expression into its negated version."""
        return NotStartsWith(self.term, self.literal)

    @property
    def as_bound(self) -> type[BoundStartsWith]:  # type: ignore
        return BoundStartsWith

__invert__()

Transform the Expression into its negated version.

Source code in pyiceberg/expressions/__init__.py
def __invert__(self) -> NotStartsWith:
    """Transform the Expression into its negated version."""
    return NotStartsWith(self.term, self.literal)

Term

A simple expression that evaluates to a value.

Source code in pyiceberg/expressions/__init__.py
class Term:
    """A simple expression that evaluates to a value."""

UnaryPredicate

Bases: UnboundPredicate, ABC

Source code in pyiceberg/expressions/__init__.py
class UnaryPredicate(UnboundPredicate, ABC):
    type: TypingLiteral["is-null", "not-null", "is-nan", "not-nan"] = Field()

    model_config = {"arbitrary_types_allowed": True}

    def __init__(self, term: str | UnboundTerm, **_: Any) -> None:
        unbound = _to_unbound_term(term)
        super().__init__(term=unbound)

    def __str__(self) -> str:
        """Return the string representation of the UnaryPredicate class."""
        # Sort to make it deterministic
        return f"{str(self.__class__.__name__)}(term={str(self.term)})"

    def bind(self, schema: Schema, case_sensitive: bool = True) -> BoundUnaryPredicate:
        bound_term = self.term.bind(schema, case_sensitive)
        bound_type = self.as_bound
        return bound_type(bound_term)  # type: ignore[misc]

    def __repr__(self) -> str:
        """Return the string representation of the UnaryPredicate class."""
        return f"{str(self.__class__.__name__)}(term={repr(self.term)})"

    @property
    @abstractmethod
    def as_bound(self) -> type[BoundUnaryPredicate]: ...  # type: ignore

__repr__()

Return the string representation of the UnaryPredicate class.

Source code in pyiceberg/expressions/__init__.py
def __repr__(self) -> str:
    """Return the string representation of the UnaryPredicate class."""
    return f"{str(self.__class__.__name__)}(term={repr(self.term)})"

__str__()

Return the string representation of the UnaryPredicate class.

Source code in pyiceberg/expressions/__init__.py
def __str__(self) -> str:
    """Return the string representation of the UnaryPredicate class."""
    # Sort to make it deterministic
    return f"{str(self.__class__.__name__)}(term={str(self.term)})"

Unbound

Bases: ABC

Represents an unbound value expression.

Source code in pyiceberg/expressions/__init__.py
class Unbound(ABC):
    """Represents an unbound value expression."""

    @abstractmethod
    def bind(self, schema: Schema, case_sensitive: bool = True) -> Bound | BooleanExpression: ...

    @property
    @abstractmethod
    def as_bound(self) -> type[Bound]: ...

UnboundPredicate

Bases: Unbound, BooleanExpression, ABC

Source code in pyiceberg/expressions/__init__.py
class UnboundPredicate(Unbound, BooleanExpression, ABC):
    model_config = ConfigDict(arbitrary_types_allowed=True)

    term: UnboundTerm

    def __init__(self, term: str | UnboundTerm, **kwargs: Any) -> None:
        super().__init__(term=_to_unbound_term(term), **kwargs)

    def __eq__(self, other: Any) -> bool:
        """Return the equality of two instances of the UnboundPredicate class."""
        return self.term == other.term if isinstance(other, self.__class__) else False

    @abstractmethod
    def bind(self, schema: Schema, case_sensitive: bool = True) -> BooleanExpression: ...

    @property
    @abstractmethod
    def as_bound(self) -> type[BoundPredicate]: ...

__eq__(other)

Return the equality of two instances of the UnboundPredicate class.

Source code in pyiceberg/expressions/__init__.py
def __eq__(self, other: Any) -> bool:
    """Return the equality of two instances of the UnboundPredicate class."""
    return self.term == other.term if isinstance(other, self.__class__) else False

UnboundTerm

Bases: Term, Unbound, ABC

Represents an unbound term.

Source code in pyiceberg/expressions/__init__.py
class UnboundTerm(Term, Unbound, ABC):
    """Represents an unbound term."""

    @abstractmethod
    def bind(self, schema: Schema, case_sensitive: bool = True) -> BoundTerm: ...