(root)/
Python-3.12.0/
Lib/
numbers.py
       1  # Copyright 2007 Google, Inc. All Rights Reserved.
       2  # Licensed to PSF under a Contributor Agreement.
       3  
       4  """Abstract Base Classes (ABCs) for numbers, according to PEP 3141.
       5  
       6  TODO: Fill out more detailed documentation on the operators."""
       7  
       8  ############ Maintenance notes #########################################
       9  #
      10  # ABCs are different from other standard library modules in that they
      11  # specify compliance tests.  In general, once an ABC has been published,
      12  # new methods (either abstract or concrete) cannot be added.
      13  #
      14  # Though classes that inherit from an ABC would automatically receive a
      15  # new mixin method, registered classes would become non-compliant and
      16  # violate the contract promised by ``isinstance(someobj, SomeABC)``.
      17  #
      18  # Though irritating, the correct procedure for adding new abstract or
      19  # mixin methods is to create a new ABC as a subclass of the previous
      20  # ABC.
      21  #
      22  # Because they are so hard to change, new ABCs should have their APIs
      23  # carefully thought through prior to publication.
      24  #
      25  # Since ABCMeta only checks for the presence of methods, it is possible
      26  # to alter the signature of a method by adding optional arguments
      27  # or changing parameter names.  This is still a bit dubious but at
      28  # least it won't cause isinstance() to return an incorrect result.
      29  #
      30  #
      31  #######################################################################
      32  
      33  from abc import ABCMeta, abstractmethod
      34  
      35  __all__ = ["Number", "Complex", "Real", "Rational", "Integral"]
      36  
      37  class ESC[4;38;5;81mNumber(metaclass=ESC[4;38;5;149mABCMeta):
      38      """All numbers inherit from this class.
      39  
      40      If you just want to check if an argument x is a number, without
      41      caring what kind, use isinstance(x, Number).
      42      """
      43      __slots__ = ()
      44  
      45      # Concrete numeric types must provide their own hash implementation
      46      __hash__ = None
      47  
      48  
      49  ## Notes on Decimal
      50  ## ----------------
      51  ## Decimal has all of the methods specified by the Real abc, but it should
      52  ## not be registered as a Real because decimals do not interoperate with
      53  ## binary floats (i.e.  Decimal('3.14') + 2.71828 is undefined).  But,
      54  ## abstract reals are expected to interoperate (i.e. R1 + R2 should be
      55  ## expected to work if R1 and R2 are both Reals).
      56  
      57  class ESC[4;38;5;81mComplex(ESC[4;38;5;149mNumber):
      58      """Complex defines the operations that work on the builtin complex type.
      59  
      60      In short, those are: a conversion to complex, .real, .imag, +, -,
      61      *, /, **, abs(), .conjugate, ==, and !=.
      62  
      63      If it is given heterogeneous arguments, and doesn't have special
      64      knowledge about them, it should fall back to the builtin complex
      65      type as described below.
      66      """
      67  
      68      __slots__ = ()
      69  
      70      @abstractmethod
      71      def __complex__(self):
      72          """Return a builtin complex instance. Called for complex(self)."""
      73  
      74      def __bool__(self):
      75          """True if self != 0. Called for bool(self)."""
      76          return self != 0
      77  
      78      @property
      79      @abstractmethod
      80      def real(self):
      81          """Retrieve the real component of this number.
      82  
      83          This should subclass Real.
      84          """
      85          raise NotImplementedError
      86  
      87      @property
      88      @abstractmethod
      89      def imag(self):
      90          """Retrieve the imaginary component of this number.
      91  
      92          This should subclass Real.
      93          """
      94          raise NotImplementedError
      95  
      96      @abstractmethod
      97      def __add__(self, other):
      98          """self + other"""
      99          raise NotImplementedError
     100  
     101      @abstractmethod
     102      def __radd__(self, other):
     103          """other + self"""
     104          raise NotImplementedError
     105  
     106      @abstractmethod
     107      def __neg__(self):
     108          """-self"""
     109          raise NotImplementedError
     110  
     111      @abstractmethod
     112      def __pos__(self):
     113          """+self"""
     114          raise NotImplementedError
     115  
     116      def __sub__(self, other):
     117          """self - other"""
     118          return self + -other
     119  
     120      def __rsub__(self, other):
     121          """other - self"""
     122          return -self + other
     123  
     124      @abstractmethod
     125      def __mul__(self, other):
     126          """self * other"""
     127          raise NotImplementedError
     128  
     129      @abstractmethod
     130      def __rmul__(self, other):
     131          """other * self"""
     132          raise NotImplementedError
     133  
     134      @abstractmethod
     135      def __truediv__(self, other):
     136          """self / other: Should promote to float when necessary."""
     137          raise NotImplementedError
     138  
     139      @abstractmethod
     140      def __rtruediv__(self, other):
     141          """other / self"""
     142          raise NotImplementedError
     143  
     144      @abstractmethod
     145      def __pow__(self, exponent):
     146          """self ** exponent; should promote to float or complex when necessary."""
     147          raise NotImplementedError
     148  
     149      @abstractmethod
     150      def __rpow__(self, base):
     151          """base ** self"""
     152          raise NotImplementedError
     153  
     154      @abstractmethod
     155      def __abs__(self):
     156          """Returns the Real distance from 0. Called for abs(self)."""
     157          raise NotImplementedError
     158  
     159      @abstractmethod
     160      def conjugate(self):
     161          """(x+y*i).conjugate() returns (x-y*i)."""
     162          raise NotImplementedError
     163  
     164      @abstractmethod
     165      def __eq__(self, other):
     166          """self == other"""
     167          raise NotImplementedError
     168  
     169  Complex.register(complex)
     170  
     171  
     172  class ESC[4;38;5;81mReal(ESC[4;38;5;149mComplex):
     173      """To Complex, Real adds the operations that work on real numbers.
     174  
     175      In short, those are: a conversion to float, trunc(), divmod,
     176      %, <, <=, >, and >=.
     177  
     178      Real also provides defaults for the derived operations.
     179      """
     180  
     181      __slots__ = ()
     182  
     183      @abstractmethod
     184      def __float__(self):
     185          """Any Real can be converted to a native float object.
     186  
     187          Called for float(self)."""
     188          raise NotImplementedError
     189  
     190      @abstractmethod
     191      def __trunc__(self):
     192          """trunc(self): Truncates self to an Integral.
     193  
     194          Returns an Integral i such that:
     195            * i > 0 iff self > 0;
     196            * abs(i) <= abs(self);
     197            * for any Integral j satisfying the first two conditions,
     198              abs(i) >= abs(j) [i.e. i has "maximal" abs among those].
     199          i.e. "truncate towards 0".
     200          """
     201          raise NotImplementedError
     202  
     203      @abstractmethod
     204      def __floor__(self):
     205          """Finds the greatest Integral <= self."""
     206          raise NotImplementedError
     207  
     208      @abstractmethod
     209      def __ceil__(self):
     210          """Finds the least Integral >= self."""
     211          raise NotImplementedError
     212  
     213      @abstractmethod
     214      def __round__(self, ndigits=None):
     215          """Rounds self to ndigits decimal places, defaulting to 0.
     216  
     217          If ndigits is omitted or None, returns an Integral, otherwise
     218          returns a Real. Rounds half toward even.
     219          """
     220          raise NotImplementedError
     221  
     222      def __divmod__(self, other):
     223          """divmod(self, other): The pair (self // other, self % other).
     224  
     225          Sometimes this can be computed faster than the pair of
     226          operations.
     227          """
     228          return (self // other, self % other)
     229  
     230      def __rdivmod__(self, other):
     231          """divmod(other, self): The pair (other // self, other % self).
     232  
     233          Sometimes this can be computed faster than the pair of
     234          operations.
     235          """
     236          return (other // self, other % self)
     237  
     238      @abstractmethod
     239      def __floordiv__(self, other):
     240          """self // other: The floor() of self/other."""
     241          raise NotImplementedError
     242  
     243      @abstractmethod
     244      def __rfloordiv__(self, other):
     245          """other // self: The floor() of other/self."""
     246          raise NotImplementedError
     247  
     248      @abstractmethod
     249      def __mod__(self, other):
     250          """self % other"""
     251          raise NotImplementedError
     252  
     253      @abstractmethod
     254      def __rmod__(self, other):
     255          """other % self"""
     256          raise NotImplementedError
     257  
     258      @abstractmethod
     259      def __lt__(self, other):
     260          """self < other
     261  
     262          < on Reals defines a total ordering, except perhaps for NaN."""
     263          raise NotImplementedError
     264  
     265      @abstractmethod
     266      def __le__(self, other):
     267          """self <= other"""
     268          raise NotImplementedError
     269  
     270      # Concrete implementations of Complex abstract methods.
     271      def __complex__(self):
     272          """complex(self) == complex(float(self), 0)"""
     273          return complex(float(self))
     274  
     275      @property
     276      def real(self):
     277          """Real numbers are their real component."""
     278          return +self
     279  
     280      @property
     281      def imag(self):
     282          """Real numbers have no imaginary component."""
     283          return 0
     284  
     285      def conjugate(self):
     286          """Conjugate is a no-op for Reals."""
     287          return +self
     288  
     289  Real.register(float)
     290  
     291  
     292  class ESC[4;38;5;81mRational(ESC[4;38;5;149mReal):
     293      """.numerator and .denominator should be in lowest terms."""
     294  
     295      __slots__ = ()
     296  
     297      @property
     298      @abstractmethod
     299      def numerator(self):
     300          raise NotImplementedError
     301  
     302      @property
     303      @abstractmethod
     304      def denominator(self):
     305          raise NotImplementedError
     306  
     307      # Concrete implementation of Real's conversion to float.
     308      def __float__(self):
     309          """float(self) = self.numerator / self.denominator
     310  
     311          It's important that this conversion use the integer's "true"
     312          division rather than casting one side to float before dividing
     313          so that ratios of huge integers convert without overflowing.
     314  
     315          """
     316          return int(self.numerator) / int(self.denominator)
     317  
     318  
     319  class ESC[4;38;5;81mIntegral(ESC[4;38;5;149mRational):
     320      """Integral adds methods that work on integral numbers.
     321  
     322      In short, these are conversion to int, pow with modulus, and the
     323      bit-string operations.
     324      """
     325  
     326      __slots__ = ()
     327  
     328      @abstractmethod
     329      def __int__(self):
     330          """int(self)"""
     331          raise NotImplementedError
     332  
     333      def __index__(self):
     334          """Called whenever an index is needed, such as in slicing"""
     335          return int(self)
     336  
     337      @abstractmethod
     338      def __pow__(self, exponent, modulus=None):
     339          """self ** exponent % modulus, but maybe faster.
     340  
     341          Accept the modulus argument if you want to support the
     342          3-argument version of pow(). Raise a TypeError if exponent < 0
     343          or any argument isn't Integral. Otherwise, just implement the
     344          2-argument version described in Complex.
     345          """
     346          raise NotImplementedError
     347  
     348      @abstractmethod
     349      def __lshift__(self, other):
     350          """self << other"""
     351          raise NotImplementedError
     352  
     353      @abstractmethod
     354      def __rlshift__(self, other):
     355          """other << self"""
     356          raise NotImplementedError
     357  
     358      @abstractmethod
     359      def __rshift__(self, other):
     360          """self >> other"""
     361          raise NotImplementedError
     362  
     363      @abstractmethod
     364      def __rrshift__(self, other):
     365          """other >> self"""
     366          raise NotImplementedError
     367  
     368      @abstractmethod
     369      def __and__(self, other):
     370          """self & other"""
     371          raise NotImplementedError
     372  
     373      @abstractmethod
     374      def __rand__(self, other):
     375          """other & self"""
     376          raise NotImplementedError
     377  
     378      @abstractmethod
     379      def __xor__(self, other):
     380          """self ^ other"""
     381          raise NotImplementedError
     382  
     383      @abstractmethod
     384      def __rxor__(self, other):
     385          """other ^ self"""
     386          raise NotImplementedError
     387  
     388      @abstractmethod
     389      def __or__(self, other):
     390          """self | other"""
     391          raise NotImplementedError
     392  
     393      @abstractmethod
     394      def __ror__(self, other):
     395          """other | self"""
     396          raise NotImplementedError
     397  
     398      @abstractmethod
     399      def __invert__(self):
     400          """~self"""
     401          raise NotImplementedError
     402  
     403      # Concrete implementations of Rational and Real abstract methods.
     404      def __float__(self):
     405          """float(self) == float(int(self))"""
     406          return float(int(self))
     407  
     408      @property
     409      def numerator(self):
     410          """Integers are their own numerators."""
     411          return +self
     412  
     413      @property
     414      def denominator(self):
     415          """Integers have a denominator of 1."""
     416          return 1
     417  
     418  Integral.register(int)