blob: 827c25379ff8cb21f06310b9f956cd3451c1be09 [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
Christian Heimes08976cb2008-03-16 00:32:36 +000010__all__ = ["Number", "Complex", "Real", "Rational", "Integral"]
Guido van Rossum1daf9542007-08-30 17:45:54 +000011
12class Number(metaclass=ABCMeta):
13 """All numbers inherit from this class.
14
15 If you just want to check if an argument x is a number, without
16 caring what kind, use isinstance(x, Number).
17 """
Nick Coghlan36f49522008-08-18 12:31:52 +000018 # Concrete numeric types must provide their own hash implementation
19 __hash__ = None
Guido van Rossum1daf9542007-08-30 17:45:54 +000020
21
Christian Heimes68f5fbe2008-02-14 08:27:37 +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
Christian Heimes08976cb2008-03-16 00:32:36 +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).
Christian Heimes0bd4e112008-02-12 22:59:25 +000029
Guido van Rossum1daf9542007-08-30 17:45:54 +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):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000043 """Return a builtin complex instance. Called for complex(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +000044
Jeffrey Yasskin9893de12008-01-17 07:36:30 +000045 def __bool__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000046 """True if self != 0. Called for bool(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +000047 return self != 0
48
49 @abstractproperty
50 def real(self):
51 """Retrieve the real component of this number.
52
53 This should subclass Real.
54 """
55 raise NotImplementedError
56
57 @abstractproperty
58 def imag(self):
59 """Retrieve the real component of this number.
60
61 This should subclass Real.
62 """
63 raise NotImplementedError
64
65 @abstractmethod
66 def __add__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000067 """self + other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000068 raise NotImplementedError
69
70 @abstractmethod
71 def __radd__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000072 """other + self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000073 raise NotImplementedError
74
75 @abstractmethod
76 def __neg__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000077 """-self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000078 raise NotImplementedError
79
Guido van Rossum7736b5b2008-01-15 21:44:53 +000080 @abstractmethod
Guido van Rossum1daf9542007-08-30 17:45:54 +000081 def __pos__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000082 """+self"""
Guido van Rossumd4256302007-12-06 17:45:33 +000083 raise NotImplementedError
Guido van Rossum1daf9542007-08-30 17:45:54 +000084
85 def __sub__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000086 """self - other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000087 return self + -other
88
89 def __rsub__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000090 """other - self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000091 return -self + other
92
93 @abstractmethod
94 def __mul__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000095 """self * other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000096 raise NotImplementedError
97
98 @abstractmethod
99 def __rmul__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000100 """other * self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000101 raise NotImplementedError
102
103 @abstractmethod
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000104 def __truediv__(self, other):
Jeffrey Yasskin9893de12008-01-17 07:36:30 +0000105 """self / other: Should promote to float when necessary."""
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000106 raise NotImplementedError
107
108 @abstractmethod
109 def __rtruediv__(self, other):
Jeffrey Yasskin9893de12008-01-17 07:36:30 +0000110 """other / self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000111 raise NotImplementedError
112
113 @abstractmethod
114 def __pow__(self, exponent):
Guido van Rossumd4256302007-12-06 17:45:33 +0000115 """self**exponent; should promote to float or complex when necessary."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000116 raise NotImplementedError
117
118 @abstractmethod
119 def __rpow__(self, base):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000120 """base ** self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000121 raise NotImplementedError
122
123 @abstractmethod
124 def __abs__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000125 """Returns the Real distance from 0. Called for abs(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000126 raise NotImplementedError
127
128 @abstractmethod
129 def conjugate(self):
130 """(x+y*i).conjugate() returns (x-y*i)."""
131 raise NotImplementedError
132
133 @abstractmethod
134 def __eq__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000135 """self == other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000136 raise NotImplementedError
137
Christian Heimes77c02eb2008-02-09 02:18:51 +0000138 def __ne__(self, other):
139 """self != other"""
140 # The default __ne__ doesn't negate __eq__ until 3.0.
141 return not (self == other)
Guido van Rossum1daf9542007-08-30 17:45:54 +0000142
143Complex.register(complex)
144
145
146class Real(Complex):
147 """To Complex, Real adds the operations that work on real numbers.
148
149 In short, those are: a conversion to float, trunc(), divmod,
150 %, <, <=, >, and >=.
151
152 Real also provides defaults for the derived operations.
153 """
154
155 @abstractmethod
156 def __float__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000157 """Any Real can be converted to a native float object.
158
159 Called for float(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000160 raise NotImplementedError
161
162 @abstractmethod
163 def __trunc__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000164 """trunc(self): Truncates self to an Integral.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000165
166 Returns an Integral i such that:
Guido van Rossumd4256302007-12-06 17:45:33 +0000167 * i>0 iff self>0;
168 * abs(i) <= abs(self);
169 * for any Integral j satisfying the first two conditions,
170 abs(i) >= abs(j) [i.e. i has "maximal" abs among those].
171 i.e. "truncate towards 0".
172 """
173 raise NotImplementedError
174
175 @abstractmethod
176 def __floor__(self):
177 """Finds the greatest Integral <= self."""
178 raise NotImplementedError
179
180 @abstractmethod
181 def __ceil__(self):
182 """Finds the least Integral >= self."""
183 raise NotImplementedError
184
185 @abstractmethod
186 def __round__(self, ndigits:"Integral"=None):
187 """Rounds self to ndigits decimal places, defaulting to 0.
188
189 If ndigits is omitted or None, returns an Integral, otherwise
190 returns a Real. Rounds half toward even.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000191 """
192 raise NotImplementedError
193
194 def __divmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000195 """divmod(self, other): The pair (self // other, self % other).
Guido van Rossum1daf9542007-08-30 17:45:54 +0000196
197 Sometimes this can be computed faster than the pair of
198 operations.
199 """
200 return (self // other, self % other)
201
202 def __rdivmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000203 """divmod(other, self): The pair (self // other, self % other).
Guido van Rossum1daf9542007-08-30 17:45:54 +0000204
205 Sometimes this can be computed faster than the pair of
206 operations.
207 """
208 return (other // self, other % self)
209
210 @abstractmethod
211 def __floordiv__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000212 """self // other: The floor() of self/other."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000213 raise NotImplementedError
214
215 @abstractmethod
216 def __rfloordiv__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000217 """other // self: The floor() of other/self."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000218 raise NotImplementedError
219
220 @abstractmethod
221 def __mod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000222 """self % other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000223 raise NotImplementedError
224
225 @abstractmethod
226 def __rmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000227 """other % self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000228 raise NotImplementedError
229
230 @abstractmethod
231 def __lt__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000232 """self < other
233
234 < on Reals defines a total ordering, except perhaps for NaN."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000235 raise NotImplementedError
236
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000237 @abstractmethod
Guido van Rossum1daf9542007-08-30 17:45:54 +0000238 def __le__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000239 """self <= other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000240 raise NotImplementedError
241
242 # Concrete implementations of Complex abstract methods.
243 def __complex__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000244 """complex(self) == complex(float(self), 0)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000245 return complex(float(self))
246
247 @property
248 def real(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000249 """Real numbers are their real component."""
Guido van Rossumd4256302007-12-06 17:45:33 +0000250 return +self
Guido van Rossum1daf9542007-08-30 17:45:54 +0000251
252 @property
253 def imag(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000254 """Real numbers have no imaginary component."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000255 return 0
256
257 def conjugate(self):
258 """Conjugate is a no-op for Reals."""
Guido van Rossumd4256302007-12-06 17:45:33 +0000259 return +self
Guido van Rossum1daf9542007-08-30 17:45:54 +0000260
261Real.register(float)
262
263
Christian Heimes08976cb2008-03-16 00:32:36 +0000264class Rational(Real):
Guido van Rossum1daf9542007-08-30 17:45:54 +0000265 """.numerator and .denominator should be in lowest terms."""
266
267 @abstractproperty
268 def numerator(self):
269 raise NotImplementedError
270
271 @abstractproperty
272 def denominator(self):
273 raise NotImplementedError
274
275 # Concrete implementation of Real's conversion to float.
276 def __float__(self):
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000277 """float(self) = self.numerator / self.denominator
278
279 It's important that this conversion use the integer's "true"
280 division rather than casting one side to float before dividing
281 so that ratios of huge integers convert without overflowing.
282
283 """
Guido van Rossum1daf9542007-08-30 17:45:54 +0000284 return self.numerator / self.denominator
285
286
287class Integral(Rational):
288 """Integral adds a conversion to int and the bit-string operations."""
289
290 @abstractmethod
291 def __int__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000292 """int(self)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000293 raise NotImplementedError
294
295 def __index__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000296 """index(self)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000297 return int(self)
298
299 @abstractmethod
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000300 def __pow__(self, exponent, modulus=None):
Guido van Rossum1daf9542007-08-30 17:45:54 +0000301 """self ** exponent % modulus, but maybe faster.
302
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000303 Accept the modulus argument if you want to support the
304 3-argument version of pow(). Raise a TypeError if exponent < 0
305 or any argument isn't Integral. Otherwise, just implement the
306 2-argument version described in Complex.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000307 """
308 raise NotImplementedError
309
310 @abstractmethod
311 def __lshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000312 """self << other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000313 raise NotImplementedError
314
315 @abstractmethod
316 def __rlshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000317 """other << self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000318 raise NotImplementedError
319
320 @abstractmethod
321 def __rshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000322 """self >> other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000323 raise NotImplementedError
324
325 @abstractmethod
326 def __rrshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000327 """other >> self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000328 raise NotImplementedError
329
330 @abstractmethod
331 def __and__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000332 """self & other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000333 raise NotImplementedError
334
335 @abstractmethod
336 def __rand__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000337 """other & self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000338 raise NotImplementedError
339
340 @abstractmethod
341 def __xor__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000342 """self ^ other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000343 raise NotImplementedError
344
345 @abstractmethod
346 def __rxor__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000347 """other ^ self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000348 raise NotImplementedError
349
350 @abstractmethod
351 def __or__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000352 """self | other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000353 raise NotImplementedError
354
355 @abstractmethod
356 def __ror__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000357 """other | self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000358 raise NotImplementedError
359
360 @abstractmethod
361 def __invert__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000362 """~self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000363 raise NotImplementedError
364
365 # Concrete implementations of Rational and Real abstract methods.
366 def __float__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000367 """float(self) == float(int(self))"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000368 return float(int(self))
369
370 @property
371 def numerator(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000372 """Integers are their own numerators."""
Guido van Rossumd4256302007-12-06 17:45:33 +0000373 return +self
Guido van Rossum1daf9542007-08-30 17:45:54 +0000374
375 @property
376 def denominator(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000377 """Integers have a denominator of 1."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000378 return 1
379
380Integral.register(int)