class Number(metaclass=ABCMeta): """All numbers inherit from this class.
If you just want to check if an argument x is a number, without caring what kind, use isinstance(x, Number). """ __slots__ = ()
# Concrete numeric types must provide their own hash implementation __hash__ = None
## Notes on Decimal ## ---------------- ## Decimal has all of the methods specified by the Real abc, but it should ## not be registered as a Real because decimals do not interoperate with ## binary floats (i.e. Decimal('3.14') + 2.71828 is undefined). But, ## abstract reals are expected to interoperate (i.e. R1 + R2 should be ## expected to work if R1 and R2 are both Reals).
class Complex(Number): """Complex defines the operations that work on the builtin complex type.
In short, those are: a conversion to complex, .real, .imag, +, -, *, /, abs(), .conjugate, ==, and !=.
If it is given heterogenous arguments, and doesn't have special knowledge about them, it should fall back to the builtin complex type as described below. """
__slots__ = ()
@abstractmethod def __complex__(self): """Return a builtin complex instance. Called for complex(self)."""
def __bool__(self): """True if self != 0. Called for bool(self).""" return self != 0
@property @abstractmethod def real(self): """Retrieve the real component of this number.
This should subclass Real. """ raise NotImplementedError
@property @abstractmethod def imag(self): """Retrieve the imaginary component of this number.
This should subclass Real. """ raise NotImplementedError
class Real(Complex): """To Complex, Real adds the operations that work on real numbers.
In short, those are: a conversion to float, trunc(), divmod, %, <, <=, >, and >=.
Real also provides defaults for the derived operations. """
__slots__ = ()
@abstractmethod def __float__(self): """Any Real can be converted to a native float object.
Called for float(self).""" raise NotImplementedError
@abstractmethod def __trunc__(self): """trunc(self): Truncates self to an Integral.
Returns an Integral i such that: * i>0 iff self>0; * abs(i) <= abs(self); * for any Integral j satisfying the first two conditions, abs(i) >= abs(j) [i.e. i has "maximal" abs among those]. i.e. "truncate towards 0". """ raise NotImplementedError
@abstractmethod def __floor__(self): """Finds the greatest Integral <= self.""" raise NotImplementedError
@abstractmethod def __ceil__(self): """Finds the least Integral >= self.""" raise NotImplementedError
@abstractmethod def __round__(self, ndigits=None): """Rounds self to ndigits decimal places, defaulting to 0.
If ndigits is omitted or None, returns an Integral, otherwise returns a Real. Rounds half toward even. """ raise NotImplementedError
# Concrete implementation of Real's conversion to float. def __float__(self): """float(self) = self.numerator / self.denominator
It's important that this conversion use the integer's "true" division rather than casting one side to float before dividing so that ratios of huge integers convert without overflowing.
""" return self.numerator / self.denominator
class Integral(Rational): """Integral adds a conversion to int and the bit-string operations."""
Accept the modulus argument if you want to support the 3-argument version of pow(). Raise a TypeError if exponent < 0 or any argument isn't Integral. Otherwise, just implement the 2-argument version described in Complex. """ raise NotImplementedError