|
1 # Copyright 2007 Google, Inc. All Rights Reserved. |
|
2 # Licensed to PSF under a Contributor Agreement. |
|
3 |
|
4 """Abstract Base Classes (ABCs) for numbers, according to PEP 3141. |
|
5 |
|
6 TODO: Fill out more detailed documentation on the operators.""" |
|
7 |
|
8 from __future__ import division |
|
9 from abc import ABCMeta, abstractmethod, abstractproperty |
|
10 |
|
11 __all__ = ["Number", "Complex", "Real", "Rational", "Integral"] |
|
12 |
|
13 class Number(object): |
|
14 """All numbers inherit from this class. |
|
15 |
|
16 If you just want to check if an argument x is a number, without |
|
17 caring what kind, use isinstance(x, Number). |
|
18 """ |
|
19 __metaclass__ = ABCMeta |
|
20 |
|
21 # Concrete numeric types must provide their own hash implementation |
|
22 __hash__ = None |
|
23 |
|
24 |
|
25 ## Notes on Decimal |
|
26 ## ---------------- |
|
27 ## Decimal has all of the methods specified by the Real abc, but it should |
|
28 ## not be registered as a Real because decimals do not interoperate with |
|
29 ## binary floats (i.e. Decimal('3.14') + 2.71828 is undefined). But, |
|
30 ## abstract reals are expected to interoperate (i.e. R1 + R2 should be |
|
31 ## expected to work if R1 and R2 are both Reals). |
|
32 |
|
33 class Complex(Number): |
|
34 """Complex defines the operations that work on the builtin complex type. |
|
35 |
|
36 In short, those are: a conversion to complex, .real, .imag, +, -, |
|
37 *, /, abs(), .conjugate, ==, and !=. |
|
38 |
|
39 If it is given heterogenous arguments, and doesn't have special |
|
40 knowledge about them, it should fall back to the builtin complex |
|
41 type as described below. |
|
42 """ |
|
43 |
|
44 @abstractmethod |
|
45 def __complex__(self): |
|
46 """Return a builtin complex instance. Called for complex(self).""" |
|
47 |
|
48 # Will be __bool__ in 3.0. |
|
49 def __nonzero__(self): |
|
50 """True if self != 0. Called for bool(self).""" |
|
51 return self != 0 |
|
52 |
|
53 @abstractproperty |
|
54 def real(self): |
|
55 """Retrieve the real component of this number. |
|
56 |
|
57 This should subclass Real. |
|
58 """ |
|
59 raise NotImplementedError |
|
60 |
|
61 @abstractproperty |
|
62 def imag(self): |
|
63 """Retrieve the real component of this number. |
|
64 |
|
65 This should subclass Real. |
|
66 """ |
|
67 raise NotImplementedError |
|
68 |
|
69 @abstractmethod |
|
70 def __add__(self, other): |
|
71 """self + other""" |
|
72 raise NotImplementedError |
|
73 |
|
74 @abstractmethod |
|
75 def __radd__(self, other): |
|
76 """other + self""" |
|
77 raise NotImplementedError |
|
78 |
|
79 @abstractmethod |
|
80 def __neg__(self): |
|
81 """-self""" |
|
82 raise NotImplementedError |
|
83 |
|
84 @abstractmethod |
|
85 def __pos__(self): |
|
86 """+self""" |
|
87 raise NotImplementedError |
|
88 |
|
89 def __sub__(self, other): |
|
90 """self - other""" |
|
91 return self + -other |
|
92 |
|
93 def __rsub__(self, other): |
|
94 """other - self""" |
|
95 return -self + other |
|
96 |
|
97 @abstractmethod |
|
98 def __mul__(self, other): |
|
99 """self * other""" |
|
100 raise NotImplementedError |
|
101 |
|
102 @abstractmethod |
|
103 def __rmul__(self, other): |
|
104 """other * self""" |
|
105 raise NotImplementedError |
|
106 |
|
107 @abstractmethod |
|
108 def __div__(self, other): |
|
109 """self / other without __future__ division |
|
110 |
|
111 May promote to float. |
|
112 """ |
|
113 raise NotImplementedError |
|
114 |
|
115 @abstractmethod |
|
116 def __rdiv__(self, other): |
|
117 """other / self without __future__ division""" |
|
118 raise NotImplementedError |
|
119 |
|
120 @abstractmethod |
|
121 def __truediv__(self, other): |
|
122 """self / other with __future__ division. |
|
123 |
|
124 Should promote to float when necessary. |
|
125 """ |
|
126 raise NotImplementedError |
|
127 |
|
128 @abstractmethod |
|
129 def __rtruediv__(self, other): |
|
130 """other / self with __future__ division""" |
|
131 raise NotImplementedError |
|
132 |
|
133 @abstractmethod |
|
134 def __pow__(self, exponent): |
|
135 """self**exponent; should promote to float or complex when necessary.""" |
|
136 raise NotImplementedError |
|
137 |
|
138 @abstractmethod |
|
139 def __rpow__(self, base): |
|
140 """base ** self""" |
|
141 raise NotImplementedError |
|
142 |
|
143 @abstractmethod |
|
144 def __abs__(self): |
|
145 """Returns the Real distance from 0. Called for abs(self).""" |
|
146 raise NotImplementedError |
|
147 |
|
148 @abstractmethod |
|
149 def conjugate(self): |
|
150 """(x+y*i).conjugate() returns (x-y*i).""" |
|
151 raise NotImplementedError |
|
152 |
|
153 @abstractmethod |
|
154 def __eq__(self, other): |
|
155 """self == other""" |
|
156 raise NotImplementedError |
|
157 |
|
158 def __ne__(self, other): |
|
159 """self != other""" |
|
160 # The default __ne__ doesn't negate __eq__ until 3.0. |
|
161 return not (self == other) |
|
162 |
|
163 Complex.register(complex) |
|
164 |
|
165 |
|
166 class Real(Complex): |
|
167 """To Complex, Real adds the operations that work on real numbers. |
|
168 |
|
169 In short, those are: a conversion to float, trunc(), divmod, |
|
170 %, <, <=, >, and >=. |
|
171 |
|
172 Real also provides defaults for the derived operations. |
|
173 """ |
|
174 |
|
175 @abstractmethod |
|
176 def __float__(self): |
|
177 """Any Real can be converted to a native float object. |
|
178 |
|
179 Called for float(self).""" |
|
180 raise NotImplementedError |
|
181 |
|
182 @abstractmethod |
|
183 def __trunc__(self): |
|
184 """trunc(self): Truncates self to an Integral. |
|
185 |
|
186 Returns an Integral i such that: |
|
187 * i>0 iff self>0; |
|
188 * abs(i) <= abs(self); |
|
189 * for any Integral j satisfying the first two conditions, |
|
190 abs(i) >= abs(j) [i.e. i has "maximal" abs among those]. |
|
191 i.e. "truncate towards 0". |
|
192 """ |
|
193 raise NotImplementedError |
|
194 |
|
195 def __divmod__(self, other): |
|
196 """divmod(self, other): The pair (self // other, self % other). |
|
197 |
|
198 Sometimes this can be computed faster than the pair of |
|
199 operations. |
|
200 """ |
|
201 return (self // other, self % other) |
|
202 |
|
203 def __rdivmod__(self, other): |
|
204 """divmod(other, self): The pair (self // other, self % other). |
|
205 |
|
206 Sometimes this can be computed faster than the pair of |
|
207 operations. |
|
208 """ |
|
209 return (other // self, other % self) |
|
210 |
|
211 @abstractmethod |
|
212 def __floordiv__(self, other): |
|
213 """self // other: The floor() of self/other.""" |
|
214 raise NotImplementedError |
|
215 |
|
216 @abstractmethod |
|
217 def __rfloordiv__(self, other): |
|
218 """other // self: The floor() of other/self.""" |
|
219 raise NotImplementedError |
|
220 |
|
221 @abstractmethod |
|
222 def __mod__(self, other): |
|
223 """self % other""" |
|
224 raise NotImplementedError |
|
225 |
|
226 @abstractmethod |
|
227 def __rmod__(self, other): |
|
228 """other % self""" |
|
229 raise NotImplementedError |
|
230 |
|
231 @abstractmethod |
|
232 def __lt__(self, other): |
|
233 """self < other |
|
234 |
|
235 < on Reals defines a total ordering, except perhaps for NaN.""" |
|
236 raise NotImplementedError |
|
237 |
|
238 @abstractmethod |
|
239 def __le__(self, other): |
|
240 """self <= other""" |
|
241 raise NotImplementedError |
|
242 |
|
243 # Concrete implementations of Complex abstract methods. |
|
244 def __complex__(self): |
|
245 """complex(self) == complex(float(self), 0)""" |
|
246 return complex(float(self)) |
|
247 |
|
248 @property |
|
249 def real(self): |
|
250 """Real numbers are their real component.""" |
|
251 return +self |
|
252 |
|
253 @property |
|
254 def imag(self): |
|
255 """Real numbers have no imaginary component.""" |
|
256 return 0 |
|
257 |
|
258 def conjugate(self): |
|
259 """Conjugate is a no-op for Reals.""" |
|
260 return +self |
|
261 |
|
262 Real.register(float) |
|
263 |
|
264 |
|
265 class Rational(Real): |
|
266 """.numerator and .denominator should be in lowest terms.""" |
|
267 |
|
268 @abstractproperty |
|
269 def numerator(self): |
|
270 raise NotImplementedError |
|
271 |
|
272 @abstractproperty |
|
273 def denominator(self): |
|
274 raise NotImplementedError |
|
275 |
|
276 # Concrete implementation of Real's conversion to float. |
|
277 def __float__(self): |
|
278 """float(self) = self.numerator / self.denominator |
|
279 |
|
280 It's important that this conversion use the integer's "true" |
|
281 division rather than casting one side to float before dividing |
|
282 so that ratios of huge integers convert without overflowing. |
|
283 |
|
284 """ |
|
285 return self.numerator / self.denominator |
|
286 |
|
287 |
|
288 class Integral(Rational): |
|
289 """Integral adds a conversion to long and the bit-string operations.""" |
|
290 |
|
291 @abstractmethod |
|
292 def __long__(self): |
|
293 """long(self)""" |
|
294 raise NotImplementedError |
|
295 |
|
296 def __index__(self): |
|
297 """index(self)""" |
|
298 return long(self) |
|
299 |
|
300 @abstractmethod |
|
301 def __pow__(self, exponent, modulus=None): |
|
302 """self ** exponent % modulus, but maybe faster. |
|
303 |
|
304 Accept the modulus argument if you want to support the |
|
305 3-argument version of pow(). Raise a TypeError if exponent < 0 |
|
306 or any argument isn't Integral. Otherwise, just implement the |
|
307 2-argument version described in Complex. |
|
308 """ |
|
309 raise NotImplementedError |
|
310 |
|
311 @abstractmethod |
|
312 def __lshift__(self, other): |
|
313 """self << other""" |
|
314 raise NotImplementedError |
|
315 |
|
316 @abstractmethod |
|
317 def __rlshift__(self, other): |
|
318 """other << self""" |
|
319 raise NotImplementedError |
|
320 |
|
321 @abstractmethod |
|
322 def __rshift__(self, other): |
|
323 """self >> other""" |
|
324 raise NotImplementedError |
|
325 |
|
326 @abstractmethod |
|
327 def __rrshift__(self, other): |
|
328 """other >> self""" |
|
329 raise NotImplementedError |
|
330 |
|
331 @abstractmethod |
|
332 def __and__(self, other): |
|
333 """self & other""" |
|
334 raise NotImplementedError |
|
335 |
|
336 @abstractmethod |
|
337 def __rand__(self, other): |
|
338 """other & self""" |
|
339 raise NotImplementedError |
|
340 |
|
341 @abstractmethod |
|
342 def __xor__(self, other): |
|
343 """self ^ other""" |
|
344 raise NotImplementedError |
|
345 |
|
346 @abstractmethod |
|
347 def __rxor__(self, other): |
|
348 """other ^ self""" |
|
349 raise NotImplementedError |
|
350 |
|
351 @abstractmethod |
|
352 def __or__(self, other): |
|
353 """self | other""" |
|
354 raise NotImplementedError |
|
355 |
|
356 @abstractmethod |
|
357 def __ror__(self, other): |
|
358 """other | self""" |
|
359 raise NotImplementedError |
|
360 |
|
361 @abstractmethod |
|
362 def __invert__(self): |
|
363 """~self""" |
|
364 raise NotImplementedError |
|
365 |
|
366 # Concrete implementations of Rational and Real abstract methods. |
|
367 def __float__(self): |
|
368 """float(self) == float(long(self))""" |
|
369 return float(long(self)) |
|
370 |
|
371 @property |
|
372 def numerator(self): |
|
373 """Integers are their own numerators.""" |
|
374 return +self |
|
375 |
|
376 @property |
|
377 def denominator(self): |
|
378 """Integers have a denominator of 1.""" |
|
379 return 1 |
|
380 |
|
381 Integral.register(int) |
|
382 Integral.register(long) |