blob: c72a23df39fd14ba3b8fc6b8c1a532c2f6dc6753 [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 """
18
19
Christian Heimes68f5fbe2008-02-14 08:27:37 +000020## Notes on Decimal
21## ----------------
22## Decimal has all of the methods specified by the Real abc, but it should
23## not be registered as a Real because decimals do not interoperate with
Christian Heimes08976cb2008-03-16 00:32:36 +000024## binary floats (i.e. Decimal('3.14') + 2.71828 is undefined). But,
25## abstract reals are expected to interoperate (i.e. R1 + R2 should be
26## expected to work if R1 and R2 are both Reals).
Christian Heimes0bd4e112008-02-12 22:59:25 +000027
Guido van Rossum1daf9542007-08-30 17:45:54 +000028class Complex(Number):
29 """Complex defines the operations that work on the builtin complex type.
30
31 In short, those are: a conversion to complex, .real, .imag, +, -,
32 *, /, abs(), .conjugate, ==, and !=.
33
34 If it is given heterogenous arguments, and doesn't have special
35 knowledge about them, it should fall back to the builtin complex
36 type as described below.
37 """
38
39 @abstractmethod
40 def __complex__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000041 """Return a builtin complex instance. Called for complex(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +000042
Jeffrey Yasskin9893de12008-01-17 07:36:30 +000043 def __bool__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000044 """True if self != 0. Called for bool(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +000045 return self != 0
46
47 @abstractproperty
48 def real(self):
49 """Retrieve the real component of this number.
50
51 This should subclass Real.
52 """
53 raise NotImplementedError
54
55 @abstractproperty
56 def imag(self):
57 """Retrieve the real component of this number.
58
59 This should subclass Real.
60 """
61 raise NotImplementedError
62
63 @abstractmethod
64 def __add__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000065 """self + other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000066 raise NotImplementedError
67
68 @abstractmethod
69 def __radd__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000070 """other + self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000071 raise NotImplementedError
72
73 @abstractmethod
74 def __neg__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000075 """-self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000076 raise NotImplementedError
77
Guido van Rossum7736b5b2008-01-15 21:44:53 +000078 @abstractmethod
Guido van Rossum1daf9542007-08-30 17:45:54 +000079 def __pos__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000080 """+self"""
Guido van Rossumd4256302007-12-06 17:45:33 +000081 raise NotImplementedError
Guido van Rossum1daf9542007-08-30 17:45:54 +000082
83 def __sub__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000084 """self - other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000085 return self + -other
86
87 def __rsub__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000088 """other - self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000089 return -self + other
90
91 @abstractmethod
92 def __mul__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000093 """self * other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000094 raise NotImplementedError
95
96 @abstractmethod
97 def __rmul__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000098 """other * self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000099 raise NotImplementedError
100
101 @abstractmethod
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000102 def __truediv__(self, other):
Jeffrey Yasskin9893de12008-01-17 07:36:30 +0000103 """self / other: Should promote to float when necessary."""
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000104 raise NotImplementedError
105
106 @abstractmethod
107 def __rtruediv__(self, other):
Jeffrey Yasskin9893de12008-01-17 07:36:30 +0000108 """other / self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000109 raise NotImplementedError
110
111 @abstractmethod
112 def __pow__(self, exponent):
Guido van Rossumd4256302007-12-06 17:45:33 +0000113 """self**exponent; should promote to float or complex when necessary."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000114 raise NotImplementedError
115
116 @abstractmethod
117 def __rpow__(self, base):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000118 """base ** self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000119 raise NotImplementedError
120
121 @abstractmethod
122 def __abs__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000123 """Returns the Real distance from 0. Called for abs(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000124 raise NotImplementedError
125
126 @abstractmethod
127 def conjugate(self):
128 """(x+y*i).conjugate() returns (x-y*i)."""
129 raise NotImplementedError
130
131 @abstractmethod
132 def __eq__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000133 """self == other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000134 raise NotImplementedError
135
Christian Heimes77c02eb2008-02-09 02:18:51 +0000136 def __ne__(self, other):
137 """self != other"""
138 # The default __ne__ doesn't negate __eq__ until 3.0.
139 return not (self == other)
Guido van Rossum1daf9542007-08-30 17:45:54 +0000140
141Complex.register(complex)
142
143
144class Real(Complex):
145 """To Complex, Real adds the operations that work on real numbers.
146
147 In short, those are: a conversion to float, trunc(), divmod,
148 %, <, <=, >, and >=.
149
150 Real also provides defaults for the derived operations.
151 """
152
153 @abstractmethod
154 def __float__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000155 """Any Real can be converted to a native float object.
156
157 Called for float(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000158 raise NotImplementedError
159
160 @abstractmethod
161 def __trunc__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000162 """trunc(self): Truncates self to an Integral.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000163
164 Returns an Integral i such that:
Guido van Rossumd4256302007-12-06 17:45:33 +0000165 * i>0 iff self>0;
166 * abs(i) <= abs(self);
167 * for any Integral j satisfying the first two conditions,
168 abs(i) >= abs(j) [i.e. i has "maximal" abs among those].
169 i.e. "truncate towards 0".
170 """
171 raise NotImplementedError
172
173 @abstractmethod
174 def __floor__(self):
175 """Finds the greatest Integral <= self."""
176 raise NotImplementedError
177
178 @abstractmethod
179 def __ceil__(self):
180 """Finds the least Integral >= self."""
181 raise NotImplementedError
182
183 @abstractmethod
184 def __round__(self, ndigits:"Integral"=None):
185 """Rounds self to ndigits decimal places, defaulting to 0.
186
187 If ndigits is omitted or None, returns an Integral, otherwise
188 returns a Real. Rounds half toward even.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000189 """
190 raise NotImplementedError
191
192 def __divmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000193 """divmod(self, other): The pair (self // other, self % other).
Guido van Rossum1daf9542007-08-30 17:45:54 +0000194
195 Sometimes this can be computed faster than the pair of
196 operations.
197 """
198 return (self // other, self % other)
199
200 def __rdivmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000201 """divmod(other, self): 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 (other // self, other % self)
207
208 @abstractmethod
209 def __floordiv__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000210 """self // other: The floor() of self/other."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000211 raise NotImplementedError
212
213 @abstractmethod
214 def __rfloordiv__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000215 """other // self: The floor() of other/self."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000216 raise NotImplementedError
217
218 @abstractmethod
219 def __mod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000220 """self % other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000221 raise NotImplementedError
222
223 @abstractmethod
224 def __rmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000225 """other % self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000226 raise NotImplementedError
227
228 @abstractmethod
229 def __lt__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000230 """self < other
231
232 < on Reals defines a total ordering, except perhaps for NaN."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000233 raise NotImplementedError
234
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000235 @abstractmethod
Guido van Rossum1daf9542007-08-30 17:45:54 +0000236 def __le__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000237 """self <= other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000238 raise NotImplementedError
239
240 # Concrete implementations of Complex abstract methods.
241 def __complex__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000242 """complex(self) == complex(float(self), 0)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000243 return complex(float(self))
244
245 @property
246 def real(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000247 """Real numbers are their real component."""
Guido van Rossumd4256302007-12-06 17:45:33 +0000248 return +self
Guido van Rossum1daf9542007-08-30 17:45:54 +0000249
250 @property
251 def imag(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000252 """Real numbers have no imaginary component."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000253 return 0
254
255 def conjugate(self):
256 """Conjugate is a no-op for Reals."""
Guido van Rossumd4256302007-12-06 17:45:33 +0000257 return +self
Guido van Rossum1daf9542007-08-30 17:45:54 +0000258
259Real.register(float)
260
261
Christian Heimes08976cb2008-03-16 00:32:36 +0000262class Rational(Real):
Guido van Rossum1daf9542007-08-30 17:45:54 +0000263 """.numerator and .denominator should be in lowest terms."""
264
265 @abstractproperty
266 def numerator(self):
267 raise NotImplementedError
268
269 @abstractproperty
270 def denominator(self):
271 raise NotImplementedError
272
273 # Concrete implementation of Real's conversion to float.
274 def __float__(self):
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000275 """float(self) = self.numerator / self.denominator
276
277 It's important that this conversion use the integer's "true"
278 division rather than casting one side to float before dividing
279 so that ratios of huge integers convert without overflowing.
280
281 """
Guido van Rossum1daf9542007-08-30 17:45:54 +0000282 return self.numerator / self.denominator
283
284
285class Integral(Rational):
286 """Integral adds a conversion to int and the bit-string operations."""
287
288 @abstractmethod
289 def __int__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000290 """int(self)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000291 raise NotImplementedError
292
293 def __index__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000294 """index(self)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000295 return int(self)
296
297 @abstractmethod
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000298 def __pow__(self, exponent, modulus=None):
Guido van Rossum1daf9542007-08-30 17:45:54 +0000299 """self ** exponent % modulus, but maybe faster.
300
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000301 Accept the modulus argument if you want to support the
302 3-argument version of pow(). Raise a TypeError if exponent < 0
303 or any argument isn't Integral. Otherwise, just implement the
304 2-argument version described in Complex.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000305 """
306 raise NotImplementedError
307
308 @abstractmethod
309 def __lshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000310 """self << other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000311 raise NotImplementedError
312
313 @abstractmethod
314 def __rlshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000315 """other << self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000316 raise NotImplementedError
317
318 @abstractmethod
319 def __rshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000320 """self >> other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000321 raise NotImplementedError
322
323 @abstractmethod
324 def __rrshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000325 """other >> self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000326 raise NotImplementedError
327
328 @abstractmethod
329 def __and__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000330 """self & other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000331 raise NotImplementedError
332
333 @abstractmethod
334 def __rand__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000335 """other & self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000336 raise NotImplementedError
337
338 @abstractmethod
339 def __xor__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000340 """self ^ other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000341 raise NotImplementedError
342
343 @abstractmethod
344 def __rxor__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000345 """other ^ self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000346 raise NotImplementedError
347
348 @abstractmethod
349 def __or__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000350 """self | other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000351 raise NotImplementedError
352
353 @abstractmethod
354 def __ror__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000355 """other | self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000356 raise NotImplementedError
357
358 @abstractmethod
359 def __invert__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000360 """~self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000361 raise NotImplementedError
362
363 # Concrete implementations of Rational and Real abstract methods.
364 def __float__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000365 """float(self) == float(int(self))"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000366 return float(int(self))
367
368 @property
369 def numerator(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000370 """Integers are their own numerators."""
Guido van Rossumd4256302007-12-06 17:45:33 +0000371 return +self
Guido van Rossum1daf9542007-08-30 17:45:54 +0000372
373 @property
374 def denominator(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000375 """Integers have a denominator of 1."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000376 return 1
377
378Integral.register(int)