diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-03-13 13:37:11 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-03-15 21:38:29 -0400 |
commit | 6acf5d2fca4a988a77481b82662174e8015a6b37 (patch) | |
tree | 73e2868a51b8b7ac46d7b3b7f9562c1d011f6e1b /lib/sqlalchemy/sql/operators.py | |
parent | 35f82173e04b3209e07fcfc0606a7614108d018e (diff) | |
download | sqlalchemy-6acf5d2fca4a988a77481b82662174e8015a6b37.tar.gz |
pep-484 - SQL column operations
note we are taking out the
ColumnOperartors[SQLCoreOperations] thing; not really clear
why that was needed and at the moment it seems I was likely
confused.
Change-Id: I834b75f9b44f91b97e29f2e1a7b1029bd910e0a1
Diffstat (limited to 'lib/sqlalchemy/sql/operators.py')
-rw-r--r-- | lib/sqlalchemy/sql/operators.py | 363 |
1 files changed, 206 insertions, 157 deletions
diff --git a/lib/sqlalchemy/sql/operators.py b/lib/sqlalchemy/sql/operators.py index f08e71bcd..7db1631c8 100644 --- a/lib/sqlalchemy/sql/operators.py +++ b/lib/sqlalchemy/sql/operators.py @@ -12,6 +12,7 @@ from __future__ import annotations +from enum import IntEnum from operator import add as _uncast_add from operator import and_ as _uncast_and_ from operator import contains as _uncast_contains @@ -36,15 +37,17 @@ import typing from typing import Any from typing import Callable from typing import cast +from typing import Dict from typing import Generic from typing import Optional -from typing import overload +from typing import Set from typing import Type from typing import TypeVar from typing import Union from .. import exc from .. import util +from ..util.typing import Literal from ..util.typing import Protocol if typing.TYPE_CHECKING: @@ -52,8 +55,8 @@ if typing.TYPE_CHECKING: from .elements import ColumnElement from .type_api import TypeEngine -_OP_RETURN = TypeVar("_OP_RETURN", bound=Any, covariant=True) _T = TypeVar("_T", bound=Any) +_FN = TypeVar("_FN", bound=Callable[..., Any]) class OperatorType(Protocol): @@ -64,8 +67,12 @@ class OperatorType(Protocol): __name__: str def __call__( - self, left: "Operators[_OP_RETURN]", *other: Any, **kwargs: Any - ) -> "_OP_RETURN": + self, + left: "Operators", + right: Optional[Any] = None, + *other: Any, + **kwargs: Any, + ) -> "Operators": ... @@ -91,7 +98,7 @@ sub = cast(OperatorType, _uncast_sub) truediv = cast(OperatorType, _uncast_truediv) -class Operators(Generic[_OP_RETURN]): +class Operators: """Base of comparison and logical operators. Implements base methods @@ -108,7 +115,7 @@ class Operators(Generic[_OP_RETURN]): __slots__ = () - def __and__(self, other: Any) -> "Operators": + def __and__(self, other: Any) -> Operators: """Implement the ``&`` operator. When used with SQL expressions, results in an @@ -132,7 +139,7 @@ class Operators(Generic[_OP_RETURN]): """ return self.operate(and_, other) - def __or__(self, other: Any) -> "Operators": + def __or__(self, other: Any) -> Operators: """Implement the ``|`` operator. When used with SQL expressions, results in an @@ -156,7 +163,7 @@ class Operators(Generic[_OP_RETURN]): """ return self.operate(or_, other) - def __invert__(self) -> "Operators": + def __invert__(self) -> Operators: """Implement the ``~`` operator. When used with SQL expressions, results in a @@ -175,14 +182,14 @@ class Operators(Generic[_OP_RETURN]): def op( self, - opstring: Any, + opstring: str, precedence: int = 0, is_comparison: bool = False, return_type: Optional[ Union[Type["TypeEngine[Any]"], "TypeEngine[Any]"] ] = None, - python_impl=None, - ) -> Callable[[Any], Any]: + python_impl: Optional[Callable[..., Any]] = None, + ) -> Callable[[Any], Operators]: """Produce a generic operator function. e.g.:: @@ -200,7 +207,7 @@ class Operators(Generic[_OP_RETURN]): is a bitwise AND of the value in ``somecolumn``. - :param operator: a string which will be output as the infix operator + :param opstring: a string which will be output as the infix operator between this element and the expression passed to the generated function. @@ -263,14 +270,17 @@ class Operators(Generic[_OP_RETURN]): python_impl=python_impl, ) - def against(other: Any) -> _OP_RETURN: - return operator(self, other) + def against(other: Any) -> Operators: + return operator(self, other) # type: ignore return against def bool_op( - self, opstring: Any, precedence: int = 0, python_impl=None - ) -> Callable[[Any], Any]: + self, + opstring: str, + precedence: int = 0, + python_impl: Optional[Callable[..., Any]] = None, + ) -> Callable[[Any], Operators]: """Return a custom boolean operator. This method is shorthand for calling @@ -292,7 +302,7 @@ class Operators(Generic[_OP_RETURN]): def operate( self, op: OperatorType, *other: Any, **kwargs: Any - ) -> _OP_RETURN: + ) -> Operators: r"""Operate on an argument. This is the lowest level of operation, raises @@ -322,7 +332,7 @@ class Operators(Generic[_OP_RETURN]): def reverse_operate( self, op: OperatorType, other: Any, **kwargs: Any - ) -> _OP_RETURN: + ) -> Operators: """Reverse operate on an argument. Usage is the same as :meth:`operate`. @@ -379,7 +389,7 @@ class custom_op(OperatorType, Generic[_T]): ] = None, natural_self_precedent: bool = False, eager_grouping: bool = False, - python_impl=None, + python_impl: Optional[Callable[..., Any]] = None, ): self.opstring = opstring self.precedence = precedence @@ -397,25 +407,17 @@ class custom_op(OperatorType, Generic[_T]): def __hash__(self) -> int: return id(self) - @overload def __call__( - self, left: "ColumnElement", right: Any, **kw - ) -> "BinaryExpression[_T]": - ... - - @overload - def __call__( - self, left: "Operators[_OP_RETURN]", right: Any, **kw - ) -> _OP_RETURN: - ... - - def __call__( - self, left: "Operators[_OP_RETURN]", right: Any, **kw - ) -> _OP_RETURN: + self, + left: Operators, + right: Optional[Any] = None, + *other: Any, + **kwargs: Any, + ) -> Operators: if hasattr(left, "__sa_operate__"): - return left.operate(self, right, **kw) + return left.operate(self, right, *other, **kwargs) elif self.python_impl: - return self.python_impl(left, right, **kw) + return self.python_impl(left, right, *other, **kwargs) # type: ignore # noqa E501 else: raise exc.InvalidRequestError( f"Custom operator {self.opstring!r} can't be used with " @@ -424,7 +426,7 @@ class custom_op(OperatorType, Generic[_T]): ) -class ColumnOperators(Operators[_OP_RETURN]): +class ColumnOperators(Operators): """Defines boolean, comparison, and other operators for :class:`_expression.ColumnElement` expressions. @@ -464,22 +466,22 @@ class ColumnOperators(Operators[_OP_RETURN]): __slots__ = () - timetuple = None + timetuple: Literal[None] = None """Hack, allows datetime objects to be compared on the LHS.""" if typing.TYPE_CHECKING: def operate( self, op: OperatorType, *other: Any, **kwargs: Any - ) -> "ColumnOperators": + ) -> ColumnOperators: ... def reverse_operate( self, op: OperatorType, other: Any, **kwargs: Any - ) -> "ColumnOperators": + ) -> ColumnOperators: ... - def __lt__(self, other: Any) -> "ColumnOperators": + def __lt__(self, other: Any) -> ColumnOperators: """Implement the ``<`` operator. In a column context, produces the clause ``a < b``. @@ -487,7 +489,7 @@ class ColumnOperators(Operators[_OP_RETURN]): """ return self.operate(lt, other) - def __le__(self, other: Any) -> "ColumnOperators": + def __le__(self, other: Any) -> ColumnOperators: """Implement the ``<=`` operator. In a column context, produces the clause ``a <= b``. @@ -498,7 +500,7 @@ class ColumnOperators(Operators[_OP_RETURN]): # TODO: not sure why we have this __hash__ = Operators.__hash__ # type: ignore - def __eq__(self, other: Any) -> "ColumnOperators": + def __eq__(self, other: Any) -> ColumnOperators: # type: ignore[override] """Implement the ``==`` operator. In a column context, produces the clause ``a = b``. @@ -507,7 +509,7 @@ class ColumnOperators(Operators[_OP_RETURN]): """ return self.operate(eq, other) - def __ne__(self, other: Any) -> "ColumnOperators": + def __ne__(self, other: Any) -> ColumnOperators: # type: ignore[override] """Implement the ``!=`` operator. In a column context, produces the clause ``a != b``. @@ -516,7 +518,7 @@ class ColumnOperators(Operators[_OP_RETURN]): """ return self.operate(ne, other) - def is_distinct_from(self, other: Any) -> "ColumnOperators": + def is_distinct_from(self, other: Any) -> ColumnOperators: """Implement the ``IS DISTINCT FROM`` operator. Renders "a IS DISTINCT FROM b" on most platforms; @@ -527,7 +529,7 @@ class ColumnOperators(Operators[_OP_RETURN]): """ return self.operate(is_distinct_from, other) - def is_not_distinct_from(self, other: Any) -> "ColumnOperators": + def is_not_distinct_from(self, other: Any) -> ColumnOperators: """Implement the ``IS NOT DISTINCT FROM`` operator. Renders "a IS NOT DISTINCT FROM b" on most platforms; @@ -545,7 +547,7 @@ class ColumnOperators(Operators[_OP_RETURN]): # deprecated 1.4; see #5435 isnot_distinct_from = is_not_distinct_from - def __gt__(self, other: Any) -> "ColumnOperators": + def __gt__(self, other: Any) -> ColumnOperators: """Implement the ``>`` operator. In a column context, produces the clause ``a > b``. @@ -553,7 +555,7 @@ class ColumnOperators(Operators[_OP_RETURN]): """ return self.operate(gt, other) - def __ge__(self, other: Any) -> "ColumnOperators": + def __ge__(self, other: Any) -> ColumnOperators: """Implement the ``>=`` operator. In a column context, produces the clause ``a >= b``. @@ -561,7 +563,7 @@ class ColumnOperators(Operators[_OP_RETURN]): """ return self.operate(ge, other) - def __neg__(self) -> "ColumnOperators": + def __neg__(self) -> ColumnOperators: """Implement the ``-`` operator. In a column context, produces the clause ``-a``. @@ -569,10 +571,10 @@ class ColumnOperators(Operators[_OP_RETURN]): """ return self.operate(neg) - def __contains__(self, other: Any) -> "ColumnOperators": + def __contains__(self, other: Any) -> ColumnOperators: return self.operate(contains, other) - def __getitem__(self, index: Any) -> "ColumnOperators": + def __getitem__(self, index: Any) -> ColumnOperators: """Implement the [] operator. This can be used by some database-specific types @@ -581,7 +583,7 @@ class ColumnOperators(Operators[_OP_RETURN]): """ return self.operate(getitem, index) - def __lshift__(self, other: Any) -> "ColumnOperators": + def __lshift__(self, other: Any) -> ColumnOperators: """implement the << operator. Not used by SQLAlchemy core, this is provided @@ -590,7 +592,7 @@ class ColumnOperators(Operators[_OP_RETURN]): """ return self.operate(lshift, other) - def __rshift__(self, other: Any) -> "ColumnOperators": + def __rshift__(self, other: Any) -> ColumnOperators: """implement the >> operator. Not used by SQLAlchemy core, this is provided @@ -599,7 +601,7 @@ class ColumnOperators(Operators[_OP_RETURN]): """ return self.operate(rshift, other) - def concat(self, other: Any) -> "ColumnOperators": + def concat(self, other: Any) -> ColumnOperators: """Implement the 'concat' operator. In a column context, produces the clause ``a || b``, @@ -608,7 +610,9 @@ class ColumnOperators(Operators[_OP_RETURN]): """ return self.operate(concat_op, other) - def like(self, other: Any, escape=None) -> "ColumnOperators": + def like( + self, other: Any, escape: Optional[str] = None + ) -> ColumnOperators: r"""Implement the ``like`` operator. In a column context, produces the expression:: @@ -633,7 +637,9 @@ class ColumnOperators(Operators[_OP_RETURN]): """ return self.operate(like_op, other, escape=escape) - def ilike(self, other: Any, escape=None) -> "ColumnOperators": + def ilike( + self, other: Any, escape: Optional[str] = None + ) -> ColumnOperators: r"""Implement the ``ilike`` operator, e.g. case insensitive LIKE. In a column context, produces an expression either of the form:: @@ -662,7 +668,7 @@ class ColumnOperators(Operators[_OP_RETURN]): """ return self.operate(ilike_op, other, escape=escape) - def in_(self, other: Any) -> "ColumnOperators": + def in_(self, other: Any) -> ColumnOperators: """Implement the ``in`` operator. In a column context, produces the clause ``column IN <other>``. @@ -751,7 +757,7 @@ class ColumnOperators(Operators[_OP_RETURN]): """ return self.operate(in_op, other) - def not_in(self, other: Any) -> "ColumnOperators": + def not_in(self, other: Any) -> ColumnOperators: """implement the ``NOT IN`` operator. This is equivalent to using negation with @@ -782,7 +788,9 @@ class ColumnOperators(Operators[_OP_RETURN]): # deprecated 1.4; see #5429 notin_ = not_in - def not_like(self, other: Any, escape=None) -> "ColumnOperators": + def not_like( + self, other: Any, escape: Optional[str] = None + ) -> ColumnOperators: """implement the ``NOT LIKE`` operator. This is equivalent to using negation with @@ -802,7 +810,9 @@ class ColumnOperators(Operators[_OP_RETURN]): # deprecated 1.4; see #5435 notlike = not_like - def not_ilike(self, other: Any, escape=None) -> "ColumnOperators": + def not_ilike( + self, other: Any, escape: Optional[str] = None + ) -> ColumnOperators: """implement the ``NOT ILIKE`` operator. This is equivalent to using negation with @@ -822,7 +832,7 @@ class ColumnOperators(Operators[_OP_RETURN]): # deprecated 1.4; see #5435 notilike = not_ilike - def is_(self, other: Any) -> "ColumnOperators": + def is_(self, other: Any) -> ColumnOperators: """Implement the ``IS`` operator. Normally, ``IS`` is generated automatically when comparing to a @@ -835,7 +845,7 @@ class ColumnOperators(Operators[_OP_RETURN]): """ return self.operate(is_, other) - def is_not(self, other: Any) -> "ColumnOperators": + def is_not(self, other: Any) -> ColumnOperators: """Implement the ``IS NOT`` operator. Normally, ``IS NOT`` is generated automatically when comparing to a @@ -856,8 +866,11 @@ class ColumnOperators(Operators[_OP_RETURN]): isnot = is_not def startswith( - self, other: Any, escape=None, autoescape=False - ) -> "ColumnOperators": + self, + other: Any, + escape: Optional[str] = None, + autoescape: bool = False, + ) -> ColumnOperators: r"""Implement the ``startswith`` operator. Produces a LIKE expression that tests against a match for the start @@ -939,8 +952,11 @@ class ColumnOperators(Operators[_OP_RETURN]): ) def endswith( - self, other: Any, escape=None, autoescape=False - ) -> "ColumnOperators": + self, + other: Any, + escape: Optional[str] = None, + autoescape: bool = False, + ) -> ColumnOperators: r"""Implement the 'endswith' operator. Produces a LIKE expression that tests against a match for the end @@ -1021,7 +1037,7 @@ class ColumnOperators(Operators[_OP_RETURN]): endswith_op, other, escape=escape, autoescape=autoescape ) - def contains(self, other: Any, **kw: Any) -> "ColumnOperators": + def contains(self, other: Any, **kw: Any) -> ColumnOperators: r"""Implement the 'contains' operator. Produces a LIKE expression that tests against a match for the middle @@ -1101,7 +1117,7 @@ class ColumnOperators(Operators[_OP_RETURN]): """ return self.operate(contains_op, other, **kw) - def match(self, other: Any, **kwargs) -> "ColumnOperators": + def match(self, other: Any, **kwargs: Any) -> ColumnOperators: """Implements a database-specific 'match' operator. :meth:`_sql.ColumnOperators.match` attempts to resolve to @@ -1125,7 +1141,9 @@ class ColumnOperators(Operators[_OP_RETURN]): """ return self.operate(match_op, other, **kwargs) - def regexp_match(self, pattern, flags=None) -> "ColumnOperators": + def regexp_match( + self, pattern: Any, flags: Optional[str] = None + ) -> ColumnOperators: """Implements a database-specific 'regexp match' operator. E.g.:: @@ -1174,8 +1192,8 @@ class ColumnOperators(Operators[_OP_RETURN]): return self.operate(regexp_match_op, pattern, flags=flags) def regexp_replace( - self, pattern, replacement, flags=None - ) -> "ColumnOperators": + self, pattern: Any, replacement: Any, flags: Optional[str] = None + ) -> ColumnOperators: """Implements a database-specific 'regexp replace' operator. E.g.:: @@ -1220,17 +1238,17 @@ class ColumnOperators(Operators[_OP_RETURN]): flags=flags, ) - def desc(self) -> "ColumnOperators": + def desc(self) -> ColumnOperators: """Produce a :func:`_expression.desc` clause against the parent object.""" return self.operate(desc_op) - def asc(self) -> "ColumnOperators": + def asc(self) -> ColumnOperators: """Produce a :func:`_expression.asc` clause against the parent object.""" return self.operate(asc_op) - def nulls_first(self) -> "ColumnOperators": + def nulls_first(self) -> ColumnOperators: """Produce a :func:`_expression.nulls_first` clause against the parent object. @@ -1243,7 +1261,7 @@ class ColumnOperators(Operators[_OP_RETURN]): # deprecated 1.4; see #5435 nullsfirst = nulls_first - def nulls_last(self) -> "ColumnOperators": + def nulls_last(self) -> ColumnOperators: """Produce a :func:`_expression.nulls_last` clause against the parent object. @@ -1256,7 +1274,7 @@ class ColumnOperators(Operators[_OP_RETURN]): # deprecated 1.4; see #5429 nullslast = nulls_last - def collate(self, collation) -> "ColumnOperators": + def collate(self, collation: str) -> ColumnOperators: """Produce a :func:`_expression.collate` clause against the parent object, given the collation string. @@ -1267,7 +1285,7 @@ class ColumnOperators(Operators[_OP_RETURN]): """ return self.operate(collate, collation) - def __radd__(self, other: Any) -> "ColumnOperators": + def __radd__(self, other: Any) -> ColumnOperators: """Implement the ``+`` operator in reverse. See :meth:`.ColumnOperators.__add__`. @@ -1275,7 +1293,7 @@ class ColumnOperators(Operators[_OP_RETURN]): """ return self.reverse_operate(add, other) - def __rsub__(self, other: Any) -> "ColumnOperators": + def __rsub__(self, other: Any) -> ColumnOperators: """Implement the ``-`` operator in reverse. See :meth:`.ColumnOperators.__sub__`. @@ -1283,7 +1301,7 @@ class ColumnOperators(Operators[_OP_RETURN]): """ return self.reverse_operate(sub, other) - def __rmul__(self, other: Any) -> "ColumnOperators": + def __rmul__(self, other: Any) -> ColumnOperators: """Implement the ``*`` operator in reverse. See :meth:`.ColumnOperators.__mul__`. @@ -1291,7 +1309,7 @@ class ColumnOperators(Operators[_OP_RETURN]): """ return self.reverse_operate(mul, other) - def __rmod__(self, other: Any) -> "ColumnOperators": + def __rmod__(self, other: Any) -> ColumnOperators: """Implement the ``%`` operator in reverse. See :meth:`.ColumnOperators.__mod__`. @@ -1299,21 +1317,23 @@ class ColumnOperators(Operators[_OP_RETURN]): """ return self.reverse_operate(mod, other) - def between(self, cleft, cright, symmetric=False) -> "ColumnOperators": + def between( + self, cleft: Any, cright: Any, symmetric: bool = False + ) -> ColumnOperators: """Produce a :func:`_expression.between` clause against the parent object, given the lower and upper range. """ return self.operate(between_op, cleft, cright, symmetric=symmetric) - def distinct(self) -> "ColumnOperators": + def distinct(self) -> ColumnOperators: """Produce a :func:`_expression.distinct` clause against the parent object. """ return self.operate(distinct_op) - def any_(self) -> "ColumnOperators": + def any_(self) -> ColumnOperators: """Produce an :func:`_expression.any_` clause against the parent object. @@ -1330,7 +1350,7 @@ class ColumnOperators(Operators[_OP_RETURN]): """ return self.operate(any_op) - def all_(self) -> "ColumnOperators": + def all_(self) -> ColumnOperators: """Produce an :func:`_expression.all_` clause against the parent object. @@ -1348,7 +1368,7 @@ class ColumnOperators(Operators[_OP_RETURN]): """ return self.operate(all_op) - def __add__(self, other: Any) -> "ColumnOperators": + def __add__(self, other: Any) -> ColumnOperators: """Implement the ``+`` operator. In a column context, produces the clause ``a + b`` @@ -1360,7 +1380,7 @@ class ColumnOperators(Operators[_OP_RETURN]): """ return self.operate(add, other) - def __sub__(self, other: Any) -> "ColumnOperators": + def __sub__(self, other: Any) -> ColumnOperators: """Implement the ``-`` operator. In a column context, produces the clause ``a - b``. @@ -1368,7 +1388,7 @@ class ColumnOperators(Operators[_OP_RETURN]): """ return self.operate(sub, other) - def __mul__(self, other: Any) -> "ColumnOperators": + def __mul__(self, other: Any) -> ColumnOperators: """Implement the ``*`` operator. In a column context, produces the clause ``a * b``. @@ -1376,7 +1396,7 @@ class ColumnOperators(Operators[_OP_RETURN]): """ return self.operate(mul, other) - def __mod__(self, other: Any) -> "ColumnOperators": + def __mod__(self, other: Any) -> ColumnOperators: """Implement the ``%`` operator. In a column context, produces the clause ``a % b``. @@ -1384,7 +1404,7 @@ class ColumnOperators(Operators[_OP_RETURN]): """ return self.operate(mod, other) - def __truediv__(self, other: Any) -> "ColumnOperators": + def __truediv__(self, other: Any) -> ColumnOperators: """Implement the ``/`` operator. In a column context, produces the clause ``a / b``, and @@ -1397,7 +1417,7 @@ class ColumnOperators(Operators[_OP_RETURN]): """ return self.operate(truediv, other) - def __rtruediv__(self, other: Any) -> "ColumnOperators": + def __rtruediv__(self, other: Any) -> ColumnOperators: """Implement the ``/`` operator in reverse. See :meth:`.ColumnOperators.__truediv__`. @@ -1405,7 +1425,7 @@ class ColumnOperators(Operators[_OP_RETURN]): """ return self.reverse_operate(truediv, other) - def __floordiv__(self, other: Any) -> "ColumnOperators": + def __floordiv__(self, other: Any) -> ColumnOperators: """Implement the ``//`` operator. In a column context, produces the clause ``a / b``, @@ -1417,7 +1437,7 @@ class ColumnOperators(Operators[_OP_RETURN]): """ return self.operate(floordiv, other) - def __rfloordiv__(self, other: Any) -> "ColumnOperators": + def __rfloordiv__(self, other: Any) -> ColumnOperators: """Implement the ``//`` operator in reverse. See :meth:`.ColumnOperators.__floordiv__`. @@ -1426,43 +1446,47 @@ class ColumnOperators(Operators[_OP_RETURN]): return self.reverse_operate(floordiv, other) -_commutative = {eq, ne, add, mul} -_comparison = {eq, ne, lt, gt, ge, le} +_commutative: Set[Any] = {eq, ne, add, mul} +_comparison: Set[Any] = {eq, ne, lt, gt, ge, le} -def _operator_fn(fn): +def _operator_fn(fn: Callable[..., Any]) -> OperatorType: return cast(OperatorType, fn) -def commutative_op(fn): +def commutative_op(fn: _FN) -> _FN: _commutative.add(fn) return fn -def comparison_op(fn): +def comparison_op(fn: _FN) -> _FN: _comparison.add(fn) return fn -def from_(): +@_operator_fn +def from_() -> Any: raise NotImplementedError() +@_operator_fn @comparison_op -def function_as_comparison_op(): +def function_as_comparison_op() -> Any: raise NotImplementedError() -def as_(): +@_operator_fn +def as_() -> Any: raise NotImplementedError() -def exists(): +@_operator_fn +def exists() -> Any: raise NotImplementedError() @_operator_fn -def is_true(a): +def is_true(a: Any) -> Any: raise NotImplementedError() @@ -1471,7 +1495,7 @@ istrue = is_true @_operator_fn -def is_false(a): +def is_false(a: Any) -> Any: raise NotImplementedError() @@ -1481,13 +1505,13 @@ isfalse = is_false @comparison_op @_operator_fn -def is_distinct_from(a, b): +def is_distinct_from(a: Any, b: Any) -> Any: return a.is_distinct_from(b) @comparison_op @_operator_fn -def is_not_distinct_from(a, b): +def is_not_distinct_from(a: Any, b: Any) -> Any: return a.is_not_distinct_from(b) @@ -1497,13 +1521,13 @@ isnot_distinct_from = is_not_distinct_from @comparison_op @_operator_fn -def is_(a, b): +def is_(a: Any, b: Any) -> Any: return a.is_(b) @comparison_op @_operator_fn -def is_not(a, b): +def is_not(a: Any, b: Any) -> Any: return a.is_not(b) @@ -1512,24 +1536,24 @@ isnot = is_not @_operator_fn -def collate(a, b): +def collate(a: Any, b: Any) -> Any: return a.collate(b) @_operator_fn -def op(a, opstring, b): +def op(a: Any, opstring: str, b: Any) -> Any: return a.op(opstring)(b) @comparison_op @_operator_fn -def like_op(a, b, escape=None): +def like_op(a: Any, b: Any, escape: Optional[str] = None) -> Any: return a.like(b, escape=escape) @comparison_op @_operator_fn -def not_like_op(a, b, escape=None): +def not_like_op(a: Any, b: Any, escape: Optional[str] = None) -> Any: return a.notlike(b, escape=escape) @@ -1539,13 +1563,13 @@ notlike_op = not_like_op @comparison_op @_operator_fn -def ilike_op(a, b, escape=None): +def ilike_op(a: Any, b: Any, escape: Optional[str] = None) -> Any: return a.ilike(b, escape=escape) @comparison_op @_operator_fn -def not_ilike_op(a, b, escape=None): +def not_ilike_op(a: Any, b: Any, escape: Optional[str] = None) -> Any: return a.not_ilike(b, escape=escape) @@ -1555,13 +1579,13 @@ notilike_op = not_ilike_op @comparison_op @_operator_fn -def between_op(a, b, c, symmetric=False): +def between_op(a: Any, b: Any, c: Any, symmetric: bool = False) -> Any: return a.between(b, c, symmetric=symmetric) @comparison_op @_operator_fn -def not_between_op(a, b, c, symmetric=False): +def not_between_op(a: Any, b: Any, c: Any, symmetric: bool = False) -> Any: return ~a.between(b, c, symmetric=symmetric) @@ -1571,13 +1595,13 @@ notbetween_op = not_between_op @comparison_op @_operator_fn -def in_op(a, b): +def in_op(a: Any, b: Any) -> Any: return a.in_(b) @comparison_op @_operator_fn -def not_in_op(a, b): +def not_in_op(a: Any, b: Any) -> Any: return a.not_in(b) @@ -1586,21 +1610,23 @@ notin_op = not_in_op @_operator_fn -def distinct_op(a): +def distinct_op(a: Any) -> Any: return a.distinct() @_operator_fn -def any_op(a): +def any_op(a: Any) -> Any: return a.any_() @_operator_fn -def all_op(a): +def all_op(a: Any) -> Any: return a.all_() -def _escaped_like_impl(fn, other: Any, escape, autoescape): +def _escaped_like_impl( + fn: Callable[..., Any], other: Any, escape: Optional[str], autoescape: bool +) -> Any: if autoescape: if autoescape is not True: util.warn( @@ -1622,13 +1648,17 @@ def _escaped_like_impl(fn, other: Any, escape, autoescape): @comparison_op @_operator_fn -def startswith_op(a, b, escape=None, autoescape=False): +def startswith_op( + a: Any, b: Any, escape: Optional[str] = None, autoescape: bool = False +) -> Any: return _escaped_like_impl(a.startswith, b, escape, autoescape) @comparison_op @_operator_fn -def not_startswith_op(a, b, escape=None, autoescape=False): +def not_startswith_op( + a: Any, b: Any, escape: Optional[str] = None, autoescape: bool = False +) -> Any: return ~_escaped_like_impl(a.startswith, b, escape, autoescape) @@ -1638,13 +1668,17 @@ notstartswith_op = not_startswith_op @comparison_op @_operator_fn -def endswith_op(a, b, escape=None, autoescape=False): +def endswith_op( + a: Any, b: Any, escape: Optional[str] = None, autoescape: bool = False +) -> Any: return _escaped_like_impl(a.endswith, b, escape, autoescape) @comparison_op @_operator_fn -def not_endswith_op(a, b, escape=None, autoescape=False): +def not_endswith_op( + a: Any, b: Any, escape: Optional[str] = None, autoescape: bool = False +) -> Any: return ~_escaped_like_impl(a.endswith, b, escape, autoescape) @@ -1654,13 +1688,17 @@ notendswith_op = not_endswith_op @comparison_op @_operator_fn -def contains_op(a, b, escape=None, autoescape=False): +def contains_op( + a: Any, b: Any, escape: Optional[str] = None, autoescape: bool = False +) -> Any: return _escaped_like_impl(a.contains, b, escape, autoescape) @comparison_op @_operator_fn -def not_contains_op(a, b, escape=None, autoescape=False): +def not_contains_op( + a: Any, b: Any, escape: Optional[str] = None, autoescape: bool = False +) -> Any: return ~_escaped_like_impl(a.contains, b, escape, autoescape) @@ -1670,30 +1708,32 @@ notcontains_op = not_contains_op @comparison_op @_operator_fn -def match_op(a, b, **kw): +def match_op(a: Any, b: Any, **kw: Any) -> Any: return a.match(b, **kw) @comparison_op @_operator_fn -def regexp_match_op(a, b, flags=None): +def regexp_match_op(a: Any, b: Any, flags: Optional[str] = None) -> Any: return a.regexp_match(b, flags=flags) @comparison_op @_operator_fn -def not_regexp_match_op(a, b, flags=None): +def not_regexp_match_op(a: Any, b: Any, flags: Optional[str] = None) -> Any: return ~a.regexp_match(b, flags=flags) @_operator_fn -def regexp_replace_op(a, b, replacement, flags=None): +def regexp_replace_op( + a: Any, b: Any, replacement: Any, flags: Optional[str] = None +) -> Any: return a.regexp_replace(b, replacement=replacement, flags=flags) @comparison_op @_operator_fn -def not_match_op(a, b, **kw): +def not_match_op(a: Any, b: Any, **kw: Any) -> Any: return ~a.match(b, **kw) @@ -1702,32 +1742,32 @@ notmatch_op = not_match_op @_operator_fn -def comma_op(a, b): +def comma_op(a: Any, b: Any) -> Any: raise NotImplementedError() @_operator_fn -def filter_op(a, b): +def filter_op(a: Any, b: Any) -> Any: raise NotImplementedError() @_operator_fn -def concat_op(a, b): +def concat_op(a: Any, b: Any) -> Any: return a.concat(b) @_operator_fn -def desc_op(a): +def desc_op(a: Any) -> Any: return a.desc() @_operator_fn -def asc_op(a): +def asc_op(a: Any) -> Any: return a.asc() @_operator_fn -def nulls_first_op(a): +def nulls_first_op(a: Any) -> Any: return a.nulls_first() @@ -1736,7 +1776,7 @@ nullsfirst_op = nulls_first_op @_operator_fn -def nulls_last_op(a): +def nulls_last_op(a: Any) -> Any: return a.nulls_last() @@ -1745,28 +1785,28 @@ nullslast_op = nulls_last_op @_operator_fn -def json_getitem_op(a, b): +def json_getitem_op(a: Any, b: Any) -> Any: raise NotImplementedError() @_operator_fn -def json_path_getitem_op(a, b): +def json_path_getitem_op(a: Any, b: Any) -> Any: raise NotImplementedError() -def is_comparison(op): +def is_comparison(op: OperatorType) -> bool: return op in _comparison or isinstance(op, custom_op) and op.is_comparison -def is_commutative(op): +def is_commutative(op: OperatorType) -> bool: return op in _commutative -def is_ordering_modifier(op): +def is_ordering_modifier(op: OperatorType) -> bool: return op in (asc_op, desc_op, nulls_first_op, nulls_last_op) -def is_natural_self_precedent(op): +def is_natural_self_precedent(op: OperatorType) -> bool: return ( op in _natural_self_precedent or isinstance(op, custom_op) @@ -1777,14 +1817,14 @@ def is_natural_self_precedent(op): _booleans = (inv, is_true, is_false, and_, or_) -def is_boolean(op): +def is_boolean(op: OperatorType) -> bool: return is_comparison(op) or op in _booleans _mirror = {gt: lt, ge: le, lt: gt, le: ge} -def mirror(op): +def mirror(op: OperatorType) -> OperatorType: """rotate a comparison operator 180 degrees. Note this is not the same as negation. @@ -1796,7 +1836,7 @@ def mirror(op): _associative = _commutative.union([concat_op, and_, or_]).difference([eq, ne]) -def is_associative(op): +def is_associative(op: OperatorType) -> bool: return op in _associative @@ -1809,11 +1849,17 @@ parenthesize (a op b). """ -_asbool = util.symbol("_asbool", canonical=-10) -_smallest = util.symbol("_smallest", canonical=-100) -_largest = util.symbol("_largest", canonical=100) +@_operator_fn +def _asbool(a: Any) -> Any: + raise NotImplementedError() -_PRECEDENCE = { + +class _OpLimit(IntEnum): + _smallest = -100 + _largest = 100 + + +_PRECEDENCE: Dict[OperatorType, int] = { from_: 15, function_as_comparison_op: 15, any_op: 15, @@ -1866,15 +1912,18 @@ _PRECEDENCE = { as_: -1, exists: 0, _asbool: -10, - _smallest: _smallest, - _largest: _largest, } -def is_precedent(operator, against): +def is_precedent(operator: OperatorType, against: OperatorType) -> bool: if operator is against and is_natural_self_precedent(operator): return False else: - return _PRECEDENCE.get( - operator, getattr(operator, "precedence", _smallest) - ) <= _PRECEDENCE.get(against, getattr(against, "precedence", _largest)) + return bool( + _PRECEDENCE.get( + operator, getattr(operator, "precedence", _OpLimit._smallest) + ) + <= _PRECEDENCE.get( + against, getattr(against, "precedence", _OpLimit._largest) + ) + ) |