blob: 6c3c3e1110948f6a6771da482a08d53df76952aa [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):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000294 """float(self) = self.numerator / self.denominator"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000295 return self.numerator / self.denominator
296
297
298class Integral(Rational):
299 """Integral adds a conversion to int and the bit-string operations."""
300
301 @abstractmethod
302 def __int__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000303 """int(self)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000304 raise NotImplementedError
305
306 def __index__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000307 """index(self)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000308 return int(self)
309
310 @abstractmethod
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000311 def __pow__(self, exponent, modulus=None):
Guido van Rossum1daf9542007-08-30 17:45:54 +0000312 """self ** exponent % modulus, but maybe faster.
313
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000314 Accept the modulus argument if you want to support the
315 3-argument version of pow(). Raise a TypeError if exponent < 0
316 or any argument isn't Integral. Otherwise, just implement the
317 2-argument version described in Complex.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000318 """
319 raise NotImplementedError
320
321 @abstractmethod
322 def __lshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000323 """self << other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000324 raise NotImplementedError
325
326 @abstractmethod
327 def __rlshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000328 """other << self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000329 raise NotImplementedError
330
331 @abstractmethod
332 def __rshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000333 """self >> other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000334 raise NotImplementedError
335
336 @abstractmethod
337 def __rrshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000338 """other >> self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000339 raise NotImplementedError
340
341 @abstractmethod
342 def __and__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000343 """self & other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000344 raise NotImplementedError
345
346 @abstractmethod
347 def __rand__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000348 """other & self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000349 raise NotImplementedError
350
351 @abstractmethod
352 def __xor__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000353 """self ^ other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000354 raise NotImplementedError
355
356 @abstractmethod
357 def __rxor__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000358 """other ^ self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000359 raise NotImplementedError
360
361 @abstractmethod
362 def __or__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000363 """self | other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000364 raise NotImplementedError
365
366 @abstractmethod
367 def __ror__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000368 """other | self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000369 raise NotImplementedError
370
371 @abstractmethod
372 def __invert__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000373 """~self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000374 raise NotImplementedError
375
376 # Concrete implementations of Rational and Real abstract methods.
377 def __float__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000378 """float(self) == float(int(self))"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000379 return float(int(self))
380
381 @property
382 def numerator(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000383 """Integers are their own numerators."""
Guido van Rossumd4256302007-12-06 17:45:33 +0000384 return +self
Guido van Rossum1daf9542007-08-30 17:45:54 +0000385
386 @property
387 def denominator(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000388 """Integers have a denominator of 1."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000389 return 1
390
391Integral.register(int)