blob: b5150d22ff0006810193061d677ea9505d57cc85 [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)
Guido van Rossumd4256302007-12-06 17:45:33 +000046# Inexact.register(decimal.Decimal)
Guido van Rossum1daf9542007-08-30 17:45:54 +000047
48
49class Complex(Number):
50 """Complex defines the operations that work on the builtin complex type.
51
52 In short, those are: a conversion to complex, .real, .imag, +, -,
53 *, /, abs(), .conjugate, ==, and !=.
54
55 If it is given heterogenous arguments, and doesn't have special
56 knowledge about them, it should fall back to the builtin complex
57 type as described below.
58 """
59
60 @abstractmethod
61 def __complex__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000062 """Return a builtin complex instance. Called for complex(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +000063
Jeffrey Yasskin9893de12008-01-17 07:36:30 +000064 def __bool__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000065 """True if self != 0. Called for bool(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +000066 return self != 0
67
68 @abstractproperty
69 def real(self):
70 """Retrieve the real component of this number.
71
72 This should subclass Real.
73 """
74 raise NotImplementedError
75
76 @abstractproperty
77 def imag(self):
78 """Retrieve the real component of this number.
79
80 This should subclass Real.
81 """
82 raise NotImplementedError
83
84 @abstractmethod
85 def __add__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000086 """self + other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000087 raise NotImplementedError
88
89 @abstractmethod
90 def __radd__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000091 """other + self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000092 raise NotImplementedError
93
94 @abstractmethod
95 def __neg__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000096 """-self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +000097 raise NotImplementedError
98
Guido van Rossum7736b5b2008-01-15 21:44:53 +000099 @abstractmethod
Guido van Rossum1daf9542007-08-30 17:45:54 +0000100 def __pos__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000101 """+self"""
Guido van Rossumd4256302007-12-06 17:45:33 +0000102 raise NotImplementedError
Guido van Rossum1daf9542007-08-30 17:45:54 +0000103
104 def __sub__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000105 """self - other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000106 return self + -other
107
108 def __rsub__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000109 """other - self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000110 return -self + other
111
112 @abstractmethod
113 def __mul__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000114 """self * other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000115 raise NotImplementedError
116
117 @abstractmethod
118 def __rmul__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000119 """other * self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000120 raise NotImplementedError
121
122 @abstractmethod
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000123 def __truediv__(self, other):
Jeffrey Yasskin9893de12008-01-17 07:36:30 +0000124 """self / other: Should promote to float when necessary."""
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000125 raise NotImplementedError
126
127 @abstractmethod
128 def __rtruediv__(self, other):
Jeffrey Yasskin9893de12008-01-17 07:36:30 +0000129 """other / self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000130 raise NotImplementedError
131
132 @abstractmethod
133 def __pow__(self, exponent):
Guido van Rossumd4256302007-12-06 17:45:33 +0000134 """self**exponent; should promote to float or complex when necessary."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000135 raise NotImplementedError
136
137 @abstractmethod
138 def __rpow__(self, base):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000139 """base ** self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000140 raise NotImplementedError
141
142 @abstractmethod
143 def __abs__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000144 """Returns the Real distance from 0. Called for abs(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000145 raise NotImplementedError
146
147 @abstractmethod
148 def conjugate(self):
149 """(x+y*i).conjugate() returns (x-y*i)."""
150 raise NotImplementedError
151
152 @abstractmethod
153 def __eq__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000154 """self == other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000155 raise NotImplementedError
156
Christian Heimes77c02eb2008-02-09 02:18:51 +0000157 def __ne__(self, other):
158 """self != other"""
159 # The default __ne__ doesn't negate __eq__ until 3.0.
160 return not (self == other)
Guido van Rossum1daf9542007-08-30 17:45:54 +0000161
162Complex.register(complex)
163
164
165class Real(Complex):
166 """To Complex, Real adds the operations that work on real numbers.
167
168 In short, those are: a conversion to float, trunc(), divmod,
169 %, <, <=, >, and >=.
170
171 Real also provides defaults for the derived operations.
172 """
173
174 @abstractmethod
175 def __float__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000176 """Any Real can be converted to a native float object.
177
178 Called for float(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000179 raise NotImplementedError
180
181 @abstractmethod
182 def __trunc__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000183 """trunc(self): Truncates self to an Integral.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000184
185 Returns an Integral i such that:
Guido van Rossumd4256302007-12-06 17:45:33 +0000186 * i>0 iff self>0;
187 * abs(i) <= abs(self);
188 * for any Integral j satisfying the first two conditions,
189 abs(i) >= abs(j) [i.e. i has "maximal" abs among those].
190 i.e. "truncate towards 0".
191 """
192 raise NotImplementedError
193
194 @abstractmethod
195 def __floor__(self):
196 """Finds the greatest Integral <= self."""
197 raise NotImplementedError
198
199 @abstractmethod
200 def __ceil__(self):
201 """Finds the least Integral >= self."""
202 raise NotImplementedError
203
204 @abstractmethod
205 def __round__(self, ndigits:"Integral"=None):
206 """Rounds self to ndigits decimal places, defaulting to 0.
207
208 If ndigits is omitted or None, returns an Integral, otherwise
209 returns a Real. Rounds half toward even.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000210 """
211 raise NotImplementedError
212
213 def __divmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000214 """divmod(self, other): The pair (self // other, self % other).
Guido van Rossum1daf9542007-08-30 17:45:54 +0000215
216 Sometimes this can be computed faster than the pair of
217 operations.
218 """
219 return (self // other, self % other)
220
221 def __rdivmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000222 """divmod(other, self): The pair (self // other, self % other).
Guido van Rossum1daf9542007-08-30 17:45:54 +0000223
224 Sometimes this can be computed faster than the pair of
225 operations.
226 """
227 return (other // self, other % self)
228
229 @abstractmethod
230 def __floordiv__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000231 """self // other: The floor() of self/other."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000232 raise NotImplementedError
233
234 @abstractmethod
235 def __rfloordiv__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000236 """other // self: The floor() of other/self."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000237 raise NotImplementedError
238
239 @abstractmethod
240 def __mod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000241 """self % other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000242 raise NotImplementedError
243
244 @abstractmethod
245 def __rmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000246 """other % self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000247 raise NotImplementedError
248
249 @abstractmethod
250 def __lt__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000251 """self < other
252
253 < on Reals defines a total ordering, except perhaps for NaN."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000254 raise NotImplementedError
255
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000256 @abstractmethod
Guido van Rossum1daf9542007-08-30 17:45:54 +0000257 def __le__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000258 """self <= other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000259 raise NotImplementedError
260
261 # Concrete implementations of Complex abstract methods.
262 def __complex__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000263 """complex(self) == complex(float(self), 0)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000264 return complex(float(self))
265
266 @property
267 def real(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000268 """Real numbers are their real component."""
Guido van Rossumd4256302007-12-06 17:45:33 +0000269 return +self
Guido van Rossum1daf9542007-08-30 17:45:54 +0000270
271 @property
272 def imag(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000273 """Real numbers have no imaginary component."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000274 return 0
275
276 def conjugate(self):
277 """Conjugate is a no-op for Reals."""
Guido van Rossumd4256302007-12-06 17:45:33 +0000278 return +self
Guido van Rossum1daf9542007-08-30 17:45:54 +0000279
280Real.register(float)
Guido van Rossumd4256302007-12-06 17:45:33 +0000281# Real.register(decimal.Decimal)
Guido van Rossum1daf9542007-08-30 17:45:54 +0000282
283
284class Rational(Real, Exact):
285 """.numerator and .denominator should be in lowest terms."""
286
287 @abstractproperty
288 def numerator(self):
289 raise NotImplementedError
290
291 @abstractproperty
292 def denominator(self):
293 raise NotImplementedError
294
295 # Concrete implementation of Real's conversion to float.
296 def __float__(self):
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000297 """float(self) = self.numerator / self.denominator
298
299 It's important that this conversion use the integer's "true"
300 division rather than casting one side to float before dividing
301 so that ratios of huge integers convert without overflowing.
302
303 """
Guido van Rossum1daf9542007-08-30 17:45:54 +0000304 return self.numerator / self.denominator
305
306
307class Integral(Rational):
308 """Integral adds a conversion to int and the bit-string operations."""
309
310 @abstractmethod
311 def __int__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000312 """int(self)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000313 raise NotImplementedError
314
315 def __index__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000316 """index(self)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000317 return int(self)
318
319 @abstractmethod
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000320 def __pow__(self, exponent, modulus=None):
Guido van Rossum1daf9542007-08-30 17:45:54 +0000321 """self ** exponent % modulus, but maybe faster.
322
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000323 Accept the modulus argument if you want to support the
324 3-argument version of pow(). Raise a TypeError if exponent < 0
325 or any argument isn't Integral. Otherwise, just implement the
326 2-argument version described in Complex.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000327 """
328 raise NotImplementedError
329
330 @abstractmethod
331 def __lshift__(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 __rlshift__(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 __rshift__(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 __rrshift__(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 __and__(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 __rand__(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 __xor__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000362 """self ^ other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000363 raise NotImplementedError
364
365 @abstractmethod
366 def __rxor__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000367 """other ^ self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000368 raise NotImplementedError
369
370 @abstractmethod
371 def __or__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000372 """self | other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000373 raise NotImplementedError
374
375 @abstractmethod
376 def __ror__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000377 """other | self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000378 raise NotImplementedError
379
380 @abstractmethod
381 def __invert__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000382 """~self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000383 raise NotImplementedError
384
385 # Concrete implementations of Rational and Real abstract methods.
386 def __float__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000387 """float(self) == float(int(self))"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000388 return float(int(self))
389
390 @property
391 def numerator(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000392 """Integers are their own numerators."""
Guido van Rossumd4256302007-12-06 17:45:33 +0000393 return +self
Guido van Rossum1daf9542007-08-30 17:45:54 +0000394
395 @property
396 def denominator(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000397 """Integers have a denominator of 1."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000398 return 1
399
400Integral.register(int)