blob: b1c0697b39e43f4e01e42472b70709857c93eb71 [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
64 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
99 def __pos__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000100 """+self"""
Guido van Rossumd4256302007-12-06 17:45:33 +0000101 raise NotImplementedError
Guido van Rossum1daf9542007-08-30 17:45:54 +0000102
103 def __sub__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000104 """self - other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000105 return self + -other
106
107 def __rsub__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000108 """other - self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000109 return -self + other
110
111 @abstractmethod
112 def __mul__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000113 """self * other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000114 raise NotImplementedError
115
116 @abstractmethod
117 def __rmul__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000118 """other * self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000119 raise NotImplementedError
120
121 @abstractmethod
122 def __div__(self, other):
Guido van Rossumd4256302007-12-06 17:45:33 +0000123 """self / other; should promote to float or complex when necessary."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000124 raise NotImplementedError
125
126 @abstractmethod
127 def __rdiv__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000128 """other / self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000129 raise NotImplementedError
130
131 @abstractmethod
132 def __pow__(self, exponent):
Guido van Rossumd4256302007-12-06 17:45:33 +0000133 """self**exponent; should promote to float or complex when necessary."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000134 raise NotImplementedError
135
136 @abstractmethod
137 def __rpow__(self, base):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000138 """base ** self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000139 raise NotImplementedError
140
141 @abstractmethod
142 def __abs__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000143 """Returns the Real distance from 0. Called for abs(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000144 raise NotImplementedError
145
146 @abstractmethod
147 def conjugate(self):
148 """(x+y*i).conjugate() returns (x-y*i)."""
149 raise NotImplementedError
150
151 @abstractmethod
152 def __eq__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000153 """self == other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000154 raise NotImplementedError
155
Guido van Rossumd4256302007-12-06 17:45:33 +0000156 # __ne__ is inherited from object and negates whatever __eq__ does.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000157
158Complex.register(complex)
159
160
161class Real(Complex):
162 """To Complex, Real adds the operations that work on real numbers.
163
164 In short, those are: a conversion to float, trunc(), divmod,
165 %, <, <=, >, and >=.
166
167 Real also provides defaults for the derived operations.
168 """
169
170 @abstractmethod
171 def __float__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000172 """Any Real can be converted to a native float object.
173
174 Called for float(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000175 raise NotImplementedError
176
177 @abstractmethod
178 def __trunc__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000179 """trunc(self): Truncates self to an Integral.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000180
181 Returns an Integral i such that:
Guido van Rossumd4256302007-12-06 17:45:33 +0000182 * i>0 iff self>0;
183 * abs(i) <= abs(self);
184 * for any Integral j satisfying the first two conditions,
185 abs(i) >= abs(j) [i.e. i has "maximal" abs among those].
186 i.e. "truncate towards 0".
187 """
188 raise NotImplementedError
189
190 @abstractmethod
191 def __floor__(self):
192 """Finds the greatest Integral <= self."""
193 raise NotImplementedError
194
195 @abstractmethod
196 def __ceil__(self):
197 """Finds the least Integral >= self."""
198 raise NotImplementedError
199
200 @abstractmethod
201 def __round__(self, ndigits:"Integral"=None):
202 """Rounds self to ndigits decimal places, defaulting to 0.
203
204 If ndigits is omitted or None, returns an Integral, otherwise
205 returns a Real. Rounds half toward even.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000206 """
207 raise NotImplementedError
208
209 def __divmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000210 """divmod(self, other): The pair (self // other, self % other).
Guido van Rossum1daf9542007-08-30 17:45:54 +0000211
212 Sometimes this can be computed faster than the pair of
213 operations.
214 """
215 return (self // other, self % other)
216
217 def __rdivmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000218 """divmod(other, self): The pair (self // other, self % other).
Guido van Rossum1daf9542007-08-30 17:45:54 +0000219
220 Sometimes this can be computed faster than the pair of
221 operations.
222 """
223 return (other // self, other % self)
224
225 @abstractmethod
226 def __floordiv__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000227 """self // other: The floor() of self/other."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000228 raise NotImplementedError
229
230 @abstractmethod
231 def __rfloordiv__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000232 """other // self: The floor() of other/self."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000233 raise NotImplementedError
234
235 @abstractmethod
236 def __mod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000237 """self % other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000238 raise NotImplementedError
239
240 @abstractmethod
241 def __rmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000242 """other % self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000243 raise NotImplementedError
244
245 @abstractmethod
246 def __lt__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000247 """self < other
248
249 < on Reals defines a total ordering, except perhaps for NaN."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000250 raise NotImplementedError
251
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000252 @abstractmethod
Guido van Rossum1daf9542007-08-30 17:45:54 +0000253 def __le__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000254 """self <= other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000255 raise NotImplementedError
256
257 # Concrete implementations of Complex abstract methods.
258 def __complex__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000259 """complex(self) == complex(float(self), 0)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000260 return complex(float(self))
261
262 @property
263 def real(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000264 """Real numbers are their real component."""
Guido van Rossumd4256302007-12-06 17:45:33 +0000265 return +self
Guido van Rossum1daf9542007-08-30 17:45:54 +0000266
267 @property
268 def imag(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000269 """Real numbers have no imaginary component."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000270 return 0
271
272 def conjugate(self):
273 """Conjugate is a no-op for Reals."""
Guido van Rossumd4256302007-12-06 17:45:33 +0000274 return +self
Guido van Rossum1daf9542007-08-30 17:45:54 +0000275
276Real.register(float)
Guido van Rossumd4256302007-12-06 17:45:33 +0000277# Real.register(decimal.Decimal)
Guido van Rossum1daf9542007-08-30 17:45:54 +0000278
279
280class Rational(Real, Exact):
281 """.numerator and .denominator should be in lowest terms."""
282
283 @abstractproperty
284 def numerator(self):
285 raise NotImplementedError
286
287 @abstractproperty
288 def denominator(self):
289 raise NotImplementedError
290
291 # Concrete implementation of Real's conversion to float.
292 def __float__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000293 """float(self) = self.numerator / self.denominator"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000294 return self.numerator / self.denominator
295
296
297class Integral(Rational):
298 """Integral adds a conversion to int and the bit-string operations."""
299
300 @abstractmethod
301 def __int__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000302 """int(self)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000303 raise NotImplementedError
304
305 def __index__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000306 """index(self)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000307 return int(self)
308
309 @abstractmethod
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000310 def __pow__(self, exponent, modulus=None):
Guido van Rossum1daf9542007-08-30 17:45:54 +0000311 """self ** exponent % modulus, but maybe faster.
312
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000313 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.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000317 """
318 raise NotImplementedError
319
320 @abstractmethod
321 def __lshift__(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 __rlshift__(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 __rshift__(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 __rrshift__(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 __and__(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 __rand__(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 __xor__(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 __rxor__(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 __or__(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 __ror__(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 __invert__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000372 """~self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000373 raise NotImplementedError
374
375 # Concrete implementations of Rational and Real abstract methods.
376 def __float__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000377 """float(self) == float(int(self))"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000378 return float(int(self))
379
380 @property
381 def numerator(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000382 """Integers are their own numerators."""
Guido van Rossumd4256302007-12-06 17:45:33 +0000383 return +self
Guido van Rossum1daf9542007-08-30 17:45:54 +0000384
385 @property
386 def denominator(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000387 """Integers have a denominator of 1."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000388 return 1
389
390Integral.register(int)