blob: ecfad7cef8b69e3b99e7907882061009c19862e6 [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
8from abc import ABCMeta, abstractmethod, abstractproperty
9
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
53 @abstractproperty
54 def real(self):
55 """Retrieve the real component of this number.
56
57 This should subclass Real.
58 """
59 raise NotImplementedError
60
61 @abstractproperty
62 def imag(self):
Benjamin Peterson5793e6f2010-12-23 22:17:42 +000063 """Retrieve the imaginary component of this number.
Guido van Rossum1daf9542007-08-30 17:45:54 +000064
65 This should subclass Real.
66 """
67 raise NotImplementedError
68
69 @abstractmethod
70 def __add__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000071 """self + other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000072 raise NotImplementedError
73
74 @abstractmethod
75 def __radd__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000076 """other + self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000077 raise NotImplementedError
78
79 @abstractmethod
80 def __neg__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000081 """-self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000082 raise NotImplementedError
83
Guido van Rossum7736b5b2008-01-15 21:44:53 +000084 @abstractmethod
Guido van Rossum1daf9542007-08-30 17:45:54 +000085 def __pos__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000086 """+self"""
Guido van Rossumd4256302007-12-06 17:45:33 +000087 raise NotImplementedError
Guido van Rossum1daf9542007-08-30 17:45:54 +000088
89 def __sub__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000090 """self - other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000091 return self + -other
92
93 def __rsub__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000094 """other - self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000095 return -self + other
96
97 @abstractmethod
98 def __mul__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000099 """self * other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000100 raise NotImplementedError
101
102 @abstractmethod
103 def __rmul__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000104 """other * self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000105 raise NotImplementedError
106
107 @abstractmethod
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000108 def __truediv__(self, other):
Jeffrey Yasskin9893de12008-01-17 07:36:30 +0000109 """self / other: Should promote to float when necessary."""
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000110 raise NotImplementedError
111
112 @abstractmethod
113 def __rtruediv__(self, other):
Jeffrey Yasskin9893de12008-01-17 07:36:30 +0000114 """other / self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000115 raise NotImplementedError
116
117 @abstractmethod
118 def __pow__(self, exponent):
Guido van Rossumd4256302007-12-06 17:45:33 +0000119 """self**exponent; should promote to float or complex when necessary."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000120 raise NotImplementedError
121
122 @abstractmethod
123 def __rpow__(self, base):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000124 """base ** self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000125 raise NotImplementedError
126
127 @abstractmethod
128 def __abs__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000129 """Returns the Real distance from 0. Called for abs(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000130 raise NotImplementedError
131
132 @abstractmethod
133 def conjugate(self):
134 """(x+y*i).conjugate() returns (x-y*i)."""
135 raise NotImplementedError
136
137 @abstractmethod
138 def __eq__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000139 """self == other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000140 raise NotImplementedError
141
Christian Heimes77c02eb2008-02-09 02:18:51 +0000142 def __ne__(self, other):
143 """self != other"""
144 # The default __ne__ doesn't negate __eq__ until 3.0.
145 return not (self == other)
Guido van Rossum1daf9542007-08-30 17:45:54 +0000146
147Complex.register(complex)
148
149
150class Real(Complex):
151 """To Complex, Real adds the operations that work on real numbers.
152
153 In short, those are: a conversion to float, trunc(), divmod,
154 %, <, <=, >, and >=.
155
156 Real also provides defaults for the derived operations.
157 """
158
Mark Dickinsonc28ad272009-02-12 17:58:36 +0000159 __slots__ = ()
160
Guido van Rossum1daf9542007-08-30 17:45:54 +0000161 @abstractmethod
162 def __float__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000163 """Any Real can be converted to a native float object.
164
165 Called for float(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000166 raise NotImplementedError
167
168 @abstractmethod
169 def __trunc__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000170 """trunc(self): Truncates self to an Integral.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000171
172 Returns an Integral i such that:
Guido van Rossumd4256302007-12-06 17:45:33 +0000173 * i>0 iff self>0;
174 * abs(i) <= abs(self);
175 * for any Integral j satisfying the first two conditions,
176 abs(i) >= abs(j) [i.e. i has "maximal" abs among those].
177 i.e. "truncate towards 0".
178 """
179 raise NotImplementedError
180
181 @abstractmethod
182 def __floor__(self):
183 """Finds the greatest Integral <= self."""
184 raise NotImplementedError
185
186 @abstractmethod
187 def __ceil__(self):
188 """Finds the least Integral >= self."""
189 raise NotImplementedError
190
191 @abstractmethod
Raymond Hettinger219c3002011-01-12 20:52:39 +0000192 def __round__(self, ndigits=None):
Guido van Rossumd4256302007-12-06 17:45:33 +0000193 """Rounds self to ndigits decimal places, defaulting to 0.
194
195 If ndigits is omitted or None, returns an Integral, otherwise
196 returns a Real. Rounds half toward even.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000197 """
198 raise NotImplementedError
199
200 def __divmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000201 """divmod(self, other): The pair (self // other, self % other).
Guido van Rossum1daf9542007-08-30 17:45:54 +0000202
203 Sometimes this can be computed faster than the pair of
204 operations.
205 """
206 return (self // other, self % other)
207
208 def __rdivmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000209 """divmod(other, self): The pair (self // other, self % other).
Guido van Rossum1daf9542007-08-30 17:45:54 +0000210
211 Sometimes this can be computed faster than the pair of
212 operations.
213 """
214 return (other // self, other % self)
215
216 @abstractmethod
217 def __floordiv__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000218 """self // other: The floor() of self/other."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000219 raise NotImplementedError
220
221 @abstractmethod
222 def __rfloordiv__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000223 """other // self: The floor() of other/self."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000224 raise NotImplementedError
225
226 @abstractmethod
227 def __mod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000228 """self % other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000229 raise NotImplementedError
230
231 @abstractmethod
232 def __rmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000233 """other % self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000234 raise NotImplementedError
235
236 @abstractmethod
237 def __lt__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000238 """self < other
239
240 < on Reals defines a total ordering, except perhaps for NaN."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000241 raise NotImplementedError
242
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000243 @abstractmethod
Guido van Rossum1daf9542007-08-30 17:45:54 +0000244 def __le__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000245 """self <= other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000246 raise NotImplementedError
247
248 # Concrete implementations of Complex abstract methods.
249 def __complex__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000250 """complex(self) == complex(float(self), 0)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000251 return complex(float(self))
252
253 @property
254 def real(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000255 """Real numbers are their real component."""
Guido van Rossumd4256302007-12-06 17:45:33 +0000256 return +self
Guido van Rossum1daf9542007-08-30 17:45:54 +0000257
258 @property
259 def imag(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000260 """Real numbers have no imaginary component."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000261 return 0
262
263 def conjugate(self):
264 """Conjugate is a no-op for Reals."""
Guido van Rossumd4256302007-12-06 17:45:33 +0000265 return +self
Guido van Rossum1daf9542007-08-30 17:45:54 +0000266
267Real.register(float)
268
269
Christian Heimes08976cb2008-03-16 00:32:36 +0000270class Rational(Real):
Guido van Rossum1daf9542007-08-30 17:45:54 +0000271 """.numerator and .denominator should be in lowest terms."""
272
Mark Dickinsonc28ad272009-02-12 17:58:36 +0000273 __slots__ = ()
274
Guido van Rossum1daf9542007-08-30 17:45:54 +0000275 @abstractproperty
276 def numerator(self):
277 raise NotImplementedError
278
279 @abstractproperty
280 def denominator(self):
281 raise NotImplementedError
282
283 # Concrete implementation of Real's conversion to float.
284 def __float__(self):
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000285 """float(self) = self.numerator / self.denominator
286
287 It's important that this conversion use the integer's "true"
288 division rather than casting one side to float before dividing
289 so that ratios of huge integers convert without overflowing.
290
291 """
Guido van Rossum1daf9542007-08-30 17:45:54 +0000292 return self.numerator / self.denominator
293
294
295class Integral(Rational):
296 """Integral adds a conversion to int and the bit-string operations."""
297
Mark Dickinsonc28ad272009-02-12 17:58:36 +0000298 __slots__ = ()
299
Guido van Rossum1daf9542007-08-30 17:45:54 +0000300 @abstractmethod
301 def __int__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000302 """int(self)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000303 raise NotImplementedError
304
305 def __index__(self):
Éric Araujoe2544bc2011-11-03 04:34:09 +0100306 """Called whenever an index is needed, such as in slicing"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000307 return int(self)
308
309 @abstractmethod
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000310 def __pow__(self, exponent, modulus=None):
Guido van Rossum1daf9542007-08-30 17:45:54 +0000311 """self ** exponent % modulus, but maybe faster.
312
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000313 Accept the modulus argument if you want to support the
314 3-argument version of pow(). Raise a TypeError if exponent < 0
315 or any argument isn't Integral. Otherwise, just implement the
316 2-argument version described in Complex.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000317 """
318 raise NotImplementedError
319
320 @abstractmethod
321 def __lshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000322 """self << other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000323 raise NotImplementedError
324
325 @abstractmethod
326 def __rlshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000327 """other << self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000328 raise NotImplementedError
329
330 @abstractmethod
331 def __rshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000332 """self >> other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000333 raise NotImplementedError
334
335 @abstractmethod
336 def __rrshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000337 """other >> self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000338 raise NotImplementedError
339
340 @abstractmethod
341 def __and__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000342 """self & other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000343 raise NotImplementedError
344
345 @abstractmethod
346 def __rand__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000347 """other & self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000348 raise NotImplementedError
349
350 @abstractmethod
351 def __xor__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000352 """self ^ other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000353 raise NotImplementedError
354
355 @abstractmethod
356 def __rxor__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000357 """other ^ self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000358 raise NotImplementedError
359
360 @abstractmethod
361 def __or__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000362 """self | other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000363 raise NotImplementedError
364
365 @abstractmethod
366 def __ror__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000367 """other | self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000368 raise NotImplementedError
369
370 @abstractmethod
371 def __invert__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000372 """~self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000373 raise NotImplementedError
374
375 # Concrete implementations of Rational and Real abstract methods.
376 def __float__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000377 """float(self) == float(int(self))"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000378 return float(int(self))
379
380 @property
381 def numerator(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000382 """Integers are their own numerators."""
Guido van Rossumd4256302007-12-06 17:45:33 +0000383 return +self
Guido van Rossum1daf9542007-08-30 17:45:54 +0000384
385 @property
386 def denominator(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000387 """Integers have a denominator of 1."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000388 return 1
389
390Integral.register(int)