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