blob: 972fe1fd594a2e1b188116f394978bc4cd939bab [file] [log] [blame]
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +00001# 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
6TODO: Fill out more detailed documentation on the operators."""
7
Jeffrey Yasskind7b00332008-01-15 07:46:24 +00008from __future__ import division
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +00009from abc import ABCMeta, abstractmethod, abstractproperty
10
Raymond Hettinger6b467622008-03-15 20:02:04 +000011__all__ = ["Number", "Complex", "Real", "Rational", "Integral"]
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +000012
13class 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
Raymond Hettingerddb164a2008-02-14 01:08:02 +000022## Notes on Decimal
23## ----------------
24## Decimal has all of the methods specified by the Real abc, but it should
25## not be registered as a Real because decimals do not interoperate with
Raymond Hettinger6b467622008-03-15 20:02:04 +000026## binary floats (i.e. Decimal('3.14') + 2.71828 is undefined). But,
27## abstract reals are expected to interoperate (i.e. R1 + R2 should be
28## expected to work if R1 and R2 are both Reals).
Raymond Hettinger48688d82008-02-11 22:53:01 +000029
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +000030class Complex(Number):
31 """Complex defines the operations that work on the builtin complex type.
32
33 In short, those are: a conversion to complex, .real, .imag, +, -,
34 *, /, abs(), .conjugate, ==, and !=.
35
36 If it is given heterogenous arguments, and doesn't have special
37 knowledge about them, it should fall back to the builtin complex
38 type as described below.
39 """
40
41 @abstractmethod
42 def __complex__(self):
43 """Return a builtin complex instance. Called for complex(self)."""
44
Jeffrey Yasskind7b00332008-01-15 07:46:24 +000045 # Will be __bool__ in 3.0.
46 def __nonzero__(self):
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +000047 """True if self != 0. Called for bool(self)."""
48 return self != 0
49
50 @abstractproperty
51 def real(self):
52 """Retrieve the real component of this number.
53
54 This should subclass Real.
55 """
56 raise NotImplementedError
57
58 @abstractproperty
59 def imag(self):
60 """Retrieve the real component of this number.
61
62 This should subclass Real.
63 """
64 raise NotImplementedError
65
66 @abstractmethod
67 def __add__(self, other):
68 """self + other"""
69 raise NotImplementedError
70
71 @abstractmethod
72 def __radd__(self, other):
73 """other + self"""
74 raise NotImplementedError
75
76 @abstractmethod
77 def __neg__(self):
78 """-self"""
79 raise NotImplementedError
80
Jeffrey Yasskind7b00332008-01-15 07:46:24 +000081 @abstractmethod
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +000082 def __pos__(self):
83 """+self"""
84 raise NotImplementedError
85
86 def __sub__(self, other):
87 """self - other"""
88 return self + -other
89
90 def __rsub__(self, other):
91 """other - self"""
92 return -self + other
93
94 @abstractmethod
95 def __mul__(self, other):
96 """self * other"""
97 raise NotImplementedError
98
99 @abstractmethod
100 def __rmul__(self, other):
101 """other * self"""
102 raise NotImplementedError
103
104 @abstractmethod
105 def __div__(self, other):
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000106 """self / other without __future__ division
107
108 May promote to float.
109 """
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000110 raise NotImplementedError
111
112 @abstractmethod
113 def __rdiv__(self, other):
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000114 """other / self without __future__ division"""
115 raise NotImplementedError
116
117 @abstractmethod
118 def __truediv__(self, other):
119 """self / other with __future__ division.
120
121 Should promote to float when necessary.
122 """
123 raise NotImplementedError
124
125 @abstractmethod
126 def __rtruediv__(self, other):
127 """other / self with __future__ division"""
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000128 raise NotImplementedError
129
130 @abstractmethod
131 def __pow__(self, exponent):
132 """self**exponent; should promote to float or complex when necessary."""
133 raise NotImplementedError
134
135 @abstractmethod
136 def __rpow__(self, base):
137 """base ** self"""
138 raise NotImplementedError
139
140 @abstractmethod
141 def __abs__(self):
142 """Returns the Real distance from 0. Called for abs(self)."""
143 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):
152 """self == other"""
153 raise NotImplementedError
154
Jeffrey Yasskin27d33942008-02-08 06:45:40 +0000155 def __ne__(self, other):
156 """self != other"""
157 # The default __ne__ doesn't negate __eq__ until 3.0.
158 return not (self == other)
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000159
160Complex.register(complex)
161
162
163class Real(Complex):
164 """To Complex, Real adds the operations that work on real numbers.
165
166 In short, those are: a conversion to float, trunc(), divmod,
167 %, <, <=, >, and >=.
168
169 Real also provides defaults for the derived operations.
170 """
171
172 @abstractmethod
173 def __float__(self):
174 """Any Real can be converted to a native float object.
175
176 Called for float(self)."""
177 raise NotImplementedError
178
179 @abstractmethod
180 def __trunc__(self):
181 """trunc(self): Truncates self to an Integral.
182
183 Returns an Integral i such that:
184 * i>0 iff self>0;
185 * abs(i) <= abs(self);
186 * for any Integral j satisfying the first two conditions,
187 abs(i) >= abs(j) [i.e. i has "maximal" abs among those].
188 i.e. "truncate towards 0".
189 """
190 raise NotImplementedError
191
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000192 def __divmod__(self, other):
193 """divmod(self, other): The pair (self // other, self % other).
194
195 Sometimes this can be computed faster than the pair of
196 operations.
197 """
198 return (self // other, self % other)
199
200 def __rdivmod__(self, other):
201 """divmod(other, self): The pair (self // other, self % other).
202
203 Sometimes this can be computed faster than the pair of
204 operations.
205 """
206 return (other // self, other % self)
207
208 @abstractmethod
209 def __floordiv__(self, other):
210 """self // other: The floor() of self/other."""
211 raise NotImplementedError
212
213 @abstractmethod
214 def __rfloordiv__(self, other):
215 """other // self: The floor() of other/self."""
216 raise NotImplementedError
217
218 @abstractmethod
219 def __mod__(self, other):
220 """self % other"""
221 raise NotImplementedError
222
223 @abstractmethod
224 def __rmod__(self, other):
225 """other % self"""
226 raise NotImplementedError
227
228 @abstractmethod
229 def __lt__(self, other):
230 """self < other
231
232 < on Reals defines a total ordering, except perhaps for NaN."""
233 raise NotImplementedError
234
235 @abstractmethod
236 def __le__(self, other):
237 """self <= other"""
238 raise NotImplementedError
239
240 # Concrete implementations of Complex abstract methods.
241 def __complex__(self):
242 """complex(self) == complex(float(self), 0)"""
243 return complex(float(self))
244
245 @property
246 def real(self):
247 """Real numbers are their real component."""
248 return +self
249
250 @property
251 def imag(self):
252 """Real numbers have no imaginary component."""
253 return 0
254
255 def conjugate(self):
256 """Conjugate is a no-op for Reals."""
257 return +self
258
259Real.register(float)
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000260
261
Raymond Hettingercd6bfab2008-03-15 20:37:50 +0000262class Rational(Real):
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000263 """.numerator and .denominator should be in lowest terms."""
264
265 @abstractproperty
266 def numerator(self):
267 raise NotImplementedError
268
269 @abstractproperty
270 def denominator(self):
271 raise NotImplementedError
272
273 # Concrete implementation of Real's conversion to float.
274 def __float__(self):
Jeffrey Yasskinb23dea62008-01-31 07:44:11 +0000275 """float(self) = self.numerator / self.denominator
276
277 It's important that this conversion use the integer's "true"
278 division rather than casting one side to float before dividing
279 so that ratios of huge integers convert without overflowing.
280
281 """
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000282 return self.numerator / self.denominator
283
284
285class Integral(Rational):
Raymond Hettingercaea65e2008-06-11 00:25:29 +0000286 """Integral adds a conversion to int and the bit-string operations."""
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000287
288 @abstractmethod
Raymond Hettingercaea65e2008-06-11 00:25:29 +0000289 def __int__(self):
290 """int(self)"""
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000291 raise NotImplementedError
292
293 def __index__(self):
294 """index(self)"""
Raymond Hettingercaea65e2008-06-11 00:25:29 +0000295 return int(self)
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000296
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000297 def __lshift__(self, other):
Raymond Hettingercaea65e2008-06-11 00:25:29 +0000298 return int(self) << int(other)
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000299
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000300 def __rlshift__(self, other):
Raymond Hettingercaea65e2008-06-11 00:25:29 +0000301 return int(other) << int(self)
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000302
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000303 def __rshift__(self, other):
Raymond Hettingercaea65e2008-06-11 00:25:29 +0000304 return int(self) >> int(other)
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000305
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000306 def __rrshift__(self, other):
Raymond Hettingercaea65e2008-06-11 00:25:29 +0000307 return int(other) >> int(self)
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000308
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000309 def __and__(self, other):
Raymond Hettingercaea65e2008-06-11 00:25:29 +0000310 return int(self) & int(other)
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000311
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000312 def __rand__(self, other):
Raymond Hettingercaea65e2008-06-11 00:25:29 +0000313 return int(other) & int(self)
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000314
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000315 def __xor__(self, other):
Raymond Hettingercaea65e2008-06-11 00:25:29 +0000316 return int(self) ^ int(other)
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000317
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000318 def __rxor__(self, other):
Raymond Hettingercaea65e2008-06-11 00:25:29 +0000319 return int(other) ^ int(self)
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000320
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000321 def __or__(self, other):
Raymond Hettingercaea65e2008-06-11 00:25:29 +0000322 return int(self) | int(other)
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000323
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000324 def __ror__(self, other):
Raymond Hettingercaea65e2008-06-11 00:25:29 +0000325 return int(other) | int(self)
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000326
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000327 def __invert__(self):
Raymond Hettingercaea65e2008-06-11 00:25:29 +0000328 return ~int(self)
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000329
330 # Concrete implementations of Rational and Real abstract methods.
331 def __float__(self):
Raymond Hettingercaea65e2008-06-11 00:25:29 +0000332 """float(self) == float(int(self))"""
333 return float(int(self))
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000334
335 @property
336 def numerator(self):
337 """Integers are their own numerators."""
338 return +self
339
340 @property
341 def denominator(self):
342 """Integers have a denominator of 1."""
343 return 1
344
345Integral.register(int)
346Integral.register(long)