From f472732cd65db2ae6083d960e71b2b82100a190f Mon Sep 17 00:00:00 2001 From: Tim Rid <6593626+timrid@users.noreply.github.com> Date: Thu, 17 Dec 2020 19:55:07 +0100 Subject: [PATCH] enhanced stubs for expr.py and added an generator script --- construct-stubs/expr.pyi | 599 +++++++++++++++++++++++++++----- scripts/expr_mixin_generator.py | 77 ++++ 2 files changed, 584 insertions(+), 92 deletions(-) create mode 100644 scripts/expr_mixin_generator.py diff --git a/construct-stubs/expr.pyi b/construct-stubs/expr.pyi index 5e4f704..46ed44e 100644 --- a/construct-stubs/expr.pyi +++ b/construct-stubs/expr.pyi @@ -2,110 +2,525 @@ import operator import typing as t from construct.core import * -UniOperator = t.Literal[ - operator.not_, - operator.neg, - operator.pos, -] +UniOperator = t.Callable[[t.Any], t.Any] +BinOperator = t.Callable[[t.Any, t.Any], t.Any] -BinOperator = t.Literal[ - operator.add, - operator.sub, - operator.mul, - operator.floordiv, - operator.mod, - operator.pow, - operator.xor, - operator.lshift, - operator.rshift, - operator.and_, - operator.or_, - operator.contains, - operator.gt, - operator.ge, - operator.lt, - operator.le, - operator.eq, - operator.ne, -] +ReturnType = t.TypeVar("ReturnType") +LhsReturnType = t.TypeVar("LhsReturnType") +RhsReturnType = t.TypeVar("RhsReturnType") -class ExprMixin(object): - def __add__(self, other: t.Any) -> BinExpr: ... - def __sub__(self, other: t.Any) -> BinExpr: ... - def __mul__(self, other: t.Any) -> BinExpr: ... - def __floordiv__(self, other: t.Any) -> BinExpr: ... - def __truediv__(self, other: t.Any) -> BinExpr: ... - __div__: t.Callable[[t.Any], BinExpr] - def __mod__(self, other: t.Any) -> BinExpr: ... - def __pow__(self, other: t.Any) -> BinExpr: ... - def __xor__(self, other: t.Any) -> BinExpr: ... - def __rshift__(self, other: t.Any) -> BinExpr: ... - def __lshift__(self, other: t.Any) -> BinExpr: ... - def __and__(self, other: t.Any) -> BinExpr: ... - def __or__(self, other: t.Any) -> BinExpr: ... - - def __radd__(self, other: t.Any) -> BinExpr: ... - def __rsub__(self, other: t.Any) -> BinExpr: ... - def __rmul__(self, other: t.Any) -> BinExpr: ... - def __rfloordiv__(self, other: t.Any) -> BinExpr: ... - def __rtruediv__(self, other: t.Any) -> BinExpr: ... - __rdiv__: t.Callable[[t.Any], BinExpr] - def __rmod__(self, other: t.Any) -> BinExpr: ... - def __rpow__(self, other: t.Any) -> BinExpr: ... - def __rxor__(self, other: t.Any) -> BinExpr: ... - def __rrshift__(self, other: t.Any) -> BinExpr: ... - def __rlshift__(self, other: t.Any) -> BinExpr: ... - def __rand__(self, other: t.Any) -> BinExpr: ... - def __ror__(self, other: t.Any) -> BinExpr: ... - - def __neg__(self) -> UniExpr: ... - def __pos__(self) -> UniExpr: ... - def __invert__(self) -> UniExpr: ... - __inv__: t.Callable[[], UniExpr] - - def __contains__(self, other: t.Any) -> BinExpr: ... - def __gt__(self, other: t.Any) -> BinExpr: ... - def __ge__(self, other: t.Any) -> BinExpr: ... - def __lt__(self, other: t.Any) -> BinExpr: ... - def __le__(self, other: t.Any) -> BinExpr: ... - def __eq__(self, other: t.Any) -> BinExpr: ... - def __ne__(self, other: t.Any) -> BinExpr: ... +ConstOrCallable = t.Union[ReturnType, t.Callable[[ReturnType], ReturnType]] -class UniExpr(ExprMixin): +class ExprMixin(t.Generic[ReturnType], object): + # __add__ ########################################################################################################## + @t.overload + def __add__(self: ExprMixin[int], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __add__(self: ExprMixin[int], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __add__(self: ExprMixin[bool], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __add__(self: ExprMixin[bool], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __add__(self: ExprMixin[float], other: ConstOrCallable[int]) -> BinExpr[float]: ... + @t.overload + def __add__(self: ExprMixin[float], other: ConstOrCallable[bool]) -> BinExpr[float]: ... + @t.overload + def __add__(self: ExprMixin[float], other: ConstOrCallable[float]) -> BinExpr[float]: ... + @t.overload + + # __sub__ ########################################################################################################## + @t.overload + def __sub__(self: ExprMixin[int], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __sub__(self: ExprMixin[int], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __sub__(self: ExprMixin[bool], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __sub__(self: ExprMixin[bool], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __sub__(self: ExprMixin[float], other: ConstOrCallable[int]) -> BinExpr[float]: ... + @t.overload + def __sub__(self: ExprMixin[float], other: ConstOrCallable[bool]) -> BinExpr[float]: ... + @t.overload + def __sub__(self: ExprMixin[float], other: ConstOrCallable[float]) -> BinExpr[float]: ... + @t.overload + def __sub__(self, other: t.Any) -> BinExpr[t.Any]: ... + + # __mul__ ########################################################################################################## + @t.overload + def __mul__(self: ExprMixin[int], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __mul__(self: ExprMixin[int], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __mul__(self: ExprMixin[bool], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __mul__(self: ExprMixin[bool], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __mul__(self: ExprMixin[float], other: ConstOrCallable[int]) -> BinExpr[float]: ... + @t.overload + def __mul__(self: ExprMixin[float], other: ConstOrCallable[bool]) -> BinExpr[float]: ... + @t.overload + def __mul__(self: ExprMixin[float], other: ConstOrCallable[float]) -> BinExpr[float]: ... + @t.overload + def __mul__(self, other: t.Any) -> BinExpr[t.Any]: ... + + # __floordiv__ ##################################################################################################### + @t.overload + def __floordiv__(self: ExprMixin[int], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __floordiv__(self: ExprMixin[int], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __floordiv__(self: ExprMixin[bool], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __floordiv__(self: ExprMixin[bool], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __floordiv__(self: ExprMixin[float], other: ConstOrCallable[int]) -> BinExpr[float]: ... + @t.overload + def __floordiv__(self: ExprMixin[float], other: ConstOrCallable[bool]) -> BinExpr[float]: ... + @t.overload + def __floordiv__(self: ExprMixin[float], other: ConstOrCallable[float]) -> BinExpr[float]: ... + @t.overload + def __floordiv__(self, other: t.Any) -> BinExpr[t.Any]: ... + + # __truediv__ ###################################################################################################### + @t.overload + def __truediv__(self: ExprMixin[int], other: ConstOrCallable[int]) -> BinExpr[float]: ... + @t.overload + def __truediv__(self: ExprMixin[int], other: ConstOrCallable[bool]) -> BinExpr[float]: ... + @t.overload + def __truediv__(self: ExprMixin[bool], other: ConstOrCallable[int]) -> BinExpr[float]: ... + @t.overload + def __truediv__(self: ExprMixin[bool], other: ConstOrCallable[bool]) -> BinExpr[float]: ... + @t.overload + def __truediv__(self: ExprMixin[float], other: ConstOrCallable[int]) -> BinExpr[float]: ... + @t.overload + def __truediv__(self: ExprMixin[float], other: ConstOrCallable[bool]) -> BinExpr[float]: ... + @t.overload + def __truediv__(self: ExprMixin[float], other: ConstOrCallable[float]) -> BinExpr[float]: ... + @t.overload + def __truediv__(self, other: t.Any) -> BinExpr[t.Any]: ... + + # __div__ ########################################################################################################## + def __div__(self, other: t.Any) -> BinExpr[t.Any]: ... + + # __mod__ ########################################################################################################## + @t.overload + def __mod__(self: ExprMixin[int], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __mod__(self: ExprMixin[int], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __mod__(self: ExprMixin[bool], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __mod__(self: ExprMixin[bool], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __mod__(self: ExprMixin[float], other: ConstOrCallable[int]) -> BinExpr[float]: ... + @t.overload + def __mod__(self: ExprMixin[float], other: ConstOrCallable[bool]) -> BinExpr[float]: ... + @t.overload + def __mod__(self: ExprMixin[float], other: ConstOrCallable[float]) -> BinExpr[float]: ... + @t.overload + def __mod__(self, other: t.Any) -> BinExpr[t.Any]: ... + + # __pow__ ########################################################################################################## + @t.overload + def __pow__(self: ExprMixin[int], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __pow__(self: ExprMixin[int], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __pow__(self: ExprMixin[bool], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __pow__(self: ExprMixin[bool], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __pow__(self: ExprMixin[float], other: ConstOrCallable[int]) -> BinExpr[float]: ... + @t.overload + def __pow__(self: ExprMixin[float], other: ConstOrCallable[bool]) -> BinExpr[float]: ... + @t.overload + def __pow__(self: ExprMixin[float], other: ConstOrCallable[float]) -> BinExpr[float]: ... + @t.overload + def __pow__(self, other: t.Any) -> BinExpr[t.Any]: ... + + # __xor__ ########################################################################################################## + @t.overload + def __xor__(self: ExprMixin[int], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __xor__(self: ExprMixin[int], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __xor__(self: ExprMixin[bool], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __xor__(self, other: t.Any) -> BinExpr[t.Any]: ... + + # __rshift__ ####################################################################################################### + @t.overload + def __rshift__(self: ExprMixin[int], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __rshift__(self: ExprMixin[int], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __rshift__(self: ExprMixin[bool], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __rshift__(self: ExprMixin[bool], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __rshift__(self, other: t.Any) -> BinExpr[t.Any]: ... + + # __lshift__ ####################################################################################################### + @t.overload + def __lshift__(self: ExprMixin[int], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __lshift__(self: ExprMixin[int], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __lshift__(self: ExprMixin[bool], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __lshift__(self: ExprMixin[bool], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __lshift__(self, other: t.Any) -> BinExpr[t.Any]: ... + + # __and__ ########################################################################################################## + @t.overload + def __and__(self: ExprMixin[int], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __and__(self: ExprMixin[int], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __and__(self: ExprMixin[bool], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __and__(self, other: t.Any) -> BinExpr[t.Any]: ... + + # __or__ ########################################################################################################### + @t.overload + def __or__(self: ExprMixin[int], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __or__(self: ExprMixin[int], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __or__(self: ExprMixin[bool], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __or__(self, other: t.Any) -> BinExpr[t.Any]: ... + + # __radd__ ######################################################################################################### + @t.overload + def __radd__(self: ExprMixin[int], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __radd__(self: ExprMixin[int], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __radd__(self: ExprMixin[bool], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __radd__(self: ExprMixin[bool], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __radd__(self: ExprMixin[float], other: ConstOrCallable[int]) -> BinExpr[float]: ... + @t.overload + def __radd__(self: ExprMixin[float], other: ConstOrCallable[bool]) -> BinExpr[float]: ... + @t.overload + def __radd__(self: ExprMixin[float], other: ConstOrCallable[float]) -> BinExpr[float]: ... + @t.overload + def __radd__(self, other: t.Any) -> BinExpr[t.Any]: ... + + # __rsub__ ######################################################################################################### + @t.overload + def __rsub__(self: ExprMixin[int], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __rsub__(self: ExprMixin[int], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __rsub__(self: ExprMixin[bool], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __rsub__(self: ExprMixin[bool], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __rsub__(self: ExprMixin[float], other: ConstOrCallable[int]) -> BinExpr[float]: ... + @t.overload + def __rsub__(self: ExprMixin[float], other: ConstOrCallable[bool]) -> BinExpr[float]: ... + @t.overload + def __rsub__(self: ExprMixin[float], other: ConstOrCallable[float]) -> BinExpr[float]: ... + @t.overload + def __rsub__(self, other: t.Any) -> BinExpr[t.Any]: ... + + # __rmul__ ######################################################################################################### + @t.overload + def __rmul__(self: ExprMixin[int], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __rmul__(self: ExprMixin[int], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __rmul__(self: ExprMixin[bool], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __rmul__(self: ExprMixin[bool], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __rmul__(self: ExprMixin[float], other: ConstOrCallable[int]) -> BinExpr[float]: ... + @t.overload + def __rmul__(self: ExprMixin[float], other: ConstOrCallable[bool]) -> BinExpr[float]: ... + @t.overload + def __rmul__(self: ExprMixin[float], other: ConstOrCallable[float]) -> BinExpr[float]: ... + @t.overload + def __rmul__(self, other: t.Any) -> BinExpr[t.Any]: ... + + # __rfloordiv__ #################################################################################################### + @t.overload + def __rfloordiv__(self: ExprMixin[int], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __rfloordiv__(self: ExprMixin[int], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __rfloordiv__(self: ExprMixin[bool], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __rfloordiv__(self: ExprMixin[bool], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __rfloordiv__(self: ExprMixin[float], other: ConstOrCallable[int]) -> BinExpr[float]: ... + @t.overload + def __rfloordiv__(self: ExprMixin[float], other: ConstOrCallable[bool]) -> BinExpr[float]: ... + @t.overload + def __rfloordiv__(self: ExprMixin[float], other: ConstOrCallable[float]) -> BinExpr[float]: ... + @t.overload + def __rfloordiv__(self, other: t.Any) -> BinExpr[t.Any]: ... + + # __rtruediv__ ##################################################################################################### + @t.overload + def __rtruediv__(self: ExprMixin[int], other: ConstOrCallable[int]) -> BinExpr[float]: ... + @t.overload + def __rtruediv__(self: ExprMixin[int], other: ConstOrCallable[bool]) -> BinExpr[float]: ... + @t.overload + def __rtruediv__(self: ExprMixin[bool], other: ConstOrCallable[int]) -> BinExpr[float]: ... + @t.overload + def __rtruediv__(self: ExprMixin[bool], other: ConstOrCallable[bool]) -> BinExpr[float]: ... + @t.overload + def __rtruediv__(self: ExprMixin[float], other: ConstOrCallable[int]) -> BinExpr[float]: ... + @t.overload + def __rtruediv__(self: ExprMixin[float], other: ConstOrCallable[bool]) -> BinExpr[float]: ... + @t.overload + def __rtruediv__(self: ExprMixin[float], other: ConstOrCallable[float]) -> BinExpr[float]: ... + @t.overload + def __rtruediv__(self, other: t.Any) -> BinExpr[t.Any]: ... + + # __rdiv__ ######################################################################################################### + def __rdiv__(self, other: t.Any) -> BinExpr[t.Any]: ... + + # __rmod__ ######################################################################################################### + @t.overload + def __rmod__(self: ExprMixin[int], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __rmod__(self: ExprMixin[int], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __rmod__(self: ExprMixin[bool], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __rmod__(self: ExprMixin[bool], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __rmod__(self: ExprMixin[float], other: ConstOrCallable[int]) -> BinExpr[float]: ... + @t.overload + def __rmod__(self: ExprMixin[float], other: ConstOrCallable[bool]) -> BinExpr[float]: ... + @t.overload + def __rmod__(self: ExprMixin[float], other: ConstOrCallable[float]) -> BinExpr[float]: ... + @t.overload + def __rmod__(self, other: t.Any) -> BinExpr[t.Any]: ... + + # __rpow__ ######################################################################################################### + @t.overload + def __rpow__(self: ExprMixin[int], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __rpow__(self: ExprMixin[int], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __rpow__(self: ExprMixin[bool], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __rpow__(self: ExprMixin[bool], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __rpow__(self: ExprMixin[float], other: ConstOrCallable[int]) -> BinExpr[float]: ... + @t.overload + def __rpow__(self: ExprMixin[float], other: ConstOrCallable[bool]) -> BinExpr[float]: ... + @t.overload + def __rpow__(self: ExprMixin[float], other: ConstOrCallable[float]) -> BinExpr[float]: ... + @t.overload + def __rpow__(self, other: t.Any) -> BinExpr[t.Any]: ... + + # __rxor__ ######################################################################################################### + @t.overload + def __rxor__(self: ExprMixin[int], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __rxor__(self: ExprMixin[int], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __rxor__(self: ExprMixin[bool], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __rxor__(self, other: t.Any) -> BinExpr[t.Any]: ... + + # __rrshift__ ###################################################################################################### + @t.overload + def __rrshift__(self: ExprMixin[int], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __rrshift__(self: ExprMixin[int], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __rrshift__(self: ExprMixin[bool], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __rrshift__(self: ExprMixin[bool], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __rrshift__(self, other: t.Any) -> BinExpr[t.Any]: ... + + # __rlshift__ ###################################################################################################### + @t.overload + def __rlshift__(self: ExprMixin[int], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __rlshift__(self: ExprMixin[int], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __rlshift__(self: ExprMixin[bool], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __rlshift__(self: ExprMixin[bool], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __rlshift__(self, other: t.Any) -> BinExpr[t.Any]: ... + + # __rand__ ######################################################################################################### + @t.overload + def __rand__(self: ExprMixin[int], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __rand__(self: ExprMixin[int], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __rand__(self: ExprMixin[bool], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __rand__(self, other: t.Any) -> BinExpr[t.Any]: ... + + # __ror__ ########################################################################################################## + @t.overload + def __ror__(self: ExprMixin[int], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __ror__(self: ExprMixin[int], other: ConstOrCallable[bool]) -> BinExpr[int]: ... + @t.overload + def __ror__(self: ExprMixin[bool], other: ConstOrCallable[int]) -> BinExpr[int]: ... + @t.overload + def __ror__(self, other: t.Any) -> BinExpr[t.Any]: ... + + # __contains__ ##################################################################################################### + def __contains__(self, other: t.Any) -> BinExpr[t.Any]: ... + + # __gt__ ########################################################################################################### + @t.overload + def __gt__(self: ExprMixin[int], other: ConstOrCallable[int]) -> BinExpr[bool]: ... + @t.overload + def __gt__(self: ExprMixin[int], other: ConstOrCallable[bool]) -> BinExpr[bool]: ... + @t.overload + def __gt__(self: ExprMixin[bool], other: ConstOrCallable[int]) -> BinExpr[bool]: ... + @t.overload + def __gt__(self: ExprMixin[bool], other: ConstOrCallable[bool]) -> BinExpr[bool]: ... + @t.overload + def __gt__(self: ExprMixin[float], other: ConstOrCallable[int]) -> BinExpr[bool]: ... + @t.overload + def __gt__(self: ExprMixin[float], other: ConstOrCallable[bool]) -> BinExpr[bool]: ... + @t.overload + def __gt__(self: ExprMixin[float], other: ConstOrCallable[float]) -> BinExpr[bool]: ... + @t.overload + def __gt__(self, other: t.Any) -> BinExpr[t.Any]: ... + + # __ge__ ########################################################################################################### + @t.overload + def __ge__(self: ExprMixin[int], other: ConstOrCallable[int]) -> BinExpr[bool]: ... + @t.overload + def __ge__(self: ExprMixin[int], other: ConstOrCallable[bool]) -> BinExpr[bool]: ... + @t.overload + def __ge__(self: ExprMixin[bool], other: ConstOrCallable[int]) -> BinExpr[bool]: ... + @t.overload + def __ge__(self: ExprMixin[bool], other: ConstOrCallable[bool]) -> BinExpr[bool]: ... + @t.overload + def __ge__(self: ExprMixin[float], other: ConstOrCallable[int]) -> BinExpr[bool]: ... + @t.overload + def __ge__(self: ExprMixin[float], other: ConstOrCallable[bool]) -> BinExpr[bool]: ... + @t.overload + def __ge__(self: ExprMixin[float], other: ConstOrCallable[float]) -> BinExpr[bool]: ... + @t.overload + def __ge__(self, other: t.Any) -> BinExpr[t.Any]: ... + + # __lt__ ########################################################################################################### + @t.overload + def __lt__(self: ExprMixin[int], other: ConstOrCallable[int]) -> BinExpr[bool]: ... + @t.overload + def __lt__(self: ExprMixin[int], other: ConstOrCallable[bool]) -> BinExpr[bool]: ... + @t.overload + def __lt__(self: ExprMixin[bool], other: ConstOrCallable[int]) -> BinExpr[bool]: ... + @t.overload + def __lt__(self: ExprMixin[bool], other: ConstOrCallable[bool]) -> BinExpr[bool]: ... + @t.overload + def __lt__(self: ExprMixin[float], other: ConstOrCallable[int]) -> BinExpr[bool]: ... + @t.overload + def __lt__(self: ExprMixin[float], other: ConstOrCallable[bool]) -> BinExpr[bool]: ... + @t.overload + def __lt__(self: ExprMixin[float], other: ConstOrCallable[float]) -> BinExpr[bool]: ... + @t.overload + def __lt__(self, other: t.Any) -> BinExpr[t.Any]: ... + + # __le__ ########################################################################################################### + @t.overload + def __le__(self: ExprMixin[int], other: ConstOrCallable[int]) -> BinExpr[bool]: ... + @t.overload + def __le__(self: ExprMixin[int], other: ConstOrCallable[bool]) -> BinExpr[bool]: ... + @t.overload + def __le__(self: ExprMixin[bool], other: ConstOrCallable[int]) -> BinExpr[bool]: ... + @t.overload + def __le__(self: ExprMixin[bool], other: ConstOrCallable[bool]) -> BinExpr[bool]: ... + @t.overload + def __le__(self: ExprMixin[float], other: ConstOrCallable[int]) -> BinExpr[bool]: ... + @t.overload + def __le__(self: ExprMixin[float], other: ConstOrCallable[bool]) -> BinExpr[bool]: ... + @t.overload + def __le__(self: ExprMixin[float], other: ConstOrCallable[float]) -> BinExpr[bool]: ... + @t.overload + def __le__(self, other: t.Any) -> BinExpr[t.Any]: ... + + # __eq__ ########################################################################################################### + @t.overload + def __eq__(self: ExprMixin[int], other: ConstOrCallable[int]) -> BinExpr[bool]: ... + @t.overload + def __eq__(self: ExprMixin[int], other: ConstOrCallable[bool]) -> BinExpr[bool]: ... + @t.overload + def __eq__(self: ExprMixin[bool], other: ConstOrCallable[int]) -> BinExpr[bool]: ... + @t.overload + def __eq__(self: ExprMixin[bool], other: ConstOrCallable[bool]) -> BinExpr[bool]: ... + @t.overload + def __eq__(self: ExprMixin[float], other: ConstOrCallable[int]) -> BinExpr[bool]: ... + @t.overload + def __eq__(self: ExprMixin[float], other: ConstOrCallable[bool]) -> BinExpr[bool]: ... + @t.overload + def __eq__(self: ExprMixin[float], other: ConstOrCallable[float]) -> BinExpr[bool]: ... + @t.overload + def __eq__(self, other: t.Any) -> BinExpr[t.Any]: ... + + # __ne__ ########################################################################################################### + @t.overload + def __ne__(self: ExprMixin[int], other: ConstOrCallable[int]) -> BinExpr[bool]: ... + @t.overload + def __ne__(self: ExprMixin[int], other: ConstOrCallable[bool]) -> BinExpr[bool]: ... + @t.overload + def __ne__(self: ExprMixin[bool], other: ConstOrCallable[int]) -> BinExpr[bool]: ... + @t.overload + def __ne__(self: ExprMixin[bool], other: ConstOrCallable[bool]) -> BinExpr[bool]: ... + @t.overload + def __ne__(self: ExprMixin[float], other: ConstOrCallable[int]) -> BinExpr[bool]: ... + @t.overload + def __ne__(self: ExprMixin[float], other: ConstOrCallable[bool]) -> BinExpr[bool]: ... + @t.overload + def __ne__(self: ExprMixin[float], other: ConstOrCallable[float]) -> BinExpr[bool]: ... + @t.overload + def __ne__(self, other: t.Any) -> BinExpr[t.Any]: ... + +class UniExpr(ExprMixin[ReturnType]): def __init__(self, op: UniOperator, operand: t.Any) -> None: ... - def __call__(self, obj: t.Union[Context, dict[str, t.Any]], *args: t.Any) -> t.Any: ... + def __call__(self, obj: t.Union[Context, dict[str, t.Any], t.Any], *args: t.Any) -> ReturnType: ... - -class BinExpr(ExprMixin): +class BinExpr(ExprMixin[ReturnType]): def __init__(self, op: BinOperator, lhs: t.Any, rhs: t.Any) -> None: ... - def __call__(self, obj: t.Union[Context, dict[str, t.Any]], *args: t.Any) -> t.Any: ... + def __call__(self, obj: t.Union[Context, dict[str, t.Any], t.Any], *args: t.Any) -> ReturnType: ... + +class Path(ExprMixin[ReturnType]): + def __init__(self, name: str, field: t.Optional[str] = ..., parent: t.Optional[Path[t.Any]] = ...) -> None: ... + def __call__(self, obj: t.Union[Context, dict[str, t.Any], t.Any], *args: t.Any) -> ReturnType: ... + def __getattr__(self, name: str) -> Path[t.Any]: ... + def __getitem__(self, name: str) -> Path[t.Any]: ... -class Path(ExprMixin): - def __init__(self, name: str, field: t.Optional[str] = ..., parent: t.Optional[Path] = ...) -> None: ... - def __call__(self, obj: t.Union[Context, dict[str, t.Any]], *args: t.Any) -> t.Any: ... - def __getattr__(self, name: str) -> Path: ... - def __getitem__(self, name: str) -> Path: ... +class Path2(ExprMixin[ReturnType]): + def __init__(self, name: str, index: t.Optional[int] = ..., parent: t.Optional[Path2[t.Any]] = ...) -> None: ... + def __call__(self, *args: t.Any) -> ReturnType: ... + def __getitem__(self, index: int) -> Path2[t.Any]: ... -class Path2(ExprMixin): - def __init__(self, name: str, index: t.Optional[int] = ..., parent: t.Optional[Path2] = ...) -> None: ... - def __call__(self, *args: t.Any) -> t.Any: ... - def __getitem__(self, index: int) -> Path2: ... - - -class FuncPath(ExprMixin): +class FuncPath(ExprMixin[ReturnType]): def __init__(self, func: t.Callable[[t.Any], t.Any], operand: t.Optional[t.Any] = ...) -> None: ... - def __call__(self, operand: t.Any, *args: t.Any) -> t.Any: ... + def __call__(self, operand: t.Any, *args: t.Any) -> ReturnType: ... -this: Path -obj_: Path -list_: Path2 +this: Path[t.Any] +obj_: Path[t.Any] +list_: Path2[t.Any] -len_: FuncPath -sum_: FuncPath -min_: FuncPath -max_: FuncPath -abs_: FuncPath +len_: FuncPath[int] +sum_: FuncPath[int] +min_: FuncPath[int] +max_: FuncPath[int] +abs_: FuncPath[int] diff --git a/scripts/expr_mixin_generator.py b/scripts/expr_mixin_generator.py new file mode 100644 index 0000000..91a2613 --- /dev/null +++ b/scripts/expr_mixin_generator.py @@ -0,0 +1,77 @@ + + +testobjs = [ + int(10), + bool(1), + float(10.0), +] + +operators = [ + "__add__", + "__sub__", + "__mul__", + "__floordiv__", + "__truediv__", + "__div__", + "__mod__", + "__pow__", + "__xor__", + "__rshift__", + "__lshift__", + "__and__", + "__or__", + + "__radd__", + "__rsub__", + "__rmul__", + "__rfloordiv__", + "__rtruediv__", + "__rdiv__", + "__rmod__", + "__rpow__", + "__rxor__", + "__rrshift__", + "__rlshift__", + "__rand__", + "__ror__", + + # "__neg__", + # "__pos__", + # "__invert__", + # "__inv__", + + "__contains__", + "__gt__", + "__ge__", + "__lt__", + "__le__", + "__eq__", + "__ne__", +] + + +def create_overload(op, lhs=None, rhs=None): + if lhs is None and rhs is None: + print(" @t.overload") + print(f" def {op}(self, other: t.Any) -> BinExpr[t.Any]: ...") + else: + try: + result = getattr(lhs, op)(rhs) + lhs_type = type(lhs).__name__ + rhs_type = type(rhs).__name__ + result_type = type(result).__name__ + if result_type != "NotImplementedType": + print(" @t.overload") + print(f" def {op}(self: ExprMixin[{lhs_type}], other: ConstOrCallable[{rhs_type}]) -> BinExpr[{result_type}]: ...") + except AttributeError: + pass + + +print("class ExprMixin(t.Generic[ReturnType], object):") +for op in operators: + print(f" # {op} ".ljust(120, "#")) + for lhs in testobjs: + for rhs in testobjs: + create_overload(op, lhs, rhs) + create_overload(op) + print("")