import numbers
from typing import Generic, TypeVar
from typing import Any, Callable, Union

from .dimensions import Dimensions
from .units import SIUnit, _Q

_T = TypeVar("_T")

def make(quantity: Union[_Q, _T], SIUnit) -> _Q: ...
def converter(units: SIUnit) -> Callable[[Any], _Q]: ...
def is_of(dimensions: Dimensions) -> Callable[[_Q], bool]: ...

class Quantity(Generic[_T]):
    quantity: _T
    units: SIUnit
    def __init__(self, quantity: Union[_Q, _T], units: SIUnit) -> None: ...
    def is_of(self, dimensions: Dimensions) -> bool: ...
    def get_as(self, units: SIUnit) -> _T: ...
    def cvt_to(self, units: SIUnit) -> _Q: ...
    def compatible(self, other: Quantity) -> bool: ...
    def __add__(self, other: _Q) -> _Q: ...
    def __iadd__(self, other: _Q) -> _Q: ...
    def __sub__(self, other: _Q) -> _Q: ...
    def __isub__(self, other: _Q) -> _Q: ...
    def __mul__(self, other: Any) -> _Q: ...
    def __imul__(self, other: Any) -> _Q: ...
    def __rmul__(self, other: Any) -> _Q: ...
    def __truediv__(self, other: Any) -> _Q: ...
    def __itruediv__(self, other: Any) -> _Q: ...
    def __rtruediv__(self, other: Any) -> _Q: ...
    def __pow__(self, other: numbers.Real) -> _Q: ...
    def __invert__(self) -> _Q: ...
    def __abs__(self) -> _Q: ...
    def __neg__(self) -> _Q: ...
    def __eq__(self, other: Any) -> bool: ...
    def __ne__(self, other: Any) -> bool: ...
    def __lt__(self, other: Quantity[Any]) -> bool: ...
    def __le__(self, other: Quantity[Any]) -> bool: ...
    def __gt__(self, other: Quantity[Any]) -> bool: ...
    def __ge__(self, other: Quantity[Any]) -> bool: ...
    def __str__(self) -> str: ...
    def __repr__(self) -> str: ...
