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) 392