blob: 34cc803714513e3c914f05d35072affd41e41bc4 [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)
46
47
48class Complex(Number):
49 """Complex defines the operations that work on the builtin complex type.
50
51 In short, those are: a conversion to complex, .real, .imag, +, -,
52 *, /, abs(), .conjugate, ==, and !=.
53
54 If it is given heterogenous arguments, and doesn't have special
55 knowledge about them, it should fall back to the builtin complex
56 type as described below.
57 """
58
59 @abstractmethod
60 def __complex__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000061 """Return a builtin complex instance. Called for complex(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +000062
63 def __bool__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000064 """True if self != 0. Called for bool(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +000065 return self != 0
66
67 @abstractproperty
68 def real(self):
69 """Retrieve the real component of this number.
70
71 This should subclass Real.
72 """
73 raise NotImplementedError
74
75 @abstractproperty
76 def imag(self):
77 """Retrieve the real component of this number.
78
79 This should subclass Real.
80 """
81 raise NotImplementedError
82
83 @abstractmethod
84 def __add__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000085 """self + other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000086 raise NotImplementedError
87
88 @abstractmethod
89 def __radd__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000090 """other + self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000091 raise NotImplementedError
92
93 @abstractmethod
94 def __neg__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000095 """-self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000096 raise NotImplementedError
97
98 def __pos__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000099 """+self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000100 return self
101
102 def __sub__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000103 """self - other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000104 return self + -other
105
106 def __rsub__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000107 """other - self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000108 return -self + other
109
110 @abstractmethod
111 def __mul__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000112 """self * other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000113 raise NotImplementedError
114
115 @abstractmethod
116 def __rmul__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000117 """other * self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000118 raise NotImplementedError
119
120 @abstractmethod
121 def __div__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000122 """self / other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000123 raise NotImplementedError
124
125 @abstractmethod
126 def __rdiv__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000127 """other / self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000128 raise NotImplementedError
129
130 @abstractmethod
131 def __pow__(self, exponent):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000132 """Like division, self**exponent should promote to complex when necessary."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000133 raise NotImplementedError
134
135 @abstractmethod
136 def __rpow__(self, base):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000137 """base ** self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000138 raise NotImplementedError
139
140 @abstractmethod
141 def __abs__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000142 """Returns the Real distance from 0. Called for abs(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000143 raise NotImplementedError
144
145 @abstractmethod
146 def conjugate(self):
147 """(x+y*i).conjugate() returns (x-y*i)."""
148 raise NotImplementedError
149
150 @abstractmethod
151 def __eq__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000152 """self == other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000153 raise NotImplementedError
154
155 def __ne__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000156 """self != other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000157 return not (self == other)
158
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:
183 * i>0 iff self>0
184 * abs(i) <= abs(self).
185 """
186 raise NotImplementedError
187
188 def __divmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000189 """divmod(self, other): The pair (self // other, self % other).
Guido van Rossum1daf9542007-08-30 17:45:54 +0000190
191 Sometimes this can be computed faster than the pair of
192 operations.
193 """
194 return (self // other, self % other)
195
196 def __rdivmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000197 """divmod(other, self): The pair (self // other, self % other).
Guido van Rossum1daf9542007-08-30 17:45:54 +0000198
199 Sometimes this can be computed faster than the pair of
200 operations.
201 """
202 return (other // self, other % self)
203
204 @abstractmethod
205 def __floordiv__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000206 """self // other: The floor() of self/other."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000207 raise NotImplementedError
208
209 @abstractmethod
210 def __rfloordiv__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000211 """other // self: The floor() of other/self."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000212 raise NotImplementedError
213
214 @abstractmethod
215 def __mod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000216 """self % other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000217 raise NotImplementedError
218
219 @abstractmethod
220 def __rmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000221 """other % self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000222 raise NotImplementedError
223
224 @abstractmethod
225 def __lt__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000226 """self < other
227
228 < on Reals defines a total ordering, except perhaps for NaN."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000229 raise NotImplementedError
230
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000231 @abstractmethod
Guido van Rossum1daf9542007-08-30 17:45:54 +0000232 def __le__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000233 """self <= other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000234 raise NotImplementedError
235
236 # Concrete implementations of Complex abstract methods.
237 def __complex__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000238 """complex(self) == complex(float(self), 0)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000239 return complex(float(self))
240
241 @property
242 def real(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000243 """Real numbers are their real component."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000244 return self
245
246 @property
247 def imag(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000248 """Real numbers have no imaginary component."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000249 return 0
250
251 def conjugate(self):
252 """Conjugate is a no-op for Reals."""
253 return self
254
255Real.register(float)
256
257
258class Rational(Real, Exact):
259 """.numerator and .denominator should be in lowest terms."""
260
261 @abstractproperty
262 def numerator(self):
263 raise NotImplementedError
264
265 @abstractproperty
266 def denominator(self):
267 raise NotImplementedError
268
269 # Concrete implementation of Real's conversion to float.
270 def __float__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000271 """float(self) = self.numerator / self.denominator"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000272 return self.numerator / self.denominator
273
274
275class Integral(Rational):
276 """Integral adds a conversion to int and the bit-string operations."""
277
278 @abstractmethod
279 def __int__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000280 """int(self)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000281 raise NotImplementedError
282
283 def __index__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000284 """index(self)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000285 return int(self)
286
287 @abstractmethod
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000288 def __pow__(self, exponent, modulus=None):
Guido van Rossum1daf9542007-08-30 17:45:54 +0000289 """self ** exponent % modulus, but maybe faster.
290
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000291 Accept the modulus argument if you want to support the
292 3-argument version of pow(). Raise a TypeError if exponent < 0
293 or any argument isn't Integral. Otherwise, just implement the
294 2-argument version described in Complex.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000295 """
296 raise NotImplementedError
297
298 @abstractmethod
299 def __lshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000300 """self << other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000301 raise NotImplementedError
302
303 @abstractmethod
304 def __rlshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000305 """other << self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000306 raise NotImplementedError
307
308 @abstractmethod
309 def __rshift__(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 __rrshift__(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 __and__(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 __rand__(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 __xor__(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 __rxor__(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 __or__(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 __ror__(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 __invert__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000350 """~self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000351 raise NotImplementedError
352
353 # Concrete implementations of Rational and Real abstract methods.
354 def __float__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000355 """float(self) == float(int(self))"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000356 return float(int(self))
357
358 @property
359 def numerator(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000360 """Integers are their own numerators."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000361 return self
362
363 @property
364 def denominator(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000365 """Integers have a denominator of 1."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000366 return 1
367
368Integral.register(int)