import ast
import itertools
import re
import sys
import types
from _typeshed import Incomplete
from collections.abc import Generator, Iterable, Sequence
from datetime import date, datetime, time, timedelta
from decimal import Decimal
from random import random
from typing import Any, ClassVar, NoReturn
from typing_extensions import Self

from pony.orm import core
from pony.orm.asttranslation import ASTTranslator
from pony.orm.ormtypes import raw_sql
from pony.utils import between, coalesce, concat, localbase

NoneType: type[None]

def check_comparable(left_monad: Monad, right_monad: Monad, op: str = "==") -> None: ...

class IncomparableTypesError(TypeError):
    type1: Incomplete
    type2: Incomplete
    def __init__(exc, type1, type2) -> None: ...

def sqland(items): ...
def sqlor(items): ...
def join_tables(alias1, alias2, columns1, columns2): ...
def type2str(t) -> str: ...

class Local(localbase):
    translators: list[SQLTranslator]
    def __init__(local) -> None: ...
    @property
    def translator(self) -> SQLTranslator: ...

translator_counter: itertools.count[int]
local: Local

class SQLTranslator(ASTTranslator):
    dialect: ClassVar[str | None]
    row_value_syntax: ClassVar[bool]
    json_path_wildcard_syntax: ClassVar[bool]
    json_values_are_comparable: ClassVar[bool]
    rowid_support: ClassVar[bool]
    registered_functions: dict[types.FunctionType, type[FuncMonad]]
    def __enter__(translator) -> None: ...
    def __exit__(translator, exc_type, exc_val, exc_tb) -> None: ...
    def default_post(translator, node) -> None: ...
    def dispatch(translator, node): ...
    def dispatch_external(translator, node) -> None: ...
    def call(translator, method, node): ...
    def deepcopy(translator): ...
    def __init__(
        translator,
        tree,
        parent_translator,
        code_key=None,
        filter_num=None,
        extractors=None,
        vars=None,
        vartypes=None,
        left_join: bool = False,
        optimize=None,
    ) -> None: ...
    def init(
        translator,
        tree,
        parent_translator,
        code_key=None,
        filter_num=None,
        extractors=None,
        vars=None,
        vartypes=None,
        left_join: bool = False,
        optimize=None,
    ): ...
    @property
    def namespace(translator): ...
    def can_be_optimized(translator): ...
    def process_query_qual(
        translator, prev_translator, prev_limit, prev_offset, names, try_extend_prev_query: bool = False
    ) -> None: ...
    def construct_subquery_ast(
        translator, limit=None, offset=None, aliases=None, star=None, distinct=None, is_not_null_checks: bool = False
    ): ...
    def construct_sql_ast(
        translator,
        limit=None,
        offset=None,
        distinct=None,
        aggr_func_name=None,
        aggr_func_distinct=None,
        sep=None,
        for_update: bool = False,
        nowait: bool = False,
        skip_locked: bool = False,
        is_not_null_checks: bool = False,
    ): ...
    def construct_delete_sql_ast(translator): ...
    def get_used_attrs(translator): ...
    def without_order(translator) -> Self: ...
    def order_by_numbers(translator, numbers: Iterable[int]) -> Self: ...
    def order_by_attributes(translator, attrs: Iterable[core.DescWrapper | core.Attribute]) -> Self: ...
    def apply_kwfilters(translator, filterattrs, original_names: bool = False) -> Self: ...
    def apply_lambda(
        translator, func_id, filter_num, order_by, func_ast, argnames, original_names, extractors, vars, vartypes
    ) -> Self: ...
    def preGeneratorExp(translator, node: ast.GeneratorExp) -> QuerySetMonad: ...
    def postExpr(translator, node: ast.Expr): ...
    def preCompare(translator, node: ast.Compare): ...
    def postConstant(translator, node: ast.Constant) -> ConstMonad: ...
    if sys.version_info >= (3, 14):
        def postNameConstant(translator, node: ast.Constant): ...
        def postNum(translator, node: ast.Constant) -> ConstMonad: ...
        def postStr(translator, node: ast.Constant) -> ConstMonad: ...
        def postBytes(translator, node: ast.Constant) -> ConstMonad: ...
    else:
        def postNameConstant(translator, node: ast.NameConstant): ...
        def postNum(translator, node: ast.Num) -> ConstMonad: ...
        def postStr(translator, node: ast.Str) -> ConstMonad: ...
        def postBytes(translator, node: ast.Bytes) -> ConstMonad: ...

    def postList(translator, node: ast.List) -> ListMonad: ...
    def postTuple(translator, node: ast.Tuple) -> ListMonad: ...
    def postName(translator, node: ast.Name) -> Monad: ...
    def resolve_name(translator, name) -> Monad: ...
    def postAdd(translator, node: ast.Add): ...
    def postSub(translator, node: ast.Sub): ...
    def postMult(translator, node: ast.Mult): ...
    def postMatMult(translator, node: ast.MatMult) -> NoReturn: ...
    def postDiv(translator, node: ast.Div): ...
    def postFloorDiv(translator, node: ast.FloorDiv): ...
    def postMod(translator, node: ast.Mod): ...
    def postLShift(translator, node: ast.LShift) -> NoReturn: ...
    def postRShift(translator, node: ast.RShift) -> NoReturn: ...
    def postPow(translator, node: ast.Pow): ...
    def postUSub(translator, node: ast.USub): ...
    def postAttribute(translator, node: ast.Attribute): ...
    def postAnd(translator, node: ast.And) -> AndMonad: ...
    def postOr(translator, node: ast.Or) -> OrMonad: ...
    def postBitOr(translator, node: ast.BitOr): ...
    def postBitAnd(translator, node: ast.BitAnd): ...
    def postBitXor(translator, node: ast.BitXor): ...
    def postNot(translator, node: ast.Not): ...
    def preCall(translator, node: ast.Call): ...
    def postCall(translator, node: ast.Call): ...
    def postkeyword(translator, node: ast.keyword) -> None: ...
    def postSubscript(translator, node: ast.Subscript): ...
    def postSlice(translator, node: ast.Slice) -> None: ...
    def postIndex(translator, node: ast.Index): ...
    def postIfExp(translator, node: ast.IfExp) -> ExprMonad: ...
    def postJoinedStr(translator, node: ast.JoinedStr) -> StringExprMonad: ...
    def postFormattedValue(translator, node: ast.FormattedValue): ...

def combine_limit_and_offset(limit, offset, limit2, offset2) -> tuple[Incomplete, Incomplete]: ...
def coerce_monads(m1, m2, for_comparison: bool = False): ...

max_alias_length: int

class SqlQuery:
    translator: Incomplete
    parent_sqlquery: SqlQuery | None
    left_join: bool
    from_ast: list[Incomplete]
    conditions: list[Incomplete]
    outer_conditions: list[Incomplete]
    tablerefs: dict[Incomplete, Incomplete]
    alias_counters: dict[Incomplete, Incomplete]
    expr_counter: itertools.count[int]
    used_from_subquery: bool
    def __init__(sqlquery, translator, parent_sqlquery: SqlQuery | None = None, left_join: bool = False) -> None: ...
    def get_tableref(sqlquery, name_path): ...
    def add_tableref(sqlquery, name_path, parent_tableref, attr) -> JoinedTableRef: ...
    def make_alias(sqlquery, name: str) -> str: ...
    def join_table(sqlquery, parent_alias, alias, table_name, join_cond) -> None: ...

class TableRef:
    sqlquery: SqlQuery
    alias: str
    name_path: str
    entity: Incomplete
    joined: bool
    can_affect_distinct: bool
    used_attrs: set[Incomplete]
    def __init__(tableref, sqlquery: SqlQuery, name: str, entity) -> None: ...
    def make_join(tableref, pk_only: bool = False) -> tuple[str, Incomplete]: ...

class ExprTableRef(TableRef):
    def __init__(tableref, sqlquery: SqlQuery, name: str, subquery_ast, expr_names, expr_aliases) -> None: ...
    def make_join(tableref, pk_only: bool = False) -> tuple[str, Incomplete]: ...

class StarTableRef(TableRef):
    def __init__(tableref, sqlquery: SqlQuery, name: str, entity, subquery_ast) -> None: ...
    def make_join(tableref, pk_only: bool = False) -> tuple[str, Incomplete]: ...

class ExprJoinedTableRef:
    def __init__(tableref, sqlquery: SqlQuery, parent_tableref, parent_columns, name, entity) -> None: ...
    def make_join(tableref, pk_only: bool = False) -> tuple[str, Incomplete]: ...

class JoinedTableRef:
    sqlquery: SqlQuery
    name_path: str
    var_name: str | None
    alias: str | None
    optimized: bool | None
    parent_tableref: Incomplete
    attr: Incomplete
    entity: Incomplete
    joined: bool
    can_affect_distinct: bool
    used_attrs: set[Incomplete]
    def __init__(tableref, sqlquery: SqlQuery, name_path: str, parent_tableref, attr) -> None: ...
    def make_join(tableref, pk_only: bool = False) -> tuple[str, Incomplete]: ...

def wrap_monad_method(cls_name: str, func: types.FunctionType): ...

class MonadMeta(type):
    def __new__(meta, cls_name: str, bases: tuple[type, ...], cls_dict: dict[str, Any]): ...

class MonadMixin(metaclass=MonadMeta): ...

class Monad(metaclass=MonadMeta):
    disable_distinct: ClassVar[bool]
    disable_ordering: ClassVar[bool]
    node: Incomplete
    translator: SQLTranslator
    type: Incomplete
    nullable: bool
    def __init__(monad, type, nullable: bool = True) -> None: ...
    def mixin_init(monad) -> None: ...
    def to_single_cell_value(monad): ...
    def cmp(monad, op, monad2): ...
    def contains(monad, item, not_in: bool = False) -> None: ...
    def nonzero(monad): ...
    def negate(monad): ...
    def getattr(monad, attrname): ...
    def len(monad) -> None: ...
    def count(monad, distinct=None): ...
    def aggregate(monad, func_name, distinct=None, sep=None): ...
    def __call__(monad, *args, **kwargs) -> None: ...
    def __getitem__(monad, key) -> None: ...
    def __add__(monad, monad2) -> None: ...
    def __sub__(monad, monad2) -> None: ...
    def __mul__(monad, monad2) -> None: ...
    def __truediv__(monad, monad2) -> None: ...
    def __floordiv__(monad, monad2) -> None: ...
    def __pow__(monad, monad2) -> None: ...
    def __neg__(monad) -> None: ...
    def __or__(monad, monad2) -> None: ...
    def __and__(monad, monad2) -> None: ...
    def __xor__(monad, monad2) -> None: ...
    def abs(monad) -> None: ...
    def cast_from_json(monad, type) -> None: ...
    def to_int(monad): ...
    def to_str(monad): ...
    def to_real(monad): ...

def distinct_from_monad(distinct, default=None): ...

class RawSQLMonad(Monad):
    def __init__(monad, rawtype, varkey, nullable: bool = True) -> None: ...
    def contains(monad, item, not_in: bool = False): ...
    def nonzero(monad): ...
    def getsql(monad, sqlquery=None): ...

typeerror_re_1: re.Pattern[str]
typeerror_re_2: re.Pattern[str]

def reraise_improved_typeerror(exc: Exception, func_name: str | tuple[str, ...], orig_func_name: str) -> NoReturn: ...
def raise_forgot_parentheses(monad: Monad) -> NoReturn: ...

class MethodMonad(Monad):
    def __init__(monad, parent, attrname) -> None: ...
    def getattr(monad, attrname) -> None: ...
    def __call__(monad, *args, **kwargs): ...
    def contains(monad, item, not_in: bool = False) -> None: ...
    def nonzero(monad) -> None: ...
    def negate(monad) -> None: ...
    def aggregate(monad, func_name, distinct=None, sep=None) -> None: ...
    def __getitem__(monad, key) -> None: ...
    def __add__(monad, monad2) -> None: ...
    def __sub__(monad, monad2) -> None: ...
    def __mul__(monad, monad2) -> None: ...
    def __truediv__(monad, monad2) -> None: ...
    def __floordiv__(monad, monad2) -> None: ...
    def __pow__(monad, monad2) -> None: ...
    def __neg__(monad) -> None: ...
    def abs(monad) -> None: ...

class EntityMonad(Monad):
    def __init__(monad, entity) -> None: ...
    def __getitem__(monad, *args) -> None: ...

class ListMonad(Monad):
    def __init__(monad, items) -> None: ...
    def contains(monad, x, not_in: bool = False): ...
    def getsql(monad, sqlquery=None): ...

class BufferMixin(MonadMixin): ...
class UuidMixin(MonadMixin): ...

def make_numeric_binop(op, sqlop): ...

class NumericMixin(MonadMixin):
    def mixin_init(monad) -> None: ...
    __add__: Incomplete
    __sub__: Incomplete
    __mul__: Incomplete
    __truediv__: Incomplete
    __floordiv__: Incomplete
    __mod__: Incomplete
    __and__: Incomplete
    __or__: Incomplete
    __xor__: Incomplete
    def __pow__(monad, monad2): ...
    def __neg__(monad): ...
    def abs(monad): ...
    def nonzero(monad): ...
    def negate(monad): ...

def numeric_attr_factory(name): ...
def make_datetime_binop(op, sqlop): ...

class DateMixin(MonadMixin):
    def mixin_init(monad) -> None: ...
    attr_year: Incomplete
    attr_month: Incomplete
    attr_day: Incomplete
    def __add__(monad, other): ...
    def __sub__(monad, other): ...

class TimeMixin(MonadMixin):
    def mixin_init(monad) -> None: ...
    attr_hour: Incomplete
    attr_minute: Incomplete
    attr_second: Incomplete

class TimedeltaMixin(MonadMixin):
    def mixin_init(monad) -> None: ...

class DatetimeMixin(DateMixin):
    def mixin_init(monad) -> None: ...
    def call_date(monad): ...
    attr_hour: Incomplete
    attr_minute: Incomplete
    attr_second: Incomplete
    def __add__(monad, other): ...
    def __sub__(monad, other): ...

def make_string_binop(op, sqlop): ...
def make_string_func(sqlop): ...

class StringMixin(MonadMixin):
    def mixin_init(monad) -> None: ...
    __add__: Incomplete
    def __getitem__(monad, index): ...
    def negate(monad): ...
    def nonzero(monad): ...
    def len(monad): ...
    def contains(monad, item, not_in: bool = False): ...
    call_upper: Incomplete
    call_lower: Incomplete
    def call_startswith(monad, arg): ...
    def call_endswith(monad, arg): ...
    def strip(monad, chars, strip_type): ...
    def call_strip(monad, chars=None): ...
    def call_lstrip(monad, chars=None): ...
    def call_rstrip(monad, chars=None): ...

class JsonMixin:
    disable_distinct: ClassVar[bool]
    disable_ordering: ClassVar[bool]
    def mixin_init(monad) -> None: ...
    def get_path(monad): ...
    def __getitem__(monad, key): ...
    def contains(monad, key, not_in: bool = False): ...
    def __or__(monad, other): ...
    def len(monad): ...
    def cast_from_json(monad, type): ...
    def nonzero(monad): ...

class ArrayMixin(MonadMixin):
    def contains(monad, key, not_in: bool = False): ...
    def len(monad): ...
    def nonzero(monad): ...
    def __getitem__(monad, index): ...

class ObjectMixin(MonadMixin):
    def mixin_init(monad) -> None: ...
    def negate(monad): ...
    def nonzero(monad): ...
    def getattr(monad, attrname): ...
    def requires_distinct(monad, joined: bool = False): ...

class ObjectIterMonad(ObjectMixin, Monad):
    def __init__(monad, tableref, entity) -> None: ...
    def getsql(monad, sqlquery=None): ...
    def requires_distinct(monad, joined: bool = False): ...

class AttrMonad(Monad):
    @staticmethod
    def new(parent, attr, *args, **kwargs) -> AttrMonad: ...
    def __new__(cls, parent, attr): ...
    def __init__(monad, parent, attr) -> None: ...
    def getsql(monad, sqlquery=None): ...

class ObjectAttrMonad(ObjectMixin, AttrMonad):
    def __init__(monad, parent, attr) -> None: ...

class StringAttrMonad(StringMixin, AttrMonad): ...
class NumericAttrMonad(NumericMixin, AttrMonad): ...
class DateAttrMonad(DateMixin, AttrMonad): ...
class TimeAttrMonad(TimeMixin, AttrMonad): ...
class TimedeltaAttrMonad(TimedeltaMixin, AttrMonad): ...
class DatetimeAttrMonad(DatetimeMixin, AttrMonad): ...
class BufferAttrMonad(BufferMixin, AttrMonad): ...
class UuidAttrMonad(UuidMixin, AttrMonad): ...
class JsonAttrMonad(JsonMixin, AttrMonad): ...
class ArrayAttrMonad(ArrayMixin, AttrMonad): ...

class ParamMonad(Monad):
    @staticmethod
    def new(t, paramkey) -> ParamMonad: ...
    def __new__(cls, *args, **kwargs): ...
    def __init__(monad, t, paramkey) -> None: ...
    def getsql(monad, sqlquery=None): ...

class ObjectParamMonad(ObjectMixin, ParamMonad):
    def __init__(monad, entity, paramkey) -> None: ...
    def getsql(monad, sqlquery=None): ...
    def requires_distinct(monad, joined: bool = False) -> None: ...

class StringParamMonad(StringMixin, ParamMonad): ...
class NumericParamMonad(NumericMixin, ParamMonad): ...
class DateParamMonad(DateMixin, ParamMonad): ...
class TimeParamMonad(TimeMixin, ParamMonad): ...
class TimedeltaParamMonad(TimedeltaMixin, ParamMonad): ...
class DatetimeParamMonad(DatetimeMixin, ParamMonad): ...
class BufferParamMonad(BufferMixin, ParamMonad): ...
class UuidParamMonad(UuidMixin, ParamMonad): ...

class ArrayParamMonad(ArrayMixin, ParamMonad):
    def __init__(monad, t, paramkey, list_monad=None) -> None: ...
    def contains(monad, key, not_in: bool = False): ...

class JsonParamMonad(JsonMixin, ParamMonad):
    def getsql(monad, sqlquery=None): ...

class ExprMonad(Monad):
    @staticmethod
    def new(t, sql, nullable: bool = True) -> ExprMonad: ...
    def __new__(cls, *args, **kwargs): ...
    def __init__(monad, type, sql, nullable: bool = True) -> None: ...
    def getsql(monad, sqlquery=None): ...

class ObjectExprMonad(ObjectMixin, ExprMonad):
    def getsql(monad, sqlquery=None): ...

class StringExprMonad(StringMixin, ExprMonad): ...
class NumericExprMonad(NumericMixin, ExprMonad): ...
class DateExprMonad(DateMixin, ExprMonad): ...
class TimeExprMonad(TimeMixin, ExprMonad): ...
class TimedeltaExprMonad(TimedeltaMixin, ExprMonad): ...
class DatetimeExprMonad(DatetimeMixin, ExprMonad): ...
class JsonExprMonad(JsonMixin, ExprMonad): ...
class ArrayExprMonad(ArrayMixin, ExprMonad): ...

class JsonItemMonad(JsonMixin, Monad):
    def __init__(monad, parent, key) -> None: ...
    def get_path(monad): ...
    def to_int(monad): ...
    def to_str(monad): ...
    def to_real(monad): ...
    def cast_from_json(monad, type): ...
    def getsql(monad): ...

class ConstMonad(Monad):
    @staticmethod
    def new(value) -> ConstMonad: ...
    def __new__(cls, value): ...
    def __init__(monad, value) -> None: ...
    def getsql(monad, sqlquery=None): ...

class NoneMonad(ConstMonad):
    type = NoneType
    def __new__(cls, value=None): ...
    def __init__(monad, value=None) -> None: ...
    def cmp(monad, op, monad2): ...
    def contains(monad, item, not_in: bool = False): ...
    def nonzero(monad): ...
    def negate(monad): ...
    def getattr(monad, attrname): ...
    def len(monad): ...
    def count(monad, distinct=None): ...
    def aggregate(monad, func_name, distinct=None, sep=None): ...
    def __call__(monad, *args, **kwargs): ...
    def __getitem__(monad, key): ...
    def __add__(monad, monad2): ...
    def __sub__(monad, monad2): ...
    def __mul__(monad, monad2): ...
    def __truediv__(monad, monad2): ...
    def __floordiv__(monad, monad2): ...
    def __pow__(monad, monad2): ...
    def __neg__(monad): ...
    def __or__(monad, monad2): ...
    def __and__(monad, monad2): ...
    def __xor__(monad, monad2): ...
    def abs(monad): ...
    def to_int(monad): ...
    def to_str(monad): ...
    def to_real(monad): ...

class EllipsisMonad(ConstMonad): ...

class StringConstMonad(StringMixin, ConstMonad):
    def len(monad): ...

class JsonConstMonad(JsonMixin, ConstMonad): ...
class BufferConstMonad(BufferMixin, ConstMonad): ...
class NumericConstMonad(NumericMixin, ConstMonad): ...
class DateConstMonad(DateMixin, ConstMonad): ...
class TimeConstMonad(TimeMixin, ConstMonad): ...
class TimedeltaConstMonad(TimedeltaMixin, ConstMonad): ...
class DatetimeConstMonad(DatetimeMixin, ConstMonad): ...

class BoolMonad(Monad):
    def __init__(monad, nullable: bool = True) -> None: ...
    def nonzero(monad): ...

sql_negation: dict[str, str]

class BoolExprMonad(BoolMonad):
    def __init__(monad, sql, nullable: bool = True) -> None: ...
    def getsql(monad, sqlquery=None): ...
    def negate(monad): ...

cmp_ops: dict[str, str]
cmp_negate: dict[str, str]

class CmpMonad(BoolMonad):
    EQ: str
    NE: str
    def __init__(monad, op: str, left, right) -> None: ...
    def negate(monad): ...
    def getsql(monad, sqlquery=None): ...

class LogicalBinOpMonad(BoolMonad):
    def __init__(monad, operands) -> None: ...
    def getsql(monad, sqlquery=None): ...

class AndMonad(LogicalBinOpMonad):
    binop: str

class OrMonad(LogicalBinOpMonad):
    binop: str

class NotMonad(BoolMonad):
    def __init__(monad, operand) -> None: ...
    def negate(monad): ...
    def getsql(monad, sqlquery=None): ...

class HybridFuncMonad(Monad):
    def __init__(monad, func_type, func_name, *params) -> None: ...
    def __call__(monad, *args, **kwargs): ...

class HybridMethodMonad(HybridFuncMonad):
    def __init__(monad, parent, attrname, func) -> None: ...

registered_functions: dict[types.FunctionType, type[FuncMonad]]

class FuncMonadMeta(MonadMeta):
    def __new__(meta, cls_name: str, bases: tuple[type, ...], cls_dict: dict[str, Any]): ...

class FuncMonad(Monad, metaclass=FuncMonadMeta):
    def __call__(monad, *args, **kwargs): ...

def get_classes(classinfo) -> Generator[Incomplete]: ...

class FuncIsinstanceMonad(FuncMonad):
    func = isinstance
    def call(monad, obj, classinfo): ...

class FuncBufferMonad(FuncMonad):
    func: type[bytes]
    def call(monad, source, encoding=None, errors=None): ...

class FuncBoolMonad(FuncMonad):
    func: type[bool]
    def call(monad, x): ...

class FuncIntMonad(FuncMonad):
    func: type[int]
    def call(monad, x): ...

class FuncStrMonad(FuncMonad):
    func: type[str]
    def call(monad, x): ...

class FuncFloatMonad(FuncMonad):
    func: type[float]
    def call(monad, x): ...

class FuncDecimalMonad(FuncMonad):
    func: type[Decimal]
    def call(monad, x): ...

class FuncDateMonad(FuncMonad):
    func: type[date]
    def call(monad, year, month, day): ...
    def call_today(monad): ...

class FuncTimeMonad(FuncMonad):
    func: type[time]
    def call(monad, *args): ...

class FuncTimedeltaMonad(FuncMonad):
    func: type[timedelta]
    def call(monad, days=None, seconds=None, microseconds=None, milliseconds=None, minutes=None, hours=None, weeks=None): ...

class FuncDatetimeMonad(FuncDateMonad):
    func: type[datetime]
    def call(monad, year, month, day, hour=None, minute=None, second=None, microsecond=None): ...
    def call_now(monad): ...

class FuncBetweenMonad(FuncMonad):
    func = between
    def call(monad, x, a, b): ...

class FuncConcatMonad(FuncMonad):
    func = concat
    def call(monad, *args): ...

class FuncLenMonad(FuncMonad):
    func = len
    def call(monad, x): ...

class FuncGetattrMonad(FuncMonad):
    func = getattr
    def call(monad, obj_monad, name_monad): ...

class FuncRawSQLMonad(FuncMonad):
    func = raw_sql
    def call(monad, *args) -> None: ...

class FuncCountMonad(FuncMonad):
    func: Incomplete
    def call(monad, x=None, distinct=None): ...

class FuncAbsMonad(FuncMonad):
    func = abs
    def call(monad, x): ...

class FuncSumMonad(FuncMonad):
    func: Incomplete
    def call(monad, x, distinct=None): ...

class FuncAvgMonad(FuncMonad):
    func: Incomplete
    def call(monad, x, distinct=None): ...

class FuncGroupConcatMonad(FuncMonad):
    func: Incomplete
    def call(monad, x, sep=None, distinct=None): ...

class FuncCoalesceMonad(FuncMonad):
    func = coalesce
    def call(monad, *args): ...

class FuncDistinctMonad(FuncMonad):
    func: Incomplete
    def call(monad, x): ...

class FuncMinMonad(FuncMonad):
    func: Incomplete
    def call(monad, *args): ...

class FuncMaxMonad(FuncMonad):
    func: Incomplete
    def call(monad, *args): ...

def minmax(monad, sqlop, *args): ...

class FuncSelectMonad(FuncMonad):
    func = core.select
    def call(monad, queryset): ...

class FuncExistsMonad(FuncMonad):
    func = core.exists
    def call(monad, arg): ...

class FuncDescMonad(FuncMonad):
    func = core.desc
    def call(monad, expr): ...

class DescMonad(Monad):
    def __init__(monad, expr) -> None: ...
    def getsql(monad): ...

class JoinMonad(Monad):
    def __init__(monad, type) -> None: ...
    def __call__(monad, x): ...

class FuncRandomMonad(FuncMonad):
    func = random
    def __init__(monad, type) -> None: ...
    def __call__(monad): ...

class SetMixin(MonadMixin):
    forced_distinct: bool
    def call_distinct(monad): ...

def make_attrset_binop(op, sqlop): ...

class AttrSetMonad(SetMixin, Monad):
    def __init__(monad, parent, attr) -> None: ...
    def cmp(monad, op, monad2) -> None: ...
    def contains(monad, item, not_in: bool = False): ...
    def getattr(monad, name): ...
    def call_select(monad): ...
    call_filter = call_select
    def call_exists(monad): ...
    def requires_distinct(monad, joined: bool = False, for_count: bool = False): ...
    def count(monad, distinct=None): ...
    len = count
    def aggregate(monad, func_name, distinct=None, sep=None): ...
    def nonzero(monad): ...
    def negate(monad): ...
    call_is_empty = negate
    def make_tableref(monad, sqlquery): ...
    def make_expr_list(monad): ...
    def getsql(monad, sqlquery=None): ...
    __add__: Incomplete
    __sub__: Incomplete
    __mul__: Incomplete
    __truediv__: Incomplete
    __floordiv__: Incomplete

def make_numericset_binop(op, sqlop): ...

class NumericSetExprMonad(SetMixin, Monad):
    def __init__(monad, op, sqlop, left, right) -> None: ...
    def aggregate(monad, func_name, distinct=None, sep=None): ...
    def getsql(monad, sqlquery=None): ...
    __add__: Incomplete
    __sub__: Incomplete
    __mul__: Incomplete
    __truediv__: Incomplete
    __floordiv__: Incomplete

class QuerySetMonad(SetMixin, Monad):
    nogroup: bool
    def __init__(monad, subtranslator) -> None: ...
    def to_single_cell_value(monad): ...
    def requires_distinct(monad, joined: bool = False) -> None: ...
    def call_limit(monad, limit=None, offset=None): ...
    def contains(monad, item, not_in: bool = False): ...
    def nonzero(monad): ...
    def negate(monad): ...
    def count(monad, distinct=None): ...
    len = count
    def aggregate(monad, func_name, distinct=None, sep=None): ...
    def call_count(monad, distinct=None): ...
    def call_sum(monad, distinct=None): ...
    def call_min(monad): ...
    def call_max(monad): ...
    def call_avg(monad, distinct=None): ...
    def call_group_concat(monad, sep=None, distinct=None): ...
    def getsql(monad): ...

def find_or_create_having_ast(sections: list[Sequence[str]]): ...
