from collections.abc import Iterator
from typing import Any, Callable, Literal
from typing_extensions import Self

from sympy.core.basic import Basic
from sympy.core.expr import Atom, Expr
from sympy.core.function import UndefinedFunction
from sympy.core.numbers import Float, Integer

class CodegenAST(Basic):
    __slots__ = ...

class Token(CodegenAST):
    __slots__: tuple[str, ...] = ...
    _fields = ...
    defaults: dict[str, Any] = ...
    not_in_args: list[str] = ...
    indented_args = ...
    @property
    def is_Atom(self) -> bool: ...
    def __new__(cls, *args, **kwargs) -> Self: ...
    def __eq__(self, other) -> bool: ...
    def __hash__(self) -> int: ...

    _sympystr = ...
    def __repr__(self): ...
    def kwargs(self, exclude=..., apply=...) -> dict[Any, Any]: ...

class BreakToken(Token): ...

break_ = ...

class ContinueToken(Token): ...

continue_ = ...

class NoneToken(Token):
    def __eq__(self, other) -> bool: ...
    def __hash__(self) -> int: ...

none = ...

class AssignmentBase(CodegenAST):
    def __new__(cls, lhs, rhs) -> Self: ...
    @property
    def lhs(self) -> Basic: ...
    @property
    def rhs(self) -> Basic: ...

class Assignment(AssignmentBase):
    op = ...

class AugmentedAssignment(AssignmentBase):
    binop: str = ...
    @property
    def op(self) -> str: ...

class AddAugmentedAssignment(AugmentedAssignment):
    binop = ...

class SubAugmentedAssignment(AugmentedAssignment):
    binop = ...

class MulAugmentedAssignment(AugmentedAssignment):
    binop = ...

class DivAugmentedAssignment(AugmentedAssignment):
    binop = ...

class ModAugmentedAssignment(AugmentedAssignment):
    binop = ...

augassign_classes = ...

def aug_assign(lhs, op, rhs): ...

class CodeBlock(CodegenAST):
    def __new__(cls, *args) -> Self: ...
    def __iter__(self) -> Iterator[Basic]: ...

    _sympystr = ...
    @property
    def free_symbols(self) -> set[Basic]: ...
    @classmethod
    def topological_sort(cls, assignments) -> Self: ...
    def cse(self, symbols=..., optimizations=..., postprocess=..., order=...) -> Self: ...

class For(Token):
    _fields = ...
    _construct_target = ...

class String(Atom, Token):
    _fields = ...
    not_in_args = ...
    is_Atom = ...
    def kwargs(self, exclude=..., apply=...) -> dict[Any, Any]: ...
    @property
    def func(self) -> Callable[[], Self]: ...

class QuotedString(String): ...
class Comment(String): ...

class Node(Token):
    __slots__: tuple[str, ...] = ...
    _fields = ...
    defaults: dict[str, Any] = ...
    _construct_attrs = ...
    def attr_params(self, looking_for) -> None: ...

class Type(Token):
    __slots__: tuple[str, ...] = ...
    _fields = ...
    _construct_name = String
    @classmethod
    def from_expr(cls, expr) -> FloatBaseType | IntBaseType | ComplexBaseType | Type: ...
    def cast_check(self, value, rtol=..., atol=..., precision_targets=...): ...

class IntBaseType(Type):
    __slots__ = ...
    cast_nocheck = ...

class _SizedIntType(IntBaseType):
    __slots__ = ...
    _fields = ...
    _construct_nbits = Integer

class SignedIntType(_SizedIntType):
    __slots__ = ...
    @property
    def min(self) -> Any: ...
    @property
    def max(self) -> Any: ...

class UnsignedIntType(_SizedIntType):
    __slots__ = ...
    @property
    def min(self) -> Literal[0]: ...
    @property
    def max(self) -> Literal[0]: ...

two = ...

class FloatBaseType(Type):
    __slots__ = ...
    cast_nocheck = Float

class FloatType(FloatBaseType):
    __slots__ = ...
    _fields = ...
    _construct_nexp = Integer
    _construct_nmant = Integer
    _construct_nbits = Integer
    @property
    def max_exponent(self) -> Expr: ...
    @property
    def min_exponent(self): ...
    @property
    def max(self): ...
    @property
    def tiny(self): ...
    @property
    def eps(self): ...
    @property
    def dig(self) -> type[UndefinedFunction]: ...
    @property
    def decimal_dig(self) -> type[UndefinedFunction]: ...
    def cast_nocheck(self, value) -> float | Float: ...

class ComplexBaseType(FloatBaseType):
    __slots__ = ...
    def cast_nocheck(self, value) -> Float: ...

class ComplexType(ComplexBaseType, FloatType):
    __slots__ = ...

intc = ...
intp = ...
int8 = ...
int16 = ...
int32 = ...
int64 = ...
uint8 = ...
uint16 = ...
uint32 = ...
uint64 = ...
float16 = ...
float32 = ...
float64 = ...
float80 = ...
float128 = ...
float256 = ...
complex64 = ...
complex128 = ...
untyped = ...
real = ...
integer = ...
complex_ = ...
bool_ = ...

class Attribute(Token):
    _fields = ...
    defaults = ...
    _construct_name = String
    _construct_parameters = ...

value_const = ...
pointer_const = ...

class Variable(Node):
    __slots__ = ...
    _fields = ...
    defaults = ...
    _construct_symbol = ...
    _construct_value = ...
    @classmethod
    def deduced(cls, symbol, value=..., attrs=..., cast_check=...) -> Variable | Self: ...
    def as_Declaration(self, **kwargs) -> Declaration: ...

    __lt__ = ...
    __le__ = ...
    __ge__ = ...
    __gt__ = ...

class Pointer(Variable):
    __slots__ = ...
    def __getitem__(self, key) -> Element: ...

class Element(Token):
    _fields = ...
    defaults = ...
    _construct_symbol = ...
    _construct_indices = ...
    _construct_strides = ...
    _construct_offset = ...

class Declaration(Token):
    _fields = ...
    _construct_variable = Variable

class While(Token):
    _fields = ...
    _construct_condition = ...

class Scope(Token):
    _fields = ...

class Stream(Token):
    _fields = ...
    _construct_name = String

stdout = ...
stderr = ...

class Print(Token):
    _fields = ...
    defaults = ...
    _construct_print_args = ...
    _construct_format_string = QuotedString
    _construct_file = Stream

class FunctionPrototype(Node):
    __slots__ = ...
    _fields: tuple[str, ...] = ...
    _construct_return_type = Type
    _construct_name = String
    @classmethod
    def from_FunctionDefinition(cls, func_def) -> Self: ...

class FunctionDefinition(FunctionPrototype):
    __slots__ = ...
    _fields = ...
    @classmethod
    def from_FunctionPrototype(cls, func_proto, body) -> Self: ...

class Return(Token):
    _fields = ...
    _construct_return = ...

class FunctionCall(Token, Expr):
    _fields = ...
    _construct_name = String
    _construct_function_args = ...
