from types import NotImplementedType
from typing import Any
from typing_extensions import LiteralString

from sympy import Order
from sympy.core.add import Add
from sympy.core.basic import Basic
from sympy.core.expr import Expr
from sympy.core.mul import Mul
from sympy.core.numbers import Rational

_eps = ...

def decompose_power(expr: Expr) -> tuple[Expr, int]: ...
def decompose_power_rat(expr: Expr) -> tuple[Expr, Rational]: ...

class Factors:
    __slots__ = ...
    def __init__(self, factors=...) -> None: ...
    def __hash__(self) -> int: ...
    def __repr__(self) -> LiteralString: ...
    @property
    def is_zero(self) -> bool: ...
    @property
    def is_one(self) -> bool: ...
    def as_expr(self) -> Order: ...
    def mul(self, other) -> Factors: ...
    def normal(self, other) -> tuple[Factors, Factors]: ...
    def div(self, other) -> tuple[Factors, Factors]: ...
    def quo(self, other) -> Factors: ...
    def rem(self, other) -> Factors: ...
    def pow(self, other) -> Factors: ...
    def gcd(self, other) -> Factors: ...
    def lcm(self, other) -> Factors: ...
    def __mul__(self, other) -> Factors: ...
    def __divmod__(self, other) -> tuple[Factors, Factors]: ...
    def __truediv__(self, other) -> Factors: ...
    def __mod__(self, other) -> Factors: ...
    def __pow__(self, other) -> Factors: ...
    def __eq__(self, other) -> bool: ...
    def __ne__(self, other) -> bool: ...

class Term:
    __slots__ = ...
    def __init__(self, term, numer=..., denom=...) -> None: ...
    def __hash__(self) -> int: ...
    def as_expr(self): ...
    def mul(self, other) -> Term: ...
    def inv(self) -> Term: ...
    def quo(self, other) -> Term: ...
    def pow(self, other) -> Term: ...
    def gcd(self, other) -> Term: ...
    def lcm(self, other) -> Term: ...
    def __mul__(self, other) -> Term | NotImplementedType: ...
    def __truediv__(self, other) -> Term | NotImplementedType: ...
    def __pow__(self, other) -> Term | NotImplementedType: ...
    def __eq__(self, other) -> bool: ...
    def __ne__(self, other) -> bool: ...

def gcd_terms(terms, isprimitive=..., clear=..., fraction=...) -> Add | Order | Mul | Basic | dict: ...
def factor_terms(expr, radical=..., clear=..., fraction=..., sign=...) -> Basic | Any | Add | Order | Mul: ...
def factor_nc(expr) -> Expr | Any | Add | Order | Mul: ...
