blob: 7c73fa7eed4628bb3e4a07d9534da80c299762e5 [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
Guido van Rossum7736b5b2008-01-15 21:44:53 +00008from __future__ import division
Guido van Rossum1daf9542007-08-30 17:45:54 +00009from abc import ABCMeta, abstractmethod, abstractproperty
10
11__all__ = ["Number", "Exact", "Inexact",
12 "Complex", "Real", "Rational", "Integral",
13 ]
14
15
16class Number(metaclass=ABCMeta):
17 """All numbers inherit from this class.
18
19 If you just want to check if an argument x is a number, without
20 caring what kind, use isinstance(x, Number).
21 """
22
23
24class Exact(Number):
25 """Operations on instances of this type are exact.
26
27 As long as the result of a homogenous operation is of the same
28 type, you can assume that it was computed exactly, and there are
29 no round-off errors. Laws like commutativity and associativity
30 hold.
31 """
32
33Exact.register(int)
34
35
36class Inexact(Number):
37 """Operations on instances of this type are inexact.
38
39 Given X, an instance of Inexact, it is possible that (X + -X) + 3
40 == 3, but X + (-X + 3) == 0. The exact form this error takes will
41 vary by type, but it's generally unsafe to compare this type for
42 equality.
43 """
44
45Inexact.register(complex)
46Inexact.register(float)
Guido van Rossumd4256302007-12-06 17:45:33 +000047# Inexact.register(decimal.Decimal)
Guido van Rossum1daf9542007-08-30 17:45:54 +000048
49
50class Complex(Number):
51 """Complex defines the operations that work on the builtin complex type.
52
53 In short, those are: a conversion to complex, .real, .imag, +, -,
54 *, /, abs(), .conjugate, ==, and !=.
55
56 If it is given heterogenous arguments, and doesn't have special
57 knowledge about them, it should fall back to the builtin complex
58 type as described below.
59 """
60
61 @abstractmethod
62 def __complex__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000063 """Return a builtin complex instance. Called for complex(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +000064
Guido van Rossum7736b5b2008-01-15 21:44:53 +000065 # Will be __bool__ in 3.0.
66 def __nonzero__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000067 """True if self != 0. Called for bool(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +000068 return self != 0
69
70 @abstractproperty
71 def real(self):
72 """Retrieve the real component of this number.
73
74 This should subclass Real.
75 """
76 raise NotImplementedError
77
78 @abstractproperty
79 def imag(self):
80 """Retrieve the real component of this number.
81
82 This should subclass Real.
83 """
84 raise NotImplementedError
85
86 @abstractmethod
87 def __add__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000088 """self + other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000089 raise NotImplementedError
90
91 @abstractmethod
92 def __radd__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000093 """other + self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000094 raise NotImplementedError
95
96 @abstractmethod
97 def __neg__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000098 """-self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000099 raise NotImplementedError
100
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000101 @abstractmethod
Guido van Rossum1daf9542007-08-30 17:45:54 +0000102 def __pos__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000103 """+self"""
Guido van Rossumd4256302007-12-06 17:45:33 +0000104 raise NotImplementedError
Guido van Rossum1daf9542007-08-30 17:45:54 +0000105
106 def __sub__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000107 """self - other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000108 return self + -other
109
110 def __rsub__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000111 """other - self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000112 return -self + other
113
114 @abstractmethod
115 def __mul__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000116 """self * other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000117 raise NotImplementedError
118
119 @abstractmethod
120 def __rmul__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000121 """other * self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000122 raise NotImplementedError
123
124 @abstractmethod
125 def __div__(self, other):
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000126 """self / other without __future__ division
127
128 May promote to float.
129 """
Guido van Rossum1daf9542007-08-30 17:45:54 +0000130 raise NotImplementedError
131
132 @abstractmethod
133 def __rdiv__(self, other):
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000134 """other / self without __future__ division"""
135 raise NotImplementedError
136
137 @abstractmethod
138 def __truediv__(self, other):
139 """self / other with __future__ division.
140
141 Should promote to float when necessary.
142 """
143 raise NotImplementedError
144
145 @abstractmethod
146 def __rtruediv__(self, other):
147 """other / self with __future__ division"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000148 raise NotImplementedError
149
150 @abstractmethod
151 def __pow__(self, exponent):
Guido van Rossumd4256302007-12-06 17:45:33 +0000152 """self**exponent; should promote to float or complex when necessary."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000153 raise NotImplementedError
154
155 @abstractmethod
156 def __rpow__(self, base):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000157 """base ** self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000158 raise NotImplementedError
159
160 @abstractmethod
161 def __abs__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000162 """Returns the Real distance from 0. Called for abs(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000163 raise NotImplementedError
164
165 @abstractmethod
166 def conjugate(self):
167 """(x+y*i).conjugate() returns (x-y*i)."""
168 raise NotImplementedError
169
170 @abstractmethod
171 def __eq__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000172 """self == other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000173 raise NotImplementedError
174
Guido van Rossumd4256302007-12-06 17:45:33 +0000175 # __ne__ is inherited from object and negates whatever __eq__ does.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000176
177Complex.register(complex)
178
179
180class Real(Complex):
181 """To Complex, Real adds the operations that work on real numbers.
182
183 In short, those are: a conversion to float, trunc(), divmod,
184 %, <, <=, >, and >=.
185
186 Real also provides defaults for the derived operations.
187 """
188
189 @abstractmethod
190 def __float__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000191 """Any Real can be converted to a native float object.
192
193 Called for float(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000194 raise NotImplementedError
195
196 @abstractmethod
197 def __trunc__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000198 """trunc(self): Truncates self to an Integral.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000199
200 Returns an Integral i such that:
Guido van Rossumd4256302007-12-06 17:45:33 +0000201 * i>0 iff self>0;
202 * abs(i) <= abs(self);
203 * for any Integral j satisfying the first two conditions,
204 abs(i) >= abs(j) [i.e. i has "maximal" abs among those].
205 i.e. "truncate towards 0".
206 """
207 raise NotImplementedError
208
209 @abstractmethod
210 def __floor__(self):
211 """Finds the greatest Integral <= self."""
212 raise NotImplementedError
213
214 @abstractmethod
215 def __ceil__(self):
216 """Finds the least Integral >= self."""
217 raise NotImplementedError
218
219 @abstractmethod
220 def __round__(self, ndigits:"Integral"=None):
221 """Rounds self to ndigits decimal places, defaulting to 0.
222
223 If ndigits is omitted or None, returns an Integral, otherwise
224 returns a Real. Rounds half toward even.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000225 """
226 raise NotImplementedError
227
228 def __divmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000229 """divmod(self, other): The pair (self // other, self % other).
Guido van Rossum1daf9542007-08-30 17:45:54 +0000230
231 Sometimes this can be computed faster than the pair of
232 operations.
233 """
234 return (self // other, self % other)
235
236 def __rdivmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000237 """divmod(other, self): The pair (self // other, self % other).
Guido van Rossum1daf9542007-08-30 17:45:54 +0000238
239 Sometimes this can be computed faster than the pair of
240 operations.
241 """
242 return (other // self, other % self)
243
244 @abstractmethod
245 def __floordiv__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000246 """self // other: The floor() of self/other."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000247 raise NotImplementedError
248
249 @abstractmethod
250 def __rfloordiv__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000251 """other // self: The floor() of other/self."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000252 raise NotImplementedError
253
254 @abstractmethod
255 def __mod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000256 """self % other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000257 raise NotImplementedError
258
259 @abstractmethod
260 def __rmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000261 """other % self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000262 raise NotImplementedError
263
264 @abstractmethod
265 def __lt__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000266 """self < other
267
268 < on Reals defines a total ordering, except perhaps for NaN."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000269 raise NotImplementedError
270
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000271 @abstractmethod
Guido van Rossum1daf9542007-08-30 17:45:54 +0000272 def __le__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000273 """self <= other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000274 raise NotImplementedError
275
276 # Concrete implementations of Complex abstract methods.
277 def __complex__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000278 """complex(self) == complex(float(self), 0)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000279 return complex(float(self))
280
281 @property
282 def real(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000283 """Real numbers are their real component."""
Guido van Rossumd4256302007-12-06 17:45:33 +0000284 return +self
Guido van Rossum1daf9542007-08-30 17:45:54 +0000285
286 @property
287 def imag(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000288 """Real numbers have no imaginary component."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000289 return 0
290
291 def conjugate(self):
292 """Conjugate is a no-op for Reals."""
Guido van Rossumd4256302007-12-06 17:45:33 +0000293 return +self
Guido van Rossum1daf9542007-08-30 17:45:54 +0000294
295Real.register(float)
Guido van Rossumd4256302007-12-06 17:45:33 +0000296# Real.register(decimal.Decimal)
Guido van Rossum1daf9542007-08-30 17:45:54 +0000297
298
299class Rational(Real, Exact):
300 """.numerator and .denominator should be in lowest terms."""
301
302 @abstractproperty
303 def numerator(self):
304 raise NotImplementedError
305
306 @abstractproperty
307 def denominator(self):
308 raise NotImplementedError
309
310 # Concrete implementation of Real's conversion to float.
311 def __float__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000312 """float(self) = self.numerator / self.denominator"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000313 return self.numerator / self.denominator
314
315
316class Integral(Rational):
317 """Integral adds a conversion to int and the bit-string operations."""
318
319 @abstractmethod
320 def __int__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000321 """int(self)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000322 raise NotImplementedError
323
324 def __index__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000325 """index(self)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000326 return int(self)
327
328 @abstractmethod
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000329 def __pow__(self, exponent, modulus=None):
Guido van Rossum1daf9542007-08-30 17:45:54 +0000330 """self ** exponent % modulus, but maybe faster.
331
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000332 Accept the modulus argument if you want to support the
333 3-argument version of pow(). Raise a TypeError if exponent < 0
334 or any argument isn't Integral. Otherwise, just implement the
335 2-argument version described in Complex.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000336 """
337 raise NotImplementedError
338
339 @abstractmethod
340 def __lshift__(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 __rlshift__(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 __rshift__(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 __rrshift__(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 __and__(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 __rand__(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 __xor__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000371 """self ^ other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000372 raise NotImplementedError
373
374 @abstractmethod
375 def __rxor__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000376 """other ^ self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000377 raise NotImplementedError
378
379 @abstractmethod
380 def __or__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000381 """self | other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000382 raise NotImplementedError
383
384 @abstractmethod
385 def __ror__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000386 """other | self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000387 raise NotImplementedError
388
389 @abstractmethod
390 def __invert__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000391 """~self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000392 raise NotImplementedError
393
394 # Concrete implementations of Rational and Real abstract methods.
395 def __float__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000396 """float(self) == float(int(self))"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000397 return float(int(self))
398
399 @property
400 def numerator(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000401 """Integers are their own numerators."""
Guido van Rossumd4256302007-12-06 17:45:33 +0000402 return +self
Guido van Rossum1daf9542007-08-30 17:45:54 +0000403
404 @property
405 def denominator(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000406 """Integers have a denominator of 1."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000407 return 1
408
409Integral.register(int)