blob: 7eedc63ec05db2a7952b3dd3871c4915a2be0b38 [file] [log] [blame]
Guido van Rossum1daf9542007-08-30 17:45:54 +00001# Copyright 2007 Google, Inc. All Rights Reserved.
2# Licensed to PSF under a Contributor Agreement.
3
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +00004"""Abstract Base Classes (ABCs) for numbers, according to PEP 3141.
5
6TODO: Fill out more detailed documentation on the operators."""
Guido van Rossum1daf9542007-08-30 17:45:54 +00007
Benjamin Petersonbfebb7b2011-12-15 15:34:02 -05008from abc import ABCMeta, abstractmethod
Guido van Rossum1daf9542007-08-30 17:45:54 +00009
Christian Heimes08976cb2008-03-16 00:32:36 +000010__all__ = ["Number", "Complex", "Real", "Rational", "Integral"]
Guido van Rossum1daf9542007-08-30 17:45:54 +000011
12class Number(metaclass=ABCMeta):
13 """All numbers inherit from this class.
14
15 If you just want to check if an argument x is a number, without
16 caring what kind, use isinstance(x, Number).
17 """
Mark Dickinsonc28ad272009-02-12 17:58:36 +000018 __slots__ = ()
19
Nick Coghlan36f49522008-08-18 12:31:52 +000020 # Concrete numeric types must provide their own hash implementation
21 __hash__ = None
Guido van Rossum1daf9542007-08-30 17:45:54 +000022
23
Christian Heimes68f5fbe2008-02-14 08:27:37 +000024## Notes on Decimal
25## ----------------
26## Decimal has all of the methods specified by the Real abc, but it should
27## not be registered as a Real because decimals do not interoperate with
Christian Heimes08976cb2008-03-16 00:32:36 +000028## binary floats (i.e. Decimal('3.14') + 2.71828 is undefined). But,
29## abstract reals are expected to interoperate (i.e. R1 + R2 should be
30## expected to work if R1 and R2 are both Reals).
Christian Heimes0bd4e112008-02-12 22:59:25 +000031
Guido van Rossum1daf9542007-08-30 17:45:54 +000032class Complex(Number):
33 """Complex defines the operations that work on the builtin complex type.
34
35 In short, those are: a conversion to complex, .real, .imag, +, -,
36 *, /, abs(), .conjugate, ==, and !=.
37
38 If it is given heterogenous arguments, and doesn't have special
39 knowledge about them, it should fall back to the builtin complex
40 type as described below.
41 """
42
Mark Dickinsonc28ad272009-02-12 17:58:36 +000043 __slots__ = ()
44
Guido van Rossum1daf9542007-08-30 17:45:54 +000045 @abstractmethod
46 def __complex__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000047 """Return a builtin complex instance. Called for complex(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +000048
Jeffrey Yasskin9893de12008-01-17 07:36:30 +000049 def __bool__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000050 """True if self != 0. Called for bool(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +000051 return self != 0
52
Benjamin Petersonbfebb7b2011-12-15 15:34:02 -050053 @property
54 @abstractmethod
Guido van Rossum1daf9542007-08-30 17:45:54 +000055 def real(self):
56 """Retrieve the real component of this number.
57
58 This should subclass Real.
59 """
60 raise NotImplementedError
61
Benjamin Petersonbfebb7b2011-12-15 15:34:02 -050062 @property
63 @abstractmethod
Guido van Rossum1daf9542007-08-30 17:45:54 +000064 def imag(self):
Benjamin Peterson5793e6f2010-12-23 22:17:42 +000065 """Retrieve the imaginary component of this number.
Guido van Rossum1daf9542007-08-30 17:45:54 +000066
67 This should subclass Real.
68 """
69 raise NotImplementedError
70
71 @abstractmethod
72 def __add__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000073 """self + other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000074 raise NotImplementedError
75
76 @abstractmethod
77 def __radd__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000078 """other + self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000079 raise NotImplementedError
80
81 @abstractmethod
82 def __neg__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000083 """-self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000084 raise NotImplementedError
85
Guido van Rossum7736b5b2008-01-15 21:44:53 +000086 @abstractmethod
Guido van Rossum1daf9542007-08-30 17:45:54 +000087 def __pos__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000088 """+self"""
Guido van Rossumd4256302007-12-06 17:45:33 +000089 raise NotImplementedError
Guido van Rossum1daf9542007-08-30 17:45:54 +000090
91 def __sub__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000092 """self - other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000093 return self + -other
94
95 def __rsub__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000096 """other - self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000097 return -self + other
98
99 @abstractmethod
100 def __mul__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000101 """self * other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000102 raise NotImplementedError
103
104 @abstractmethod
105 def __rmul__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000106 """other * self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000107 raise NotImplementedError
108
109 @abstractmethod
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000110 def __truediv__(self, other):
Jeffrey Yasskin9893de12008-01-17 07:36:30 +0000111 """self / other: Should promote to float when necessary."""
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000112 raise NotImplementedError
113
114 @abstractmethod
115 def __rtruediv__(self, other):
Jeffrey Yasskin9893de12008-01-17 07:36:30 +0000116 """other / self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000117 raise NotImplementedError
118
119 @abstractmethod
120 def __pow__(self, exponent):
Guido van Rossumd4256302007-12-06 17:45:33 +0000121 """self**exponent; should promote to float or complex when necessary."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000122 raise NotImplementedError
123
124 @abstractmethod
125 def __rpow__(self, base):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000126 """base ** self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000127 raise NotImplementedError
128
129 @abstractmethod
130 def __abs__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000131 """Returns the Real distance from 0. Called for abs(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000132 raise NotImplementedError
133
134 @abstractmethod
135 def conjugate(self):
136 """(x+y*i).conjugate() returns (x-y*i)."""
137 raise NotImplementedError
138
139 @abstractmethod
140 def __eq__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000141 """self == other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000142 raise NotImplementedError
143
Guido van Rossum1daf9542007-08-30 17:45:54 +0000144Complex.register(complex)
145
146
147class Real(Complex):
148 """To Complex, Real adds the operations that work on real numbers.
149
150 In short, those are: a conversion to float, trunc(), divmod,
151 %, <, <=, >, and >=.
152
153 Real also provides defaults for the derived operations.
154 """
155
Mark Dickinsonc28ad272009-02-12 17:58:36 +0000156 __slots__ = ()
157
Guido van Rossum1daf9542007-08-30 17:45:54 +0000158 @abstractmethod
159 def __float__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000160 """Any Real can be converted to a native float object.
161
162 Called for float(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000163 raise NotImplementedError
164
165 @abstractmethod
166 def __trunc__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000167 """trunc(self): Truncates self to an Integral.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000168
169 Returns an Integral i such that:
Guido van Rossumd4256302007-12-06 17:45:33 +0000170 * i>0 iff self>0;
171 * abs(i) <= abs(self);
172 * for any Integral j satisfying the first two conditions,
173 abs(i) >= abs(j) [i.e. i has "maximal" abs among those].
174 i.e. "truncate towards 0".
175 """
176 raise NotImplementedError
177
178 @abstractmethod
179 def __floor__(self):
180 """Finds the greatest Integral <= self."""
181 raise NotImplementedError
182
183 @abstractmethod
184 def __ceil__(self):
185 """Finds the least Integral >= self."""
186 raise NotImplementedError
187
188 @abstractmethod
Raymond Hettinger219c3002011-01-12 20:52:39 +0000189 def __round__(self, ndigits=None):
Guido van Rossumd4256302007-12-06 17:45:33 +0000190 """Rounds self to ndigits decimal places, defaulting to 0.
191
192 If ndigits is omitted or None, returns an Integral, otherwise
193 returns a Real. Rounds half toward even.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000194 """
195 raise NotImplementedError
196
197 def __divmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000198 """divmod(self, other): The pair (self // other, self % other).
Guido van Rossum1daf9542007-08-30 17:45:54 +0000199
200 Sometimes this can be computed faster than the pair of
201 operations.
202 """
203 return (self // other, self % other)
204
205 def __rdivmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000206 """divmod(other, self): The pair (self // other, self % other).
Guido van Rossum1daf9542007-08-30 17:45:54 +0000207
208 Sometimes this can be computed faster than the pair of
209 operations.
210 """
211 return (other // self, other % self)
212
213 @abstractmethod
214 def __floordiv__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000215 """self // other: The floor() of self/other."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000216 raise NotImplementedError
217
218 @abstractmethod
219 def __rfloordiv__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000220 """other // self: The floor() of other/self."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000221 raise NotImplementedError
222
223 @abstractmethod
224 def __mod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000225 """self % other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000226 raise NotImplementedError
227
228 @abstractmethod
229 def __rmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000230 """other % self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000231 raise NotImplementedError
232
233 @abstractmethod
234 def __lt__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000235 """self < other
236
237 < on Reals defines a total ordering, except perhaps for NaN."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000238 raise NotImplementedError
239
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000240 @abstractmethod
Guido van Rossum1daf9542007-08-30 17:45:54 +0000241 def __le__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000242 """self <= other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000243 raise NotImplementedError
244
245 # Concrete implementations of Complex abstract methods.
246 def __complex__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000247 """complex(self) == complex(float(self), 0)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000248 return complex(float(self))
249
250 @property
251 def real(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000252 """Real numbers are their real component."""
Guido van Rossumd4256302007-12-06 17:45:33 +0000253 return +self
Guido van Rossum1daf9542007-08-30 17:45:54 +0000254
255 @property
256 def imag(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000257 """Real numbers have no imaginary component."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000258 return 0
259
260 def conjugate(self):
261 """Conjugate is a no-op for Reals."""
Guido van Rossumd4256302007-12-06 17:45:33 +0000262 return +self
Guido van Rossum1daf9542007-08-30 17:45:54 +0000263
264Real.register(float)
265
266
Christian Heimes08976cb2008-03-16 00:32:36 +0000267class Rational(Real):
Guido van Rossum1daf9542007-08-30 17:45:54 +0000268 """.numerator and .denominator should be in lowest terms."""
269
Mark Dickinsonc28ad272009-02-12 17:58:36 +0000270 __slots__ = ()
271
Benjamin Petersonbfebb7b2011-12-15 15:34:02 -0500272 @property
273 @abstractmethod
Guido van Rossum1daf9542007-08-30 17:45:54 +0000274 def numerator(self):
275 raise NotImplementedError
276
Benjamin Petersonbfebb7b2011-12-15 15:34:02 -0500277 @property
278 @abstractmethod
Guido van Rossum1daf9542007-08-30 17:45:54 +0000279 def denominator(self):
280 raise NotImplementedError
281
282 # Concrete implementation of Real's conversion to float.
283 def __float__(self):
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000284 """float(self) = self.numerator / self.denominator
285
286 It's important that this conversion use the integer's "true"
287 division rather than casting one side to float before dividing
288 so that ratios of huge integers convert without overflowing.
289
290 """
Guido van Rossum1daf9542007-08-30 17:45:54 +0000291 return self.numerator / self.denominator
292
293
294class Integral(Rational):
295 """Integral adds a conversion to int and the bit-string operations."""
296
Mark Dickinsonc28ad272009-02-12 17:58:36 +0000297 __slots__ = ()
298
Guido van Rossum1daf9542007-08-30 17:45:54 +0000299 @abstractmethod
300 def __int__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000301 """int(self)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000302 raise NotImplementedError
303
304 def __index__(self):
Éric Araujoe2544bc2011-11-03 04:34:09 +0100305 """Called whenever an index is needed, such as in slicing"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000306 return int(self)
307
308 @abstractmethod
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000309 def __pow__(self, exponent, modulus=None):
Guido van Rossum1daf9542007-08-30 17:45:54 +0000310 """self ** exponent % modulus, but maybe faster.
311
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000312 Accept the modulus argument if you want to support the
313 3-argument version of pow(). Raise a TypeError if exponent < 0
314 or any argument isn't Integral. Otherwise, just implement the
315 2-argument version described in Complex.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000316 """
317 raise NotImplementedError
318
319 @abstractmethod
320 def __lshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000321 """self << other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000322 raise NotImplementedError
323
324 @abstractmethod
325 def __rlshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000326 """other << self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000327 raise NotImplementedError
328
329 @abstractmethod
330 def __rshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000331 """self >> other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000332 raise NotImplementedError
333
334 @abstractmethod
335 def __rrshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000336 """other >> self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000337 raise NotImplementedError
338
339 @abstractmethod
340 def __and__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000341 """self & other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000342 raise NotImplementedError
343
344 @abstractmethod
345 def __rand__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000346 """other & self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000347 raise NotImplementedError
348
349 @abstractmethod
350 def __xor__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000351 """self ^ other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000352 raise NotImplementedError
353
354 @abstractmethod
355 def __rxor__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000356 """other ^ self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000357 raise NotImplementedError
358
359 @abstractmethod
360 def __or__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000361 """self | other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000362 raise NotImplementedError
363
364 @abstractmethod
365 def __ror__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000366 """other | self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000367 raise NotImplementedError
368
369 @abstractmethod
370 def __invert__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000371 """~self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000372 raise NotImplementedError
373
374 # Concrete implementations of Rational and Real abstract methods.
375 def __float__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000376 """float(self) == float(int(self))"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000377 return float(int(self))
378
379 @property
380 def numerator(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000381 """Integers are their own numerators."""
Guido van Rossumd4256302007-12-06 17:45:33 +0000382 return +self
Guido van Rossum1daf9542007-08-30 17:45:54 +0000383
384 @property
385 def denominator(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000386 """Integers have a denominator of 1."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000387 return 1
388
389Integral.register(int)