Coverage for /pythoncovmergedfiles/medio/medio/usr/lib/python3.9/numbers.py: 69%

178 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-10-20 07:00 +0000

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 

6TODO: Fill out more detailed documentation on the operators.""" 

7 

8from abc import ABCMeta, abstractmethod 

9 

10__all__ = ["Number", "Complex", "Real", "Rational", "Integral"] 

11 

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 """ 

18 __slots__ = () 

19 

20 # Concrete numeric types must provide their own hash implementation 

21 __hash__ = None 

22 

23 

24## Notes on Decimal 

25## ---------------- 

26## Decimal has all of the methods specified by the Real abc, but it should 

27## not be registered as a Real because decimals do not interoperate with 

28## binary floats (i.e. Decimal('3.14') + 2.71828 is undefined). But, 

29## abstract reals are expected to interoperate (i.e. R1 + R2 should be 

30## expected to work if R1 and R2 are both Reals). 

31 

32class Complex(Number): 

33 """Complex defines the operations that work on the builtin complex type. 

34 

35 In short, those are: a conversion to complex, .real, .imag, +, -, 

36 *, /, abs(), .conjugate, ==, and !=. 

37 

38 If it is given heterogeneous arguments, and doesn't have special 

39 knowledge about them, it should fall back to the builtin complex 

40 type as described below. 

41 """ 

42 

43 __slots__ = () 

44 

45 @abstractmethod 

46 def __complex__(self): 

47 """Return a builtin complex instance. Called for complex(self).""" 

48 

49 def __bool__(self): 

50 """True if self != 0. Called for bool(self).""" 

51 return self != 0 

52 

53 @property 

54 @abstractmethod 

55 def real(self): 

56 """Retrieve the real component of this number. 

57 

58 This should subclass Real. 

59 """ 

60 raise NotImplementedError 

61 

62 @property 

63 @abstractmethod 

64 def imag(self): 

65 """Retrieve the imaginary component of this number. 

66 

67 This should subclass Real. 

68 """ 

69 raise NotImplementedError 

70 

71 @abstractmethod 

72 def __add__(self, other): 

73 """self + other""" 

74 raise NotImplementedError 

75 

76 @abstractmethod 

77 def __radd__(self, other): 

78 """other + self""" 

79 raise NotImplementedError 

80 

81 @abstractmethod 

82 def __neg__(self): 

83 """-self""" 

84 raise NotImplementedError 

85 

86 @abstractmethod 

87 def __pos__(self): 

88 """+self""" 

89 raise NotImplementedError 

90 

91 def __sub__(self, other): 

92 """self - other""" 

93 return self + -other 

94 

95 def __rsub__(self, other): 

96 """other - self""" 

97 return -self + other 

98 

99 @abstractmethod 

100 def __mul__(self, other): 

101 """self * other""" 

102 raise NotImplementedError 

103 

104 @abstractmethod 

105 def __rmul__(self, other): 

106 """other * self""" 

107 raise NotImplementedError 

108 

109 @abstractmethod 

110 def __truediv__(self, other): 

111 """self / other: Should promote to float when necessary.""" 

112 raise NotImplementedError 

113 

114 @abstractmethod 

115 def __rtruediv__(self, other): 

116 """other / self""" 

117 raise NotImplementedError 

118 

119 @abstractmethod 

120 def __pow__(self, exponent): 

121 """self**exponent; should promote to float or complex when necessary.""" 

122 raise NotImplementedError 

123 

124 @abstractmethod 

125 def __rpow__(self, base): 

126 """base ** self""" 

127 raise NotImplementedError 

128 

129 @abstractmethod 

130 def __abs__(self): 

131 """Returns the Real distance from 0. Called for abs(self).""" 

132 raise NotImplementedError 

133 

134 @abstractmethod 

135 def conjugate(self): 

136 """(x+y*i).conjugate() returns (x-y*i).""" 

137 raise NotImplementedError 

138 

139 @abstractmethod 

140 def __eq__(self, other): 

141 """self == other""" 

142 raise NotImplementedError 

143 

144Complex.register(complex) 

145 

146 

147class Real(Complex): 

148 """To Complex, Real adds the operations that work on real numbers. 

149 

150 In short, those are: a conversion to float, trunc(), divmod, 

151 %, <, <=, >, and >=. 

152 

153 Real also provides defaults for the derived operations. 

154 """ 

155 

156 __slots__ = () 

157 

158 @abstractmethod 

159 def __float__(self): 

160 """Any Real can be converted to a native float object. 

161 

162 Called for float(self).""" 

163 raise NotImplementedError 

164 

165 @abstractmethod 

166 def __trunc__(self): 

167 """trunc(self): Truncates self to an Integral. 

168 

169 Returns an Integral i such that: 

170 * i>0 iff self>0; 

171 * abs(i) <= abs(self); 

172 * for any Integral j satisfying the first two conditions, 

173 abs(i) >= abs(j) [i.e. i has "maximal" abs among those]. 

174 i.e. "truncate towards 0". 

175 """ 

176 raise NotImplementedError 

177 

178 @abstractmethod 

179 def __floor__(self): 

180 """Finds the greatest Integral <= self.""" 

181 raise NotImplementedError 

182 

183 @abstractmethod 

184 def __ceil__(self): 

185 """Finds the least Integral >= self.""" 

186 raise NotImplementedError 

187 

188 @abstractmethod 

189 def __round__(self, ndigits=None): 

190 """Rounds self to ndigits decimal places, defaulting to 0. 

191 

192 If ndigits is omitted or None, returns an Integral, otherwise 

193 returns a Real. Rounds half toward even. 

194 """ 

195 raise NotImplementedError 

196 

197 def __divmod__(self, other): 

198 """divmod(self, other): The pair (self // other, self % other). 

199 

200 Sometimes this can be computed faster than the pair of 

201 operations. 

202 """ 

203 return (self // other, self % other) 

204 

205 def __rdivmod__(self, other): 

206 """divmod(other, self): The pair (self // other, self % other). 

207 

208 Sometimes this can be computed faster than the pair of 

209 operations. 

210 """ 

211 return (other // self, other % self) 

212 

213 @abstractmethod 

214 def __floordiv__(self, other): 

215 """self // other: The floor() of self/other.""" 

216 raise NotImplementedError 

217 

218 @abstractmethod 

219 def __rfloordiv__(self, other): 

220 """other // self: The floor() of other/self.""" 

221 raise NotImplementedError 

222 

223 @abstractmethod 

224 def __mod__(self, other): 

225 """self % other""" 

226 raise NotImplementedError 

227 

228 @abstractmethod 

229 def __rmod__(self, other): 

230 """other % self""" 

231 raise NotImplementedError 

232 

233 @abstractmethod 

234 def __lt__(self, other): 

235 """self < other 

236 

237 < on Reals defines a total ordering, except perhaps for NaN.""" 

238 raise NotImplementedError 

239 

240 @abstractmethod 

241 def __le__(self, other): 

242 """self <= other""" 

243 raise NotImplementedError 

244 

245 # Concrete implementations of Complex abstract methods. 

246 def __complex__(self): 

247 """complex(self) == complex(float(self), 0)""" 

248 return complex(float(self)) 

249 

250 @property 

251 def real(self): 

252 """Real numbers are their real component.""" 

253 return +self 

254 

255 @property 

256 def imag(self): 

257 """Real numbers have no imaginary component.""" 

258 return 0 

259 

260 def conjugate(self): 

261 """Conjugate is a no-op for Reals.""" 

262 return +self 

263 

264Real.register(float) 

265 

266 

267class Rational(Real): 

268 """.numerator and .denominator should be in lowest terms.""" 

269 

270 __slots__ = () 

271 

272 @property 

273 @abstractmethod 

274 def numerator(self): 

275 raise NotImplementedError 

276 

277 @property 

278 @abstractmethod 

279 def denominator(self): 

280 raise NotImplementedError 

281 

282 # Concrete implementation of Real's conversion to float. 

283 def __float__(self): 

284 """float(self) = self.numerator / self.denominator 

285 

286 It's important that this conversion use the integer's "true" 

287 division rather than casting one side to float before dividing 

288 so that ratios of huge integers convert without overflowing. 

289 

290 """ 

291 return self.numerator / self.denominator 

292 

293 

294class Integral(Rational): 

295 """Integral adds a conversion to int and the bit-string operations.""" 

296 

297 __slots__ = () 

298 

299 @abstractmethod 

300 def __int__(self): 

301 """int(self)""" 

302 raise NotImplementedError 

303 

304 def __index__(self): 

305 """Called whenever an index is needed, such as in slicing""" 

306 return int(self) 

307 

308 @abstractmethod 

309 def __pow__(self, exponent, modulus=None): 

310 """self ** exponent % modulus, but maybe faster. 

311 

312 Accept the modulus argument if you want to support the 

313 3-argument version of pow(). Raise a TypeError if exponent < 0 

314 or any argument isn't Integral. Otherwise, just implement the 

315 2-argument version described in Complex. 

316 """ 

317 raise NotImplementedError 

318 

319 @abstractmethod 

320 def __lshift__(self, other): 

321 """self << other""" 

322 raise NotImplementedError 

323 

324 @abstractmethod 

325 def __rlshift__(self, other): 

326 """other << self""" 

327 raise NotImplementedError 

328 

329 @abstractmethod 

330 def __rshift__(self, other): 

331 """self >> other""" 

332 raise NotImplementedError 

333 

334 @abstractmethod 

335 def __rrshift__(self, other): 

336 """other >> self""" 

337 raise NotImplementedError 

338 

339 @abstractmethod 

340 def __and__(self, other): 

341 """self & other""" 

342 raise NotImplementedError 

343 

344 @abstractmethod 

345 def __rand__(self, other): 

346 """other & self""" 

347 raise NotImplementedError 

348 

349 @abstractmethod 

350 def __xor__(self, other): 

351 """self ^ other""" 

352 raise NotImplementedError 

353 

354 @abstractmethod 

355 def __rxor__(self, other): 

356 """other ^ self""" 

357 raise NotImplementedError 

358 

359 @abstractmethod 

360 def __or__(self, other): 

361 """self | other""" 

362 raise NotImplementedError 

363 

364 @abstractmethod 

365 def __ror__(self, other): 

366 """other | self""" 

367 raise NotImplementedError 

368 

369 @abstractmethod 

370 def __invert__(self): 

371 """~self""" 

372 raise NotImplementedError 

373 

374 # Concrete implementations of Rational and Real abstract methods. 

375 def __float__(self): 

376 """float(self) == float(int(self))""" 

377 return float(int(self)) 

378 

379 @property 

380 def numerator(self): 

381 """Integers are their own numerators.""" 

382 return +self 

383 

384 @property 

385 def denominator(self): 

386 """Integers have a denominator of 1.""" 

387 return 1 

388 

389Integral.register(int)