blob: 4dd5ca717593cb1be5051204b001307b1c8c9758 [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
10__all__ = ["Number", "Exact", "Inexact",
11 "Complex", "Real", "Rational", "Integral",
12 ]
13
14
15class Number(metaclass=ABCMeta):
16 """All numbers inherit from this class.
17
18 If you just want to check if an argument x is a number, without
19 caring what kind, use isinstance(x, Number).
20 """
21
22
23class Exact(Number):
24 """Operations on instances of this type are exact.
25
26 As long as the result of a homogenous operation is of the same
27 type, you can assume that it was computed exactly, and there are
28 no round-off errors. Laws like commutativity and associativity
29 hold.
30 """
31
32Exact.register(int)
33
34
35class Inexact(Number):
36 """Operations on instances of this type are inexact.
37
38 Given X, an instance of Inexact, it is possible that (X + -X) + 3
39 == 3, but X + (-X + 3) == 0. The exact form this error takes will
40 vary by type, but it's generally unsafe to compare this type for
41 equality.
42 """
43
44Inexact.register(complex)
45Inexact.register(float)
Guido van Rossumd4256302007-12-06 17:45:33 +000046# Inexact.register(decimal.Decimal)
Guido van Rossum1daf9542007-08-30 17:45:54 +000047
48
49class Complex(Number):
50 """Complex defines the operations that work on the builtin complex type.
51
52 In short, those are: a conversion to complex, .real, .imag, +, -,
53 *, /, abs(), .conjugate, ==, and !=.
54
55 If it is given heterogenous arguments, and doesn't have special
56 knowledge about them, it should fall back to the builtin complex
57 type as described below.
58 """
59
60 @abstractmethod
61 def __complex__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000062 """Return a builtin complex instance. Called for complex(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +000063
Jeffrey Yasskin9893de12008-01-17 07:36:30 +000064 def __bool__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000065 """True if self != 0. Called for bool(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +000066 return self != 0
67
68 @abstractproperty
69 def real(self):
70 """Retrieve the real component of this number.
71
72 This should subclass Real.
73 """
74 raise NotImplementedError
75
76 @abstractproperty
77 def imag(self):
78 """Retrieve the real component of this number.
79
80 This should subclass Real.
81 """
82 raise NotImplementedError
83
84 @abstractmethod
85 def __add__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000086 """self + other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000087 raise NotImplementedError
88
89 @abstractmethod
90 def __radd__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000091 """other + self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000092 raise NotImplementedError
93
94 @abstractmethod
95 def __neg__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000096 """-self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000097 raise NotImplementedError
98
Guido van Rossum7736b5b2008-01-15 21:44:53 +000099 @abstractmethod
Guido van Rossum1daf9542007-08-30 17:45:54 +0000100 def __pos__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000101 """+self"""
Guido van Rossumd4256302007-12-06 17:45:33 +0000102 raise NotImplementedError
Guido van Rossum1daf9542007-08-30 17:45:54 +0000103
104 def __sub__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000105 """self - other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000106 return self + -other
107
108 def __rsub__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000109 """other - self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000110 return -self + other
111
112 @abstractmethod
113 def __mul__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000114 """self * other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000115 raise NotImplementedError
116
117 @abstractmethod
118 def __rmul__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000119 """other * self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000120 raise NotImplementedError
121
122 @abstractmethod
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000123 def __truediv__(self, other):
Jeffrey Yasskin9893de12008-01-17 07:36:30 +0000124 """self / other: Should promote to float when necessary."""
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000125 raise NotImplementedError
126
127 @abstractmethod
128 def __rtruediv__(self, other):
Jeffrey Yasskin9893de12008-01-17 07:36:30 +0000129 """other / self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000130 raise NotImplementedError
131
132 @abstractmethod
133 def __pow__(self, exponent):
Guido van Rossumd4256302007-12-06 17:45:33 +0000134 """self**exponent; should promote to float or complex when necessary."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000135 raise NotImplementedError
136
137 @abstractmethod
138 def __rpow__(self, base):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000139 """base ** self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000140 raise NotImplementedError
141
142 @abstractmethod
143 def __abs__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000144 """Returns the Real distance from 0. Called for abs(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000145 raise NotImplementedError
146
147 @abstractmethod
148 def conjugate(self):
149 """(x+y*i).conjugate() returns (x-y*i)."""
150 raise NotImplementedError
151
152 @abstractmethod
153 def __eq__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000154 """self == other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000155 raise NotImplementedError
156
Guido van Rossumd4256302007-12-06 17:45:33 +0000157 # __ne__ is inherited from object and negates whatever __eq__ does.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000158
159Complex.register(complex)
160
161
162class Real(Complex):
163 """To Complex, Real adds the operations that work on real numbers.
164
165 In short, those are: a conversion to float, trunc(), divmod,
166 %, <, <=, >, and >=.
167
168 Real also provides defaults for the derived operations.
169 """
170
171 @abstractmethod
172 def __float__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000173 """Any Real can be converted to a native float object.
174
175 Called for float(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000176 raise NotImplementedError
177
178 @abstractmethod
179 def __trunc__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000180 """trunc(self): Truncates self to an Integral.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000181
182 Returns an Integral i such that:
Guido van Rossumd4256302007-12-06 17:45:33 +0000183 * i>0 iff self>0;
184 * abs(i) <= abs(self);
185 * for any Integral j satisfying the first two conditions,
186 abs(i) >= abs(j) [i.e. i has "maximal" abs among those].
187 i.e. "truncate towards 0".
188 """
189 raise NotImplementedError
190
191 @abstractmethod
192 def __floor__(self):
193 """Finds the greatest Integral <= self."""
194 raise NotImplementedError
195
196 @abstractmethod
197 def __ceil__(self):
198 """Finds the least Integral >= self."""
199 raise NotImplementedError
200
201 @abstractmethod
202 def __round__(self, ndigits:"Integral"=None):
203 """Rounds self to ndigits decimal places, defaulting to 0.
204
205 If ndigits is omitted or None, returns an Integral, otherwise
206 returns a Real. Rounds half toward even.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000207 """
208 raise NotImplementedError
209
210 def __divmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000211 """divmod(self, other): The pair (self // other, self % other).
Guido van Rossum1daf9542007-08-30 17:45:54 +0000212
213 Sometimes this can be computed faster than the pair of
214 operations.
215 """
216 return (self // other, self % other)
217
218 def __rdivmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000219 """divmod(other, self): The pair (self // other, self % other).
Guido van Rossum1daf9542007-08-30 17:45:54 +0000220
221 Sometimes this can be computed faster than the pair of
222 operations.
223 """
224 return (other // self, other % self)
225
226 @abstractmethod
227 def __floordiv__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000228 """self // other: The floor() of self/other."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000229 raise NotImplementedError
230
231 @abstractmethod
232 def __rfloordiv__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000233 """other // self: The floor() of other/self."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000234 raise NotImplementedError
235
236 @abstractmethod
237 def __mod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000238 """self % other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000239 raise NotImplementedError
240
241 @abstractmethod
242 def __rmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000243 """other % self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000244 raise NotImplementedError
245
246 @abstractmethod
247 def __lt__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000248 """self < other
249
250 < on Reals defines a total ordering, except perhaps for NaN."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000251 raise NotImplementedError
252
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000253 @abstractmethod
Guido van Rossum1daf9542007-08-30 17:45:54 +0000254 def __le__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000255 """self <= other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000256 raise NotImplementedError
257
258 # Concrete implementations of Complex abstract methods.
259 def __complex__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000260 """complex(self) == complex(float(self), 0)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000261 return complex(float(self))
262
263 @property
264 def real(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000265 """Real numbers are their real component."""
Guido van Rossumd4256302007-12-06 17:45:33 +0000266 return +self
Guido van Rossum1daf9542007-08-30 17:45:54 +0000267
268 @property
269 def imag(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000270 """Real numbers have no imaginary component."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000271 return 0
272
273 def conjugate(self):
274 """Conjugate is a no-op for Reals."""
Guido van Rossumd4256302007-12-06 17:45:33 +0000275 return +self
Guido van Rossum1daf9542007-08-30 17:45:54 +0000276
277Real.register(float)
Guido van Rossumd4256302007-12-06 17:45:33 +0000278# Real.register(decimal.Decimal)
Guido van Rossum1daf9542007-08-30 17:45:54 +0000279
280
281class Rational(Real, Exact):
282 """.numerator and .denominator should be in lowest terms."""
283
284 @abstractproperty
285 def numerator(self):
286 raise NotImplementedError
287
288 @abstractproperty
289 def denominator(self):
290 raise NotImplementedError
291
292 # Concrete implementation of Real's conversion to float.
293 def __float__(self):
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000294 """float(self) = self.numerator / self.denominator
295
296 It's important that this conversion use the integer's "true"
297 division rather than casting one side to float before dividing
298 so that ratios of huge integers convert without overflowing.
299
300 """
Guido van Rossum1daf9542007-08-30 17:45:54 +0000301 return self.numerator / self.denominator
302
303
304class Integral(Rational):
305 """Integral adds a conversion to int and the bit-string operations."""
306
307 @abstractmethod
308 def __int__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000309 """int(self)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000310 raise NotImplementedError
311
312 def __index__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000313 """index(self)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000314 return int(self)
315
316 @abstractmethod
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000317 def __pow__(self, exponent, modulus=None):
Guido van Rossum1daf9542007-08-30 17:45:54 +0000318 """self ** exponent % modulus, but maybe faster.
319
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000320 Accept the modulus argument if you want to support the
321 3-argument version of pow(). Raise a TypeError if exponent < 0
322 or any argument isn't Integral. Otherwise, just implement the
323 2-argument version described in Complex.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000324 """
325 raise NotImplementedError
326
327 @abstractmethod
328 def __lshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000329 """self << other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000330 raise NotImplementedError
331
332 @abstractmethod
333 def __rlshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000334 """other << self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000335 raise NotImplementedError
336
337 @abstractmethod
338 def __rshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000339 """self >> other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000340 raise NotImplementedError
341
342 @abstractmethod
343 def __rrshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000344 """other >> self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000345 raise NotImplementedError
346
347 @abstractmethod
348 def __and__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000349 """self & other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000350 raise NotImplementedError
351
352 @abstractmethod
353 def __rand__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000354 """other & self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000355 raise NotImplementedError
356
357 @abstractmethod
358 def __xor__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000359 """self ^ other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000360 raise NotImplementedError
361
362 @abstractmethod
363 def __rxor__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000364 """other ^ self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000365 raise NotImplementedError
366
367 @abstractmethod
368 def __or__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000369 """self | other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000370 raise NotImplementedError
371
372 @abstractmethod
373 def __ror__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000374 """other | self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000375 raise NotImplementedError
376
377 @abstractmethod
378 def __invert__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000379 """~self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000380 raise NotImplementedError
381
382 # Concrete implementations of Rational and Real abstract methods.
383 def __float__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000384 """float(self) == float(int(self))"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000385 return float(int(self))
386
387 @property
388 def numerator(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000389 """Integers are their own numerators."""
Guido van Rossumd4256302007-12-06 17:45:33 +0000390 return +self
Guido van Rossum1daf9542007-08-30 17:45:54 +0000391
392 @property
393 def denominator(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000394 """Integers have a denominator of 1."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000395 return 1
396
397Integral.register(int)