from __future__ import annotations

from numbers import Rational as _Rational
from typing import TYPE_CHECKING, overload as _overload

from typing_extensions import Any as _Any, Self as _Self, final as _final

from .enums import Endianness as _Endianness, TieBreaking as _TieBreaking

if TYPE_CHECKING:

    @_final
    class Fraction:
        @property
        def numerator(self) -> Int: ...

        @property
        def denominator(self) -> Int: ...

        def round(self, tie_breaking: _TieBreaking, /) -> Int: ...

        __module__ = 'rithm.fraction'

        @_overload
        def __new__(
            cls, value: Int | _Rational | _Self | float | int = ..., /
        ) -> _Self: ...

        @_overload
        def __new__(
            cls, numerator: Int | int, denominator: Int | int, /
        ) -> _Self: ...

        def __new__(
            cls,
            numerator: _Self | Int | _Rational | float | int = ...,
            denominator: Int | int = ...,
            /,
        ) -> _Self: ...

        def __abs__(self, /) -> _Self: ...

        def __add__(self, other: _Self | Int | int, /) -> _Self: ...

        def __bool__(self, /) -> bool: ...

        def __ceil__(self, /) -> Int: ...

        def __divmod__(
            self, divisor: _Self | Int | int, /
        ) -> tuple[Int, _Self]: ...

        @_overload
        def __eq__(self, other: _Self | Int | int, /) -> bool: ...

        @_overload
        def __eq__(self, other: _Any, /) -> _Any: ...

        def __eq__(self, other: _Any, /) -> _Any: ...

        def __float__(self, /) -> float: ...

        def __floor__(self, /) -> Int: ...

        def __floordiv__(self, divisor: _Self | Int | int, /) -> Int: ...

        def __ge__(self, other: _Self | Int | int, /) -> bool: ...

        def __gt__(self, other: _Self | Int | int, /) -> bool: ...

        def __hash__(self, /) -> int: ...

        def __le__(self, other: _Self | Int | int, /) -> bool: ...

        def __lt__(self, other: _Self | Int | int, /) -> bool: ...

        def __mod__(self, divisor: _Self | Int | int, /) -> _Self: ...

        def __mul__(self, other: _Self | Int | int, /) -> _Self: ...

        def __neg__(self, /) -> _Self: ...

        def __pos__(self, /) -> _Self: ...

        def __pow__(
            self, exponent: Int | int, divisor: None = ..., /
        ) -> _Self: ...

        def __radd__(self, other: Int | int, /) -> _Self: ...

        def __rdivmod__(self, dividend: Int | int, /) -> tuple[Int, _Self]: ...

        def __reduce__(self, /) -> tuple[tuple[_Self], tuple[Int, Int]]: ...

        def __repr__(self, /) -> str: ...

        def __rfloordiv__(self, dividend: Int | int, /) -> Int: ...

        def __rmod__(self, dividend: Int | int, /) -> _Self: ...

        def __rmul__(self, other: Int | int, /) -> _Self: ...

        @_overload
        def __round__(self, digits: None = ..., /) -> Int: ...

        @_overload
        def __round__(self, digits: int, /) -> _Self: ...

        def __round__(self, digits: int | None = ..., /) -> _Self | Int: ...

        def __rsub__(self, subtrahend: Int | int, /) -> _Self: ...

        def __str__(self, /) -> str: ...

        def __sub__(self, minuend: _Self | Int | int, /) -> _Self: ...

        def __rtruediv__(self, dividend: Int | int, /) -> _Self: ...

        def __truediv__(self, divisor: _Self | Int | int, /) -> _Self: ...

        def __trunc__(self, /) -> Int: ...

    @_final
    class Int:
        @property
        def denominator(self, /) -> _Self: ...

        @property
        def numerator(self, /) -> _Self: ...

        def bit_length(self, /) -> _Self: ...

        def gcd(self, other: _Self, /) -> _Self: ...

        def is_power_of_two(self, /) -> bool: ...

        def to_bytes(self, endianness: _Endianness, /) -> bytes: ...

        @classmethod
        def from_bytes(
            cls, value: bytes, endianness: _Endianness, /
        ) -> _Self: ...

        __module__ = 'rithm.integer'

        @_overload
        def __new__(cls, value: _Self | float | int = ..., /) -> _Self: ...

        @_overload
        def __new__(cls, value: str, base: int | None = ..., /) -> _Self: ...

        def __new__(
            cls,
            value: _Self | float | int | str = ...,
            base: int | None = ...,
            /,
        ) -> _Self: ...

        def __abs__(self, /) -> _Self: ...

        def __add__(self, other: _Self | int, /) -> _Self: ...

        def __and__(self, other: _Self | int, /) -> _Self: ...

        def __bool__(self, /) -> bool: ...

        def __ceil__(self, /) -> _Self: ...

        def __divmod__(self, other: _Self | int, /) -> tuple[_Self, _Self]: ...

        @_overload
        def __eq__(self, other: _Self | int, /) -> bool: ...

        @_overload
        def __eq__(self, other: _Any, /) -> _Any: ...

        def __eq__(self, other: _Any, /) -> _Any: ...

        def __float__(self, /) -> float: ...

        def __floor__(self, /) -> _Self: ...

        def __floordiv__(self, other: _Self | int, /) -> _Self: ...

        def __ge__(self, other: _Self | int, /) -> bool: ...

        def __reduce__(self, /) -> tuple[tuple[_Self], tuple[int]]: ...

        def __gt__(self, other: _Self | int, /) -> bool: ...

        def __hash__(self, /) -> int: ...

        def __index__(self, /) -> int: ...

        def __int__(self, /) -> int: ...

        def __invert__(self, /) -> _Self: ...

        def __le__(self, other: _Self | int, /) -> bool: ...

        def __lshift__(self, other: _Self | int, /) -> _Self: ...

        def __lt__(self, other: _Self | int, /) -> bool: ...

        def __mod__(self, other: _Self | int, /) -> _Self: ...

        def __mul__(self, other: _Self | int, /) -> _Self: ...

        def __neg__(self, /) -> _Self: ...

        def __or__(self, other: _Self | int, /) -> _Self: ...

        def __pos__(self, /) -> _Self: ...

        def __pow__(
            self, exponent: _Self | int, divisor: _Self | None | int = ..., /
        ) -> Fraction | _Self: ...

        def __radd__(self, other: int, /) -> _Self: ...

        def __rand__(self, other: int, /) -> _Self: ...

        def __rdivmod__(self, other: int, /) -> tuple[_Self, _Self]: ...

        def __repr__(self, /) -> str: ...

        def __rfloordiv__(self, other: int, /) -> _Self: ...

        def __rlshift__(self, other: int, /) -> _Self: ...

        def __rmod__(self, other: int, /) -> _Self: ...

        def __rmul__(self, other: int, /) -> _Self: ...

        def __ror__(self, other: int, /) -> _Self: ...

        def __round__(self, digits: int | None = ..., /) -> _Self: ...

        def __rpow__(
            self, base: int, divisor: _Self | None | int = ..., /
        ) -> Fraction | _Self: ...

        def __rrshift__(self, other: int, /) -> _Self: ...

        def __rshift__(self, other: _Self | int, /) -> _Self: ...

        def __rsub__(self, other: int, /) -> _Self: ...

        def __rtruediv__(self, other: int, /) -> Fraction: ...

        def __rxor__(self, other: int, /) -> _Self: ...

        def __str__(self, /) -> str: ...

        def __sub__(self, other: _Self | int, /) -> _Self: ...

        def __truediv__(self, other: _Self | int, /) -> Fraction: ...

        def __trunc__(self, /) -> _Self: ...

        def __xor__(self, other: _Self | int, /) -> _Self: ...
