Source code for hbutils.expression.native.feature

"""
Operator-oriented expression feature classes.

This module provides a set of expression subclasses that extend
:class:`hbutils.expression.native.base.Expression` with operator overloading.
Each subclass offers a focused set of operators for building expression trees
that can later be evaluated through :func:`hbutils.expression.native.base.efunc`.

The main public components are:

* :class:`CheckExpression` - Equality/inequality operators.
* :class:`ComparableExpression` - Full comparison operators.
* :class:`IndexedExpression` - Item access operator.
* :class:`ObjectExpression` - Attribute access and call operators.
* :class:`LogicalExpression` - Logical operations implemented via bitwise
  operators (``&``, ``|``, ``~``).
* :class:`MathExpression` - Arithmetic operators.
* :class:`BitwiseExpression` - Bitwise operators.

These classes allow building composable expression trees suitable for
domain-specific languages, query builders, or deferred computation.

Example::

    >>> from hbutils.expression.native.feature import MathExpression
    >>> from hbutils.expression.native.base import efunc
    >>> expr = MathExpression()
    >>> calc = efunc((expr + 1) * 2)
    >>> calc(3)
    8

.. note::
   Operators return a new instance of the same class, preserving the expression
   type during chaining.

"""

from typing import Any

from .base import Expression

__all__ = [
    'CheckExpression',
    'ComparableExpression',
    'IndexedExpression',
    'ObjectExpression',
    'LogicalExpression',
    'MathExpression',
    'BitwiseExpression',
]


[docs] class CheckExpression(Expression): """ Expression supporting basic equality checks. This class provides only the ``==`` and ``!=`` operators for building comparison expressions. Example:: >>> from hbutils.expression.native.feature import CheckExpression >>> from hbutils.expression.native.base import efunc >>> expr = CheckExpression() >>> is_five = efunc(expr == 5) >>> is_five(5) True """
[docs] def __eq__(self, other: Any) -> Expression: """ Equality comparison operator. :param other: The value to compare with. :type other: Any :return: A new expression representing the equality comparison. :rtype: Expression Example:: >>> expr = CheckExpression() >>> result = expr == 5 """ return self._func(lambda x, y: x == y, self, other)
[docs] def __ne__(self, other: Any) -> Expression: """ Inequality comparison operator. :param other: The value to compare with. :type other: Any :return: A new expression representing the inequality comparison. :rtype: Expression Example:: >>> expr = CheckExpression() >>> result = expr != 5 """ return self._func(lambda x, y: x != y, self, other)
[docs] class ComparableExpression(CheckExpression): """ Expression supporting full comparison operations. This class extends :class:`CheckExpression` by adding ``<=``, ``<``, ``>=``, and ``>`` comparisons. Example:: >>> from hbutils.expression.native.feature import ComparableExpression >>> from hbutils.expression.native.base import efunc >>> expr = ComparableExpression() >>> is_between = efunc((expr >= 1) & (expr < 3)) >>> is_between(2) True """
[docs] def __le__(self, other: Any) -> Expression: """ Less than or equal to comparison operator. :param other: The value to compare with. :type other: Any :return: A new expression representing the less than or equal comparison. :rtype: Expression Example:: >>> expr = ComparableExpression() >>> result = expr <= 10 """ return self._func(lambda x, y: x <= y, self, other)
[docs] def __lt__(self, other: Any) -> Expression: """ Less than comparison operator. :param other: The value to compare with. :type other: Any :return: A new expression representing the less than comparison. :rtype: Expression Example:: >>> expr = ComparableExpression() >>> result = expr < 10 """ return self._func(lambda x, y: x < y, self, other)
[docs] def __ge__(self, other: Any) -> Expression: """ Greater than or equal to comparison operator. :param other: The value to compare with. :type other: Any :return: A new expression representing the greater than or equal comparison. :rtype: Expression Example:: >>> expr = ComparableExpression() >>> result = expr >= 5 """ return self._func(lambda x, y: x >= y, self, other)
[docs] def __gt__(self, other: Any) -> Expression: """ Greater than comparison operator. :param other: The value to compare with. :type other: Any :return: A new expression representing the greater than comparison. :rtype: Expression Example:: >>> expr = ComparableExpression() >>> result = expr > 5 """ return self._func(lambda x, y: x > y, self, other)
[docs] class IndexedExpression(Expression): """ Expression supporting indexed access. This class enables ``expr[key]`` syntax, which produces a new expression that indexes into the evaluation target. Example:: >>> from hbutils.expression.native.feature import IndexedExpression >>> from hbutils.expression.native.base import efunc >>> expr = IndexedExpression() >>> getter = efunc(expr["key"]) >>> getter({"key": "value"}) 'value' """
[docs] def __getitem__(self, item: Any) -> Expression: """ Item access operator. :param item: The index or key to access. :type item: Any :return: A new expression representing the item access. :rtype: Expression Example:: >>> expr = IndexedExpression() >>> result = expr[0] >>> result = expr['key'] """ return self._func(lambda x, y: x[y], self, item)
[docs] class ObjectExpression(Expression): """ Expression supporting attribute access and callable behavior. This class supports: * Attribute access via ``expr.attr``. * Calling via ``expr(*args, **kwargs)``. Example:: >>> from hbutils.expression.native.feature import ObjectExpression >>> from hbutils.expression.native.base import efunc >>> expr = ObjectExpression() >>> attr_getter = efunc(expr.real) >>> attr_getter(3+4j) 3.0 """
[docs] def __getattr__(self, item: str) -> Expression: """ Attribute access operator. :param item: The attribute name to access. :type item: str :return: A new expression representing the attribute access. :rtype: Expression Example:: >>> expr = ObjectExpression() >>> result = expr.attribute_name """ return self._func(lambda x, y: getattr(x, y), self, item)
[docs] def __call__(self, *args: Any, **kwargs: Any) -> Expression: """ Call operator for making the expression callable. :param args: Positional arguments to pass to the call. :type args: Any :param kwargs: Keyword arguments to pass to the call. :type kwargs: Any :return: A new expression representing the function call. :rtype: Expression Example:: >>> expr = ObjectExpression() >>> result = expr(arg1, arg2, key=value) """ return self._func(lambda s, *args_, **kwargs_: s(*args_, **kwargs_), self, *args, **kwargs)
[docs] class LogicalExpression(Expression): """ Expression supporting logical operations. The logical operations are implemented using bitwise operators: * ``&`` for logical ``and``. * ``|`` for logical ``or``. * ``~`` for logical ``not``. .. note:: Do not combine this class with :class:`BitwiseExpression` in a single expression chain because both reuse bitwise operators. Example:: >>> from hbutils.expression.native.feature import LogicalExpression >>> from hbutils.expression.native.base import efunc >>> expr = LogicalExpression() >>> is_true = efunc(expr & True) >>> is_true(True) True """
[docs] def __and__(self, other: Any) -> Expression: """ Logical AND operator. :param other: The right operand for the AND operation. :type other: Any :return: A new expression representing the logical AND. :rtype: Expression Example:: >>> expr1 = LogicalExpression() >>> expr2 = LogicalExpression() >>> result = expr1 & expr2 """ return self._func(lambda x, y: x and y, self, other)
[docs] def __rand__(self, other: Any) -> Expression: """ Reverse logical AND operator. :param other: The left operand for the AND operation. :type other: Any :return: A new expression representing the logical AND. :rtype: Expression Example:: >>> expr = LogicalExpression() >>> result = True & expr """ return self._func(lambda x, y: x and y, other, self)
[docs] def __or__(self, other: Any) -> Expression: """ Logical OR operator. :param other: The right operand for the OR operation. :type other: Any :return: A new expression representing the logical OR. :rtype: Expression Example:: >>> expr1 = LogicalExpression() >>> expr2 = LogicalExpression() >>> result = expr1 | expr2 """ return self._func(lambda x, y: x or y, self, other)
[docs] def __ror__(self, other: Any) -> Expression: """ Reverse logical OR operator. :param other: The left operand for the OR operation. :type other: Any :return: A new expression representing the logical OR. :rtype: Expression Example:: >>> expr = LogicalExpression() >>> result = False | expr """ return self._func(lambda x, y: x or y, other, self)
[docs] def __invert__(self) -> Expression: """ Logical NOT operator. :return: A new expression representing the logical NOT. :rtype: Expression Example:: >>> expr = LogicalExpression() >>> result = ~expr """ return self._func(lambda x: not x, self)
[docs] class MathExpression(Expression): """ Expression supporting arithmetic operations. This class provides the usual arithmetic operators, including unary operators for positive/negative. Example:: >>> from hbutils.expression.native.feature import MathExpression >>> from hbutils.expression.native.base import efunc >>> expr = MathExpression() >>> f = efunc(-(expr * 2) + 1) >>> f(3) -5 """
[docs] def __add__(self, other: Any) -> Expression: """ Addition operator. :param other: The value to add. :type other: Any :return: A new expression representing the addition. :rtype: Expression Example:: >>> expr = MathExpression() >>> result = expr + 5 """ return self._func(lambda x, y: x + y, self, other)
[docs] def __radd__(self, other: Any) -> Expression: """ Reverse addition operator. :param other: The left operand for addition. :type other: Any :return: A new expression representing the addition. :rtype: Expression Example:: >>> expr = MathExpression() >>> result = 5 + expr """ return self._func(lambda x, y: x + y, other, self)
[docs] def __sub__(self, other: Any) -> Expression: """ Subtraction operator. :param other: The value to subtract. :type other: Any :return: A new expression representing the subtraction. :rtype: Expression Example:: >>> expr = MathExpression() >>> result = expr - 5 """ return self._func(lambda x, y: x - y, self, other)
[docs] def __rsub__(self, other: Any) -> Expression: """ Reverse subtraction operator. :param other: The left operand for subtraction. :type other: Any :return: A new expression representing the subtraction. :rtype: Expression Example:: >>> expr = MathExpression() >>> result = 10 - expr """ return self._func(lambda x, y: x - y, other, self)
[docs] def __mul__(self, other: Any) -> Expression: """ Multiplication operator. :param other: The value to multiply by. :type other: Any :return: A new expression representing the multiplication. :rtype: Expression Example:: >>> expr = MathExpression() >>> result = expr * 3 """ return self._func(lambda x, y: x * y, self, other)
[docs] def __rmul__(self, other: Any) -> Expression: """ Reverse multiplication operator. :param other: The left operand for multiplication. :type other: Any :return: A new expression representing the multiplication. :rtype: Expression Example:: >>> expr = MathExpression() >>> result = 3 * expr """ return self._func(lambda x, y: x * y, other, self)
[docs] def __truediv__(self, other: Any) -> Expression: """ True division operator. :param other: The divisor. :type other: Any :return: A new expression representing the division. :rtype: Expression Example:: >>> expr = MathExpression() >>> result = expr / 2 """ return self._func(lambda x, y: x / y, self, other)
[docs] def __rtruediv__(self, other: Any) -> Expression: """ Reverse true division operator. :param other: The dividend. :type other: Any :return: A new expression representing the division. :rtype: Expression Example:: >>> expr = MathExpression() >>> result = 10 / expr """ return self._func(lambda x, y: x / y, other, self)
[docs] def __floordiv__(self, other: Any) -> Expression: """ Floor division operator. :param other: The divisor. :type other: Any :return: A new expression representing the floor division. :rtype: Expression Example:: >>> expr = MathExpression() >>> result = expr // 2 """ return self._func(lambda x, y: x // y, self, other)
[docs] def __rfloordiv__(self, other: Any) -> Expression: """ Reverse floor division operator. :param other: The dividend. :type other: Any :return: A new expression representing the floor division. :rtype: Expression Example:: >>> expr = MathExpression() >>> result = 10 // expr """ return self._func(lambda x, y: x // y, other, self)
[docs] def __mod__(self, other: Any) -> Expression: """ Modulo operator. :param other: The divisor for modulo operation. :type other: Any :return: A new expression representing the modulo. :rtype: Expression Example:: >>> expr = MathExpression() >>> result = expr % 3 """ return self._func(lambda x, y: x % y, self, other)
[docs] def __rmod__(self, other: Any) -> Expression: """ Reverse modulo operator. :param other: The dividend for modulo operation. :type other: Any :return: A new expression representing the modulo. :rtype: Expression Example:: >>> expr = MathExpression() >>> result = 10 % expr """ return self._func(lambda x, y: x % y, other, self)
[docs] def __pow__(self, power: Any) -> Expression: """ Power operator. :param power: The exponent. :type power: Any :return: A new expression representing the power operation. :rtype: Expression Example:: >>> expr = MathExpression() >>> result = expr ** 2 """ return self._func(lambda x, y: x ** y, self, power)
[docs] def __rpow__(self, other: Any) -> Expression: """ Reverse power operator. :param other: The base for power operation. :type other: Any :return: A new expression representing the power operation. :rtype: Expression Example:: >>> expr = MathExpression() >>> result = 2 ** expr """ return self._func(lambda x, y: x ** y, other, self)
[docs] def __pos__(self) -> Expression: """ Unary positive operator. :return: A new expression representing the positive value. :rtype: Expression Example:: >>> expr = MathExpression() >>> result = +expr """ return self._func(lambda x: +x, self)
[docs] def __neg__(self) -> Expression: """ Unary negative operator. :return: A new expression representing the negative value. :rtype: Expression Example:: >>> expr = MathExpression() >>> result = -expr """ return self._func(lambda x: -x, self)
[docs] class BitwiseExpression(Expression): """ Expression supporting bitwise operations. This class provides operators for bitwise logic and shifts. .. note:: Do not combine this class with :class:`LogicalExpression` in a single expression chain because both reuse bitwise operators. Example:: >>> from hbutils.expression.native.feature import BitwiseExpression >>> from hbutils.expression.native.base import efunc >>> expr = BitwiseExpression() >>> f = efunc(expr | 0b0011) >>> f(0b0100) 7 """
[docs] def __or__(self, other: Any) -> Expression: """ Bitwise OR operator. :param other: The right operand for bitwise OR. :type other: Any :return: A new expression representing the bitwise OR. :rtype: Expression Example:: >>> expr = BitwiseExpression() >>> result = expr | 0b1010 """ return self._func(lambda x, y: x | y, self, other)
[docs] def __ror__(self, other: Any) -> Expression: """ Reverse bitwise OR operator. :param other: The left operand for bitwise OR. :type other: Any :return: A new expression representing the bitwise OR. :rtype: Expression Example:: >>> expr = BitwiseExpression() >>> result = 0b1010 | expr """ return self._func(lambda x, y: x | y, other, self)
[docs] def __xor__(self, other: Any) -> Expression: """ Bitwise XOR operator. :param other: The right operand for bitwise XOR. :type other: Any :return: A new expression representing the bitwise XOR. :rtype: Expression Example:: >>> expr = BitwiseExpression() >>> result = expr ^ 0b1010 """ return self._func(lambda x, y: x ^ y, self, other)
[docs] def __rxor__(self, other: Any) -> Expression: """ Reverse bitwise XOR operator. :param other: The left operand for bitwise XOR. :type other: Any :return: A new expression representing the bitwise XOR. :rtype: Expression Example:: >>> expr = BitwiseExpression() >>> result = 0b1010 ^ expr """ return self._func(lambda x, y: x ^ y, other, self)
[docs] def __and__(self, other: Any) -> Expression: """ Bitwise AND operator. :param other: The right operand for bitwise AND. :type other: Any :return: A new expression representing the bitwise AND. :rtype: Expression Example:: >>> expr = BitwiseExpression() >>> result = expr & 0b1010 """ return self._func(lambda x, y: x & y, self, other)
[docs] def __rand__(self, other: Any) -> Expression: """ Reverse bitwise AND operator. :param other: The left operand for bitwise AND. :type other: Any :return: A new expression representing the bitwise AND. :rtype: Expression Example:: >>> expr = BitwiseExpression() >>> result = 0b1010 & expr """ return self._func(lambda x, y: x & y, other, self)
[docs] def __invert__(self) -> Expression: """ Bitwise NOT operator. :return: A new expression representing the bitwise NOT. :rtype: Expression Example:: >>> expr = BitwiseExpression() >>> result = ~expr """ return self._func(lambda x: ~x, self)
[docs] def __lshift__(self, other: Any) -> Expression: """ Left shift operator. :param other: The number of positions to shift left. :type other: Any :return: A new expression representing the left shift. :rtype: Expression Example:: >>> expr = BitwiseExpression() >>> result = expr << 2 """ return self._func(lambda x, y: x << y, self, other)
[docs] def __rlshift__(self, other: Any) -> Expression: """ Reverse left shift operator. :param other: The value to be shifted left. :type other: Any :return: A new expression representing the left shift. :rtype: Expression Example:: >>> expr = BitwiseExpression() >>> result = 5 << expr """ return self._func(lambda x, y: x << y, other, self)
[docs] def __rshift__(self, other: Any) -> Expression: """ Right shift operator. :param other: The number of positions to shift right. :type other: Any :return: A new expression representing the right shift. :rtype: Expression Example:: >>> expr = BitwiseExpression() >>> result = expr >> 2 """ return self._func(lambda x, y: x >> y, self, other)
[docs] def __rrshift__(self, other: Any) -> Expression: """ Reverse right shift operator. :param other: The value to be shifted right. :type other: Any :return: A new expression representing the right shift. :rtype: Expression Example:: >>> expr = BitwiseExpression() >>> result = 20 >> expr """ return self._func(lambda x, y: x >> y, other, self)