# Python code coverage for Lib/test/test_complex.py

# | count | content |
---|---|---|

1 | n/a | import unittest |

2 | n/a | from test import support |

3 | n/a | from test.test_grammar import (VALID_UNDERSCORE_LITERALS, |

4 | n/a | INVALID_UNDERSCORE_LITERALS) |

5 | n/a | |

6 | n/a | from random import random |

7 | n/a | from math import atan2, isnan, copysign |

8 | n/a | import operator |

9 | n/a | |

10 | n/a | INF = float("inf") |

11 | n/a | NAN = float("nan") |

12 | n/a | # These tests ensure that complex math does the right thing |

13 | n/a | |

14 | n/a | class ComplexTest(unittest.TestCase): |

15 | n/a | |

16 | n/a | def assertAlmostEqual(self, a, b): |

17 | n/a | if isinstance(a, complex): |

18 | n/a | if isinstance(b, complex): |

19 | n/a | unittest.TestCase.assertAlmostEqual(self, a.real, b.real) |

20 | n/a | unittest.TestCase.assertAlmostEqual(self, a.imag, b.imag) |

21 | n/a | else: |

22 | n/a | unittest.TestCase.assertAlmostEqual(self, a.real, b) |

23 | n/a | unittest.TestCase.assertAlmostEqual(self, a.imag, 0.) |

24 | n/a | else: |

25 | n/a | if isinstance(b, complex): |

26 | n/a | unittest.TestCase.assertAlmostEqual(self, a, b.real) |

27 | n/a | unittest.TestCase.assertAlmostEqual(self, 0., b.imag) |

28 | n/a | else: |

29 | n/a | unittest.TestCase.assertAlmostEqual(self, a, b) |

30 | n/a | |

31 | n/a | def assertCloseAbs(self, x, y, eps=1e-9): |

32 | n/a | """Return true iff floats x and y "are close".""" |

33 | n/a | # put the one with larger magnitude second |

34 | n/a | if abs(x) > abs(y): |

35 | n/a | x, y = y, x |

36 | n/a | if y == 0: |

37 | n/a | return abs(x) < eps |

38 | n/a | if x == 0: |

39 | n/a | return abs(y) < eps |

40 | n/a | # check that relative difference < eps |

41 | n/a | self.assertTrue(abs((x-y)/y) < eps) |

42 | n/a | |

43 | n/a | def assertFloatsAreIdentical(self, x, y): |

44 | n/a | """assert that floats x and y are identical, in the sense that: |

45 | n/a | (1) both x and y are nans, or |

46 | n/a | (2) both x and y are infinities, with the same sign, or |

47 | n/a | (3) both x and y are zeros, with the same sign, or |

48 | n/a | (4) x and y are both finite and nonzero, and x == y |

49 | n/a | |

50 | n/a | """ |

51 | n/a | msg = 'floats {!r} and {!r} are not identical' |

52 | n/a | |

53 | n/a | if isnan(x) or isnan(y): |

54 | n/a | if isnan(x) and isnan(y): |

55 | n/a | return |

56 | n/a | elif x == y: |

57 | n/a | if x != 0.0: |

58 | n/a | return |

59 | n/a | # both zero; check that signs match |

60 | n/a | elif copysign(1.0, x) == copysign(1.0, y): |

61 | n/a | return |

62 | n/a | else: |

63 | n/a | msg += ': zeros have different signs' |

64 | n/a | self.fail(msg.format(x, y)) |

65 | n/a | |

66 | n/a | def assertClose(self, x, y, eps=1e-9): |

67 | n/a | """Return true iff complexes x and y "are close".""" |

68 | n/a | self.assertCloseAbs(x.real, y.real, eps) |

69 | n/a | self.assertCloseAbs(x.imag, y.imag, eps) |

70 | n/a | |

71 | n/a | def check_div(self, x, y): |

72 | n/a | """Compute complex z=x*y, and check that z/x==y and z/y==x.""" |

73 | n/a | z = x * y |

74 | n/a | if x != 0: |

75 | n/a | q = z / x |

76 | n/a | self.assertClose(q, y) |

77 | n/a | q = z.__truediv__(x) |

78 | n/a | self.assertClose(q, y) |

79 | n/a | if y != 0: |

80 | n/a | q = z / y |

81 | n/a | self.assertClose(q, x) |

82 | n/a | q = z.__truediv__(y) |

83 | n/a | self.assertClose(q, x) |

84 | n/a | |

85 | n/a | def test_truediv(self): |

86 | n/a | simple_real = [float(i) for i in range(-5, 6)] |

87 | n/a | simple_complex = [complex(x, y) for x in simple_real for y in simple_real] |

88 | n/a | for x in simple_complex: |

89 | n/a | for y in simple_complex: |

90 | n/a | self.check_div(x, y) |

91 | n/a | |

92 | n/a | # A naive complex division algorithm (such as in 2.0) is very prone to |

93 | n/a | # nonsense errors for these (overflows and underflows). |

94 | n/a | self.check_div(complex(1e200, 1e200), 1+0j) |

95 | n/a | self.check_div(complex(1e-200, 1e-200), 1+0j) |

96 | n/a | |

97 | n/a | # Just for fun. |

98 | n/a | for i in range(100): |

99 | n/a | self.check_div(complex(random(), random()), |

100 | n/a | complex(random(), random())) |

101 | n/a | |

102 | n/a | self.assertRaises(ZeroDivisionError, complex.__truediv__, 1+1j, 0+0j) |

103 | n/a | # FIXME: The following currently crashes on Alpha |

104 | n/a | # self.assertRaises(OverflowError, pow, 1e200+1j, 1e200+1j) |

105 | n/a | |

106 | n/a | self.assertAlmostEqual(complex.__truediv__(2+0j, 1+1j), 1-1j) |

107 | n/a | self.assertRaises(ZeroDivisionError, complex.__truediv__, 1+1j, 0+0j) |

108 | n/a | |

109 | n/a | for denom_real, denom_imag in [(0, NAN), (NAN, 0), (NAN, NAN)]: |

110 | n/a | z = complex(0, 0) / complex(denom_real, denom_imag) |

111 | n/a | self.assertTrue(isnan(z.real)) |

112 | n/a | self.assertTrue(isnan(z.imag)) |

113 | n/a | |

114 | n/a | def test_floordiv(self): |

115 | n/a | self.assertRaises(TypeError, complex.__floordiv__, 3+0j, 1.5+0j) |

116 | n/a | self.assertRaises(TypeError, complex.__floordiv__, 3+0j, 0+0j) |

117 | n/a | |

118 | n/a | def test_richcompare(self): |

119 | n/a | self.assertIs(complex.__eq__(1+1j, 1<<10000), False) |

120 | n/a | self.assertIs(complex.__lt__(1+1j, None), NotImplemented) |

121 | n/a | self.assertIs(complex.__eq__(1+1j, 1+1j), True) |

122 | n/a | self.assertIs(complex.__eq__(1+1j, 2+2j), False) |

123 | n/a | self.assertIs(complex.__ne__(1+1j, 1+1j), False) |

124 | n/a | self.assertIs(complex.__ne__(1+1j, 2+2j), True) |

125 | n/a | for i in range(1, 100): |

126 | n/a | f = i / 100.0 |

127 | n/a | self.assertIs(complex.__eq__(f+0j, f), True) |

128 | n/a | self.assertIs(complex.__ne__(f+0j, f), False) |

129 | n/a | self.assertIs(complex.__eq__(complex(f, f), f), False) |

130 | n/a | self.assertIs(complex.__ne__(complex(f, f), f), True) |

131 | n/a | self.assertIs(complex.__lt__(1+1j, 2+2j), NotImplemented) |

132 | n/a | self.assertIs(complex.__le__(1+1j, 2+2j), NotImplemented) |

133 | n/a | self.assertIs(complex.__gt__(1+1j, 2+2j), NotImplemented) |

134 | n/a | self.assertIs(complex.__ge__(1+1j, 2+2j), NotImplemented) |

135 | n/a | self.assertRaises(TypeError, operator.lt, 1+1j, 2+2j) |

136 | n/a | self.assertRaises(TypeError, operator.le, 1+1j, 2+2j) |

137 | n/a | self.assertRaises(TypeError, operator.gt, 1+1j, 2+2j) |

138 | n/a | self.assertRaises(TypeError, operator.ge, 1+1j, 2+2j) |

139 | n/a | self.assertIs(operator.eq(1+1j, 1+1j), True) |

140 | n/a | self.assertIs(operator.eq(1+1j, 2+2j), False) |

141 | n/a | self.assertIs(operator.ne(1+1j, 1+1j), False) |

142 | n/a | self.assertIs(operator.ne(1+1j, 2+2j), True) |

143 | n/a | |

144 | n/a | def test_richcompare_boundaries(self): |

145 | n/a | def check(n, deltas, is_equal, imag = 0.0): |

146 | n/a | for delta in deltas: |

147 | n/a | i = n + delta |

148 | n/a | z = complex(i, imag) |

149 | n/a | self.assertIs(complex.__eq__(z, i), is_equal(delta)) |

150 | n/a | self.assertIs(complex.__ne__(z, i), not is_equal(delta)) |

151 | n/a | # For IEEE-754 doubles the following should hold: |

152 | n/a | # x in [2 ** (52 + i), 2 ** (53 + i + 1)] -> x mod 2 ** i == 0 |

153 | n/a | # where the interval is representable, of course. |

154 | n/a | for i in range(1, 10): |

155 | n/a | pow = 52 + i |

156 | n/a | mult = 2 ** i |

157 | n/a | check(2 ** pow, range(1, 101), lambda delta: delta % mult == 0) |

158 | n/a | check(2 ** pow, range(1, 101), lambda delta: False, float(i)) |

159 | n/a | check(2 ** 53, range(-100, 0), lambda delta: True) |

160 | n/a | |

161 | n/a | def test_mod(self): |

162 | n/a | # % is no longer supported on complex numbers |

163 | n/a | self.assertRaises(TypeError, (1+1j).__mod__, 0+0j) |

164 | n/a | self.assertRaises(TypeError, lambda: (3.33+4.43j) % 0) |

165 | n/a | self.assertRaises(TypeError, (1+1j).__mod__, 4.3j) |

166 | n/a | |

167 | n/a | def test_divmod(self): |

168 | n/a | self.assertRaises(TypeError, divmod, 1+1j, 1+0j) |

169 | n/a | self.assertRaises(TypeError, divmod, 1+1j, 0+0j) |

170 | n/a | |

171 | n/a | def test_pow(self): |

172 | n/a | self.assertAlmostEqual(pow(1+1j, 0+0j), 1.0) |

173 | n/a | self.assertAlmostEqual(pow(0+0j, 2+0j), 0.0) |

174 | n/a | self.assertRaises(ZeroDivisionError, pow, 0+0j, 1j) |

175 | n/a | self.assertAlmostEqual(pow(1j, -1), 1/1j) |

176 | n/a | self.assertAlmostEqual(pow(1j, 200), 1) |

177 | n/a | self.assertRaises(ValueError, pow, 1+1j, 1+1j, 1+1j) |

178 | n/a | |

179 | n/a | a = 3.33+4.43j |

180 | n/a | self.assertEqual(a ** 0j, 1) |

181 | n/a | self.assertEqual(a ** 0.+0.j, 1) |

182 | n/a | |

183 | n/a | self.assertEqual(3j ** 0j, 1) |

184 | n/a | self.assertEqual(3j ** 0, 1) |

185 | n/a | |

186 | n/a | try: |

187 | n/a | 0j ** a |

188 | n/a | except ZeroDivisionError: |

189 | n/a | pass |

190 | n/a | else: |

191 | n/a | self.fail("should fail 0.0 to negative or complex power") |

192 | n/a | |

193 | n/a | try: |

194 | n/a | 0j ** (3-2j) |

195 | n/a | except ZeroDivisionError: |

196 | n/a | pass |

197 | n/a | else: |

198 | n/a | self.fail("should fail 0.0 to negative or complex power") |

199 | n/a | |

200 | n/a | # The following is used to exercise certain code paths |

201 | n/a | self.assertEqual(a ** 105, a ** 105) |

202 | n/a | self.assertEqual(a ** -105, a ** -105) |

203 | n/a | self.assertEqual(a ** -30, a ** -30) |

204 | n/a | |

205 | n/a | self.assertEqual(0.0j ** 0, 1) |

206 | n/a | |

207 | n/a | b = 5.1+2.3j |

208 | n/a | self.assertRaises(ValueError, pow, a, b, 0) |

209 | n/a | |

210 | n/a | def test_boolcontext(self): |

211 | n/a | for i in range(100): |

212 | n/a | self.assertTrue(complex(random() + 1e-6, random() + 1e-6)) |

213 | n/a | self.assertTrue(not complex(0.0, 0.0)) |

214 | n/a | |

215 | n/a | def test_conjugate(self): |

216 | n/a | self.assertClose(complex(5.3, 9.8).conjugate(), 5.3-9.8j) |

217 | n/a | |

218 | n/a | def test_constructor(self): |

219 | n/a | class OS: |

220 | n/a | def __init__(self, value): self.value = value |

221 | n/a | def __complex__(self): return self.value |

222 | n/a | class NS(object): |

223 | n/a | def __init__(self, value): self.value = value |

224 | n/a | def __complex__(self): return self.value |

225 | n/a | self.assertEqual(complex(OS(1+10j)), 1+10j) |

226 | n/a | self.assertEqual(complex(NS(1+10j)), 1+10j) |

227 | n/a | self.assertRaises(TypeError, complex, OS(None)) |

228 | n/a | self.assertRaises(TypeError, complex, NS(None)) |

229 | n/a | self.assertRaises(TypeError, complex, {}) |

230 | n/a | self.assertRaises(TypeError, complex, NS(1.5)) |

231 | n/a | self.assertRaises(TypeError, complex, NS(1)) |

232 | n/a | |

233 | n/a | self.assertAlmostEqual(complex("1+10j"), 1+10j) |

234 | n/a | self.assertAlmostEqual(complex(10), 10+0j) |

235 | n/a | self.assertAlmostEqual(complex(10.0), 10+0j) |

236 | n/a | self.assertAlmostEqual(complex(10), 10+0j) |

237 | n/a | self.assertAlmostEqual(complex(10+0j), 10+0j) |

238 | n/a | self.assertAlmostEqual(complex(1,10), 1+10j) |

239 | n/a | self.assertAlmostEqual(complex(1,10), 1+10j) |

240 | n/a | self.assertAlmostEqual(complex(1,10.0), 1+10j) |

241 | n/a | self.assertAlmostEqual(complex(1,10), 1+10j) |

242 | n/a | self.assertAlmostEqual(complex(1,10), 1+10j) |

243 | n/a | self.assertAlmostEqual(complex(1,10.0), 1+10j) |

244 | n/a | self.assertAlmostEqual(complex(1.0,10), 1+10j) |

245 | n/a | self.assertAlmostEqual(complex(1.0,10), 1+10j) |

246 | n/a | self.assertAlmostEqual(complex(1.0,10.0), 1+10j) |

247 | n/a | self.assertAlmostEqual(complex(3.14+0j), 3.14+0j) |

248 | n/a | self.assertAlmostEqual(complex(3.14), 3.14+0j) |

249 | n/a | self.assertAlmostEqual(complex(314), 314.0+0j) |

250 | n/a | self.assertAlmostEqual(complex(314), 314.0+0j) |

251 | n/a | self.assertAlmostEqual(complex(3.14+0j, 0j), 3.14+0j) |

252 | n/a | self.assertAlmostEqual(complex(3.14, 0.0), 3.14+0j) |

253 | n/a | self.assertAlmostEqual(complex(314, 0), 314.0+0j) |

254 | n/a | self.assertAlmostEqual(complex(314, 0), 314.0+0j) |

255 | n/a | self.assertAlmostEqual(complex(0j, 3.14j), -3.14+0j) |

256 | n/a | self.assertAlmostEqual(complex(0.0, 3.14j), -3.14+0j) |

257 | n/a | self.assertAlmostEqual(complex(0j, 3.14), 3.14j) |

258 | n/a | self.assertAlmostEqual(complex(0.0, 3.14), 3.14j) |

259 | n/a | self.assertAlmostEqual(complex("1"), 1+0j) |

260 | n/a | self.assertAlmostEqual(complex("1j"), 1j) |

261 | n/a | self.assertAlmostEqual(complex(), 0) |

262 | n/a | self.assertAlmostEqual(complex("-1"), -1) |

263 | n/a | self.assertAlmostEqual(complex("+1"), +1) |

264 | n/a | self.assertAlmostEqual(complex("(1+2j)"), 1+2j) |

265 | n/a | self.assertAlmostEqual(complex("(1.3+2.2j)"), 1.3+2.2j) |

266 | n/a | self.assertAlmostEqual(complex("3.14+1J"), 3.14+1j) |

267 | n/a | self.assertAlmostEqual(complex(" ( +3.14-6J )"), 3.14-6j) |

268 | n/a | self.assertAlmostEqual(complex(" ( +3.14-J )"), 3.14-1j) |

269 | n/a | self.assertAlmostEqual(complex(" ( +3.14+j )"), 3.14+1j) |

270 | n/a | self.assertAlmostEqual(complex("J"), 1j) |

271 | n/a | self.assertAlmostEqual(complex("( j )"), 1j) |

272 | n/a | self.assertAlmostEqual(complex("+J"), 1j) |

273 | n/a | self.assertAlmostEqual(complex("( -j)"), -1j) |

274 | n/a | self.assertAlmostEqual(complex('1e-500'), 0.0 + 0.0j) |

275 | n/a | self.assertAlmostEqual(complex('-1e-500j'), 0.0 - 0.0j) |

276 | n/a | self.assertAlmostEqual(complex('-1e-500+1e-500j'), -0.0 + 0.0j) |

277 | n/a | |

278 | n/a | class complex2(complex): pass |

279 | n/a | self.assertAlmostEqual(complex(complex2(1+1j)), 1+1j) |

280 | n/a | self.assertAlmostEqual(complex(real=17, imag=23), 17+23j) |

281 | n/a | self.assertAlmostEqual(complex(real=17+23j), 17+23j) |

282 | n/a | self.assertAlmostEqual(complex(real=17+23j, imag=23), 17+46j) |

283 | n/a | self.assertAlmostEqual(complex(real=1+2j, imag=3+4j), -3+5j) |

284 | n/a | |

285 | n/a | # check that the sign of a zero in the real or imaginary part |

286 | n/a | # is preserved when constructing from two floats. (These checks |

287 | n/a | # are harmless on systems without support for signed zeros.) |

288 | n/a | def split_zeros(x): |

289 | n/a | """Function that produces different results for 0. and -0.""" |

290 | n/a | return atan2(x, -1.) |

291 | n/a | |

292 | n/a | self.assertEqual(split_zeros(complex(1., 0.).imag), split_zeros(0.)) |

293 | n/a | self.assertEqual(split_zeros(complex(1., -0.).imag), split_zeros(-0.)) |

294 | n/a | self.assertEqual(split_zeros(complex(0., 1.).real), split_zeros(0.)) |

295 | n/a | self.assertEqual(split_zeros(complex(-0., 1.).real), split_zeros(-0.)) |

296 | n/a | |

297 | n/a | c = 3.14 + 1j |

298 | n/a | self.assertTrue(complex(c) is c) |

299 | n/a | del c |

300 | n/a | |

301 | n/a | self.assertRaises(TypeError, complex, "1", "1") |

302 | n/a | self.assertRaises(TypeError, complex, 1, "1") |

303 | n/a | |

304 | n/a | # SF bug 543840: complex(string) accepts strings with \0 |

305 | n/a | # Fixed in 2.3. |

306 | n/a | self.assertRaises(ValueError, complex, '1+1j\0j') |

307 | n/a | |

308 | n/a | self.assertRaises(TypeError, int, 5+3j) |

309 | n/a | self.assertRaises(TypeError, int, 5+3j) |

310 | n/a | self.assertRaises(TypeError, float, 5+3j) |

311 | n/a | self.assertRaises(ValueError, complex, "") |

312 | n/a | self.assertRaises(TypeError, complex, None) |

313 | n/a | self.assertRaisesRegex(TypeError, "not 'NoneType'", complex, None) |

314 | n/a | self.assertRaises(ValueError, complex, "\0") |

315 | n/a | self.assertRaises(ValueError, complex, "3\09") |

316 | n/a | self.assertRaises(TypeError, complex, "1", "2") |

317 | n/a | self.assertRaises(TypeError, complex, "1", 42) |

318 | n/a | self.assertRaises(TypeError, complex, 1, "2") |

319 | n/a | self.assertRaises(ValueError, complex, "1+") |

320 | n/a | self.assertRaises(ValueError, complex, "1+1j+1j") |

321 | n/a | self.assertRaises(ValueError, complex, "--") |

322 | n/a | self.assertRaises(ValueError, complex, "(1+2j") |

323 | n/a | self.assertRaises(ValueError, complex, "1+2j)") |

324 | n/a | self.assertRaises(ValueError, complex, "1+(2j)") |

325 | n/a | self.assertRaises(ValueError, complex, "(1+2j)123") |

326 | n/a | self.assertRaises(ValueError, complex, "x") |

327 | n/a | self.assertRaises(ValueError, complex, "1j+2") |

328 | n/a | self.assertRaises(ValueError, complex, "1e1ej") |

329 | n/a | self.assertRaises(ValueError, complex, "1e++1ej") |

330 | n/a | self.assertRaises(ValueError, complex, ")1+2j(") |

331 | n/a | self.assertRaisesRegex( |

332 | n/a | TypeError, |

333 | n/a | "first argument must be a string or a number, not 'dict'", |

334 | n/a | complex, {1:2}, 1) |

335 | n/a | self.assertRaisesRegex( |

336 | n/a | TypeError, |

337 | n/a | "second argument must be a number, not 'dict'", |

338 | n/a | complex, 1, {1:2}) |

339 | n/a | # the following three are accepted by Python 2.6 |

340 | n/a | self.assertRaises(ValueError, complex, "1..1j") |

341 | n/a | self.assertRaises(ValueError, complex, "1.11.1j") |

342 | n/a | self.assertRaises(ValueError, complex, "1e1.1j") |

343 | n/a | |

344 | n/a | # check that complex accepts long unicode strings |

345 | n/a | self.assertEqual(type(complex("1"*500)), complex) |

346 | n/a | # check whitespace processing |

347 | n/a | self.assertEqual(complex('\N{EM SPACE}(\N{EN SPACE}1+1j ) '), 1+1j) |

348 | n/a | |

349 | n/a | class EvilExc(Exception): |

350 | n/a | pass |

351 | n/a | |

352 | n/a | class evilcomplex: |

353 | n/a | def __complex__(self): |

354 | n/a | raise EvilExc |

355 | n/a | |

356 | n/a | self.assertRaises(EvilExc, complex, evilcomplex()) |

357 | n/a | |

358 | n/a | class float2: |

359 | n/a | def __init__(self, value): |

360 | n/a | self.value = value |

361 | n/a | def __float__(self): |

362 | n/a | return self.value |

363 | n/a | |

364 | n/a | self.assertAlmostEqual(complex(float2(42.)), 42) |

365 | n/a | self.assertAlmostEqual(complex(real=float2(17.), imag=float2(23.)), 17+23j) |

366 | n/a | self.assertRaises(TypeError, complex, float2(None)) |

367 | n/a | |

368 | n/a | class complex0(complex): |

369 | n/a | """Test usage of __complex__() when inheriting from 'complex'""" |

370 | n/a | def __complex__(self): |

371 | n/a | return 42j |

372 | n/a | |

373 | n/a | class complex1(complex): |

374 | n/a | """Test usage of __complex__() with a __new__() method""" |

375 | n/a | def __new__(self, value=0j): |

376 | n/a | return complex.__new__(self, 2*value) |

377 | n/a | def __complex__(self): |

378 | n/a | return self |

379 | n/a | |

380 | n/a | class complex2(complex): |

381 | n/a | """Make sure that __complex__() calls fail if anything other than a |

382 | n/a | complex is returned""" |

383 | n/a | def __complex__(self): |

384 | n/a | return None |

385 | n/a | |

386 | n/a | self.assertAlmostEqual(complex(complex0(1j)), 42j) |

387 | n/a | self.assertAlmostEqual(complex(complex1(1j)), 2j) |

388 | n/a | self.assertRaises(TypeError, complex, complex2(1j)) |

389 | n/a | |

390 | n/a | def test_underscores(self): |

391 | n/a | # check underscores |

392 | n/a | for lit in VALID_UNDERSCORE_LITERALS: |

393 | n/a | if not any(ch in lit for ch in 'xXoObB'): |

394 | n/a | self.assertEqual(complex(lit), eval(lit)) |

395 | n/a | self.assertEqual(complex(lit), complex(lit.replace('_', ''))) |

396 | n/a | for lit in INVALID_UNDERSCORE_LITERALS: |

397 | n/a | if lit in ('0_7', '09_99'): # octals are not recognized here |

398 | n/a | continue |

399 | n/a | if not any(ch in lit for ch in 'xXoObB'): |

400 | n/a | self.assertRaises(ValueError, complex, lit) |

401 | n/a | |

402 | n/a | def test_hash(self): |

403 | n/a | for x in range(-30, 30): |

404 | n/a | self.assertEqual(hash(x), hash(complex(x, 0))) |

405 | n/a | x /= 3.0 # now check against floating point |

406 | n/a | self.assertEqual(hash(x), hash(complex(x, 0.))) |

407 | n/a | |

408 | n/a | def test_abs(self): |

409 | n/a | nums = [complex(x/3., y/7.) for x in range(-9,9) for y in range(-9,9)] |

410 | n/a | for num in nums: |

411 | n/a | self.assertAlmostEqual((num.real**2 + num.imag**2) ** 0.5, abs(num)) |

412 | n/a | |

413 | n/a | def test_repr_str(self): |

414 | n/a | def test(v, expected, test_fn=self.assertEqual): |

415 | n/a | test_fn(repr(v), expected) |

416 | n/a | test_fn(str(v), expected) |

417 | n/a | |

418 | n/a | test(1+6j, '(1+6j)') |

419 | n/a | test(1-6j, '(1-6j)') |

420 | n/a | |

421 | n/a | test(-(1+0j), '(-1+-0j)', test_fn=self.assertNotEqual) |

422 | n/a | |

423 | n/a | test(complex(1., INF), "(1+infj)") |

424 | n/a | test(complex(1., -INF), "(1-infj)") |

425 | n/a | test(complex(INF, 1), "(inf+1j)") |

426 | n/a | test(complex(-INF, INF), "(-inf+infj)") |

427 | n/a | test(complex(NAN, 1), "(nan+1j)") |

428 | n/a | test(complex(1, NAN), "(1+nanj)") |

429 | n/a | test(complex(NAN, NAN), "(nan+nanj)") |

430 | n/a | |

431 | n/a | test(complex(0, INF), "infj") |

432 | n/a | test(complex(0, -INF), "-infj") |

433 | n/a | test(complex(0, NAN), "nanj") |

434 | n/a | |

435 | n/a | self.assertEqual(1-6j,complex(repr(1-6j))) |

436 | n/a | self.assertEqual(1+6j,complex(repr(1+6j))) |

437 | n/a | self.assertEqual(-6j,complex(repr(-6j))) |

438 | n/a | self.assertEqual(6j,complex(repr(6j))) |

439 | n/a | |

440 | n/a | @support.requires_IEEE_754 |

441 | n/a | def test_negative_zero_repr_str(self): |

442 | n/a | def test(v, expected, test_fn=self.assertEqual): |

443 | n/a | test_fn(repr(v), expected) |

444 | n/a | test_fn(str(v), expected) |

445 | n/a | |

446 | n/a | test(complex(0., 1.), "1j") |

447 | n/a | test(complex(-0., 1.), "(-0+1j)") |

448 | n/a | test(complex(0., -1.), "-1j") |

449 | n/a | test(complex(-0., -1.), "(-0-1j)") |

450 | n/a | |

451 | n/a | test(complex(0., 0.), "0j") |

452 | n/a | test(complex(0., -0.), "-0j") |

453 | n/a | test(complex(-0., 0.), "(-0+0j)") |

454 | n/a | test(complex(-0., -0.), "(-0-0j)") |

455 | n/a | |

456 | n/a | def test_neg(self): |

457 | n/a | self.assertEqual(-(1+6j), -1-6j) |

458 | n/a | |

459 | n/a | def test_file(self): |

460 | n/a | a = 3.33+4.43j |

461 | n/a | b = 5.1+2.3j |

462 | n/a | |

463 | n/a | fo = None |

464 | n/a | try: |

465 | n/a | fo = open(support.TESTFN, "w") |

466 | n/a | print(a, b, file=fo) |

467 | n/a | fo.close() |

468 | n/a | fo = open(support.TESTFN, "r") |

469 | n/a | self.assertEqual(fo.read(), ("%s %s\n" % (a, b))) |

470 | n/a | finally: |

471 | n/a | if (fo is not None) and (not fo.closed): |

472 | n/a | fo.close() |

473 | n/a | support.unlink(support.TESTFN) |

474 | n/a | |

475 | n/a | def test_getnewargs(self): |

476 | n/a | self.assertEqual((1+2j).__getnewargs__(), (1.0, 2.0)) |

477 | n/a | self.assertEqual((1-2j).__getnewargs__(), (1.0, -2.0)) |

478 | n/a | self.assertEqual((2j).__getnewargs__(), (0.0, 2.0)) |

479 | n/a | self.assertEqual((-0j).__getnewargs__(), (0.0, -0.0)) |

480 | n/a | self.assertEqual(complex(0, INF).__getnewargs__(), (0.0, INF)) |

481 | n/a | self.assertEqual(complex(INF, 0).__getnewargs__(), (INF, 0.0)) |

482 | n/a | |

483 | n/a | @support.requires_IEEE_754 |

484 | n/a | def test_plus_minus_0j(self): |

485 | n/a | # test that -0j and 0j literals are not identified |

486 | n/a | z1, z2 = 0j, -0j |

487 | n/a | self.assertEqual(atan2(z1.imag, -1.), atan2(0., -1.)) |

488 | n/a | self.assertEqual(atan2(z2.imag, -1.), atan2(-0., -1.)) |

489 | n/a | |

490 | n/a | @support.requires_IEEE_754 |

491 | n/a | def test_negated_imaginary_literal(self): |

492 | n/a | z0 = -0j |

493 | n/a | z1 = -7j |

494 | n/a | z2 = -1e1000j |

495 | n/a | # Note: In versions of Python < 3.2, a negated imaginary literal |

496 | n/a | # accidentally ended up with real part 0.0 instead of -0.0, thanks to a |

497 | n/a | # modification during CST -> AST translation (see issue #9011). That's |

498 | n/a | # fixed in Python 3.2. |

499 | n/a | self.assertFloatsAreIdentical(z0.real, -0.0) |

500 | n/a | self.assertFloatsAreIdentical(z0.imag, -0.0) |

501 | n/a | self.assertFloatsAreIdentical(z1.real, -0.0) |

502 | n/a | self.assertFloatsAreIdentical(z1.imag, -7.0) |

503 | n/a | self.assertFloatsAreIdentical(z2.real, -0.0) |

504 | n/a | self.assertFloatsAreIdentical(z2.imag, -INF) |

505 | n/a | |

506 | n/a | @support.requires_IEEE_754 |

507 | n/a | def test_overflow(self): |

508 | n/a | self.assertEqual(complex("1e500"), complex(INF, 0.0)) |

509 | n/a | self.assertEqual(complex("-1e500j"), complex(0.0, -INF)) |

510 | n/a | self.assertEqual(complex("-1e500+1.8e308j"), complex(-INF, INF)) |

511 | n/a | |

512 | n/a | @support.requires_IEEE_754 |

513 | n/a | def test_repr_roundtrip(self): |

514 | n/a | vals = [0.0, 1e-500, 1e-315, 1e-200, 0.0123, 3.1415, 1e50, INF, NAN] |

515 | n/a | vals += [-v for v in vals] |

516 | n/a | |

517 | n/a | # complex(repr(z)) should recover z exactly, even for complex |

518 | n/a | # numbers involving an infinity, nan, or negative zero |

519 | n/a | for x in vals: |

520 | n/a | for y in vals: |

521 | n/a | z = complex(x, y) |

522 | n/a | roundtrip = complex(repr(z)) |

523 | n/a | self.assertFloatsAreIdentical(z.real, roundtrip.real) |

524 | n/a | self.assertFloatsAreIdentical(z.imag, roundtrip.imag) |

525 | n/a | |

526 | n/a | # if we predefine some constants, then eval(repr(z)) should |

527 | n/a | # also work, except that it might change the sign of zeros |

528 | n/a | inf, nan = float('inf'), float('nan') |

529 | n/a | infj, nanj = complex(0.0, inf), complex(0.0, nan) |

530 | n/a | for x in vals: |

531 | n/a | for y in vals: |

532 | n/a | z = complex(x, y) |

533 | n/a | roundtrip = eval(repr(z)) |

534 | n/a | # adding 0.0 has no effect beside changing -0.0 to 0.0 |

535 | n/a | self.assertFloatsAreIdentical(0.0 + z.real, |

536 | n/a | 0.0 + roundtrip.real) |

537 | n/a | self.assertFloatsAreIdentical(0.0 + z.imag, |

538 | n/a | 0.0 + roundtrip.imag) |

539 | n/a | |

540 | n/a | def test_format(self): |

541 | n/a | # empty format string is same as str() |

542 | n/a | self.assertEqual(format(1+3j, ''), str(1+3j)) |

543 | n/a | self.assertEqual(format(1.5+3.5j, ''), str(1.5+3.5j)) |

544 | n/a | self.assertEqual(format(3j, ''), str(3j)) |

545 | n/a | self.assertEqual(format(3.2j, ''), str(3.2j)) |

546 | n/a | self.assertEqual(format(3+0j, ''), str(3+0j)) |

547 | n/a | self.assertEqual(format(3.2+0j, ''), str(3.2+0j)) |

548 | n/a | |

549 | n/a | # empty presentation type should still be analogous to str, |

550 | n/a | # even when format string is nonempty (issue #5920). |

551 | n/a | self.assertEqual(format(3.2+0j, '-'), str(3.2+0j)) |

552 | n/a | self.assertEqual(format(3.2+0j, '<'), str(3.2+0j)) |

553 | n/a | z = 4/7. - 100j/7. |

554 | n/a | self.assertEqual(format(z, ''), str(z)) |

555 | n/a | self.assertEqual(format(z, '-'), str(z)) |

556 | n/a | self.assertEqual(format(z, '<'), str(z)) |

557 | n/a | self.assertEqual(format(z, '10'), str(z)) |

558 | n/a | z = complex(0.0, 3.0) |

559 | n/a | self.assertEqual(format(z, ''), str(z)) |

560 | n/a | self.assertEqual(format(z, '-'), str(z)) |

561 | n/a | self.assertEqual(format(z, '<'), str(z)) |

562 | n/a | self.assertEqual(format(z, '2'), str(z)) |

563 | n/a | z = complex(-0.0, 2.0) |

564 | n/a | self.assertEqual(format(z, ''), str(z)) |

565 | n/a | self.assertEqual(format(z, '-'), str(z)) |

566 | n/a | self.assertEqual(format(z, '<'), str(z)) |

567 | n/a | self.assertEqual(format(z, '3'), str(z)) |

568 | n/a | |

569 | n/a | self.assertEqual(format(1+3j, 'g'), '1+3j') |

570 | n/a | self.assertEqual(format(3j, 'g'), '0+3j') |

571 | n/a | self.assertEqual(format(1.5+3.5j, 'g'), '1.5+3.5j') |

572 | n/a | |

573 | n/a | self.assertEqual(format(1.5+3.5j, '+g'), '+1.5+3.5j') |

574 | n/a | self.assertEqual(format(1.5-3.5j, '+g'), '+1.5-3.5j') |

575 | n/a | self.assertEqual(format(1.5-3.5j, '-g'), '1.5-3.5j') |

576 | n/a | self.assertEqual(format(1.5+3.5j, ' g'), ' 1.5+3.5j') |

577 | n/a | self.assertEqual(format(1.5-3.5j, ' g'), ' 1.5-3.5j') |

578 | n/a | self.assertEqual(format(-1.5+3.5j, ' g'), '-1.5+3.5j') |

579 | n/a | self.assertEqual(format(-1.5-3.5j, ' g'), '-1.5-3.5j') |

580 | n/a | |

581 | n/a | self.assertEqual(format(-1.5-3.5e-20j, 'g'), '-1.5-3.5e-20j') |

582 | n/a | self.assertEqual(format(-1.5-3.5j, 'f'), '-1.500000-3.500000j') |

583 | n/a | self.assertEqual(format(-1.5-3.5j, 'F'), '-1.500000-3.500000j') |

584 | n/a | self.assertEqual(format(-1.5-3.5j, 'e'), '-1.500000e+00-3.500000e+00j') |

585 | n/a | self.assertEqual(format(-1.5-3.5j, '.2e'), '-1.50e+00-3.50e+00j') |

586 | n/a | self.assertEqual(format(-1.5-3.5j, '.2E'), '-1.50E+00-3.50E+00j') |

587 | n/a | self.assertEqual(format(-1.5e10-3.5e5j, '.2G'), '-1.5E+10-3.5E+05j') |

588 | n/a | |

589 | n/a | self.assertEqual(format(1.5+3j, '<20g'), '1.5+3j ') |

590 | n/a | self.assertEqual(format(1.5+3j, '*<20g'), '1.5+3j**************') |

591 | n/a | self.assertEqual(format(1.5+3j, '>20g'), ' 1.5+3j') |

592 | n/a | self.assertEqual(format(1.5+3j, '^20g'), ' 1.5+3j ') |

593 | n/a | self.assertEqual(format(1.5+3j, '<20'), '(1.5+3j) ') |

594 | n/a | self.assertEqual(format(1.5+3j, '>20'), ' (1.5+3j)') |

595 | n/a | self.assertEqual(format(1.5+3j, '^20'), ' (1.5+3j) ') |

596 | n/a | self.assertEqual(format(1.123-3.123j, '^20.2'), ' (1.1-3.1j) ') |

597 | n/a | |

598 | n/a | self.assertEqual(format(1.5+3j, '20.2f'), ' 1.50+3.00j') |

599 | n/a | self.assertEqual(format(1.5+3j, '>20.2f'), ' 1.50+3.00j') |

600 | n/a | self.assertEqual(format(1.5+3j, '<20.2f'), '1.50+3.00j ') |

601 | n/a | self.assertEqual(format(1.5e20+3j, '<20.2f'), '150000000000000000000.00+3.00j') |

602 | n/a | self.assertEqual(format(1.5e20+3j, '>40.2f'), ' 150000000000000000000.00+3.00j') |

603 | n/a | self.assertEqual(format(1.5e20+3j, '^40,.2f'), ' 150,000,000,000,000,000,000.00+3.00j ') |

604 | n/a | self.assertEqual(format(1.5e21+3j, '^40,.2f'), ' 1,500,000,000,000,000,000,000.00+3.00j ') |

605 | n/a | self.assertEqual(format(1.5e21+3000j, ',.2f'), '1,500,000,000,000,000,000,000.00+3,000.00j') |

606 | n/a | |

607 | n/a | # Issue 7094: Alternate formatting (specified by #) |

608 | n/a | self.assertEqual(format(1+1j, '.0e'), '1e+00+1e+00j') |

609 | n/a | self.assertEqual(format(1+1j, '#.0e'), '1.e+00+1.e+00j') |

610 | n/a | self.assertEqual(format(1+1j, '.0f'), '1+1j') |

611 | n/a | self.assertEqual(format(1+1j, '#.0f'), '1.+1.j') |

612 | n/a | self.assertEqual(format(1.1+1.1j, 'g'), '1.1+1.1j') |

613 | n/a | self.assertEqual(format(1.1+1.1j, '#g'), '1.10000+1.10000j') |

614 | n/a | |

615 | n/a | # Alternate doesn't make a difference for these, they format the same with or without it |

616 | n/a | self.assertEqual(format(1+1j, '.1e'), '1.0e+00+1.0e+00j') |

617 | n/a | self.assertEqual(format(1+1j, '#.1e'), '1.0e+00+1.0e+00j') |

618 | n/a | self.assertEqual(format(1+1j, '.1f'), '1.0+1.0j') |

619 | n/a | self.assertEqual(format(1+1j, '#.1f'), '1.0+1.0j') |

620 | n/a | |

621 | n/a | # Misc. other alternate tests |

622 | n/a | self.assertEqual(format((-1.5+0.5j), '#f'), '-1.500000+0.500000j') |

623 | n/a | self.assertEqual(format((-1.5+0.5j), '#.0f'), '-2.+0.j') |

624 | n/a | self.assertEqual(format((-1.5+0.5j), '#e'), '-1.500000e+00+5.000000e-01j') |

625 | n/a | self.assertEqual(format((-1.5+0.5j), '#.0e'), '-2.e+00+5.e-01j') |

626 | n/a | self.assertEqual(format((-1.5+0.5j), '#g'), '-1.50000+0.500000j') |

627 | n/a | self.assertEqual(format((-1.5+0.5j), '.0g'), '-2+0.5j') |

628 | n/a | self.assertEqual(format((-1.5+0.5j), '#.0g'), '-2.+0.5j') |

629 | n/a | |

630 | n/a | # zero padding is invalid |

631 | n/a | self.assertRaises(ValueError, (1.5+0.5j).__format__, '010f') |

632 | n/a | |

633 | n/a | # '=' alignment is invalid |

634 | n/a | self.assertRaises(ValueError, (1.5+3j).__format__, '=20') |

635 | n/a | |

636 | n/a | # integer presentation types are an error |

637 | n/a | for t in 'bcdoxX': |

638 | n/a | self.assertRaises(ValueError, (1.5+0.5j).__format__, t) |

639 | n/a | |

640 | n/a | # make sure everything works in ''.format() |

641 | n/a | self.assertEqual('*{0:.3f}*'.format(3.14159+2.71828j), '*3.142+2.718j*') |

642 | n/a | |

643 | n/a | # issue 3382 |

644 | n/a | self.assertEqual(format(complex(NAN, NAN), 'f'), 'nan+nanj') |

645 | n/a | self.assertEqual(format(complex(1, NAN), 'f'), '1.000000+nanj') |

646 | n/a | self.assertEqual(format(complex(NAN, 1), 'f'), 'nan+1.000000j') |

647 | n/a | self.assertEqual(format(complex(NAN, -1), 'f'), 'nan-1.000000j') |

648 | n/a | self.assertEqual(format(complex(NAN, NAN), 'F'), 'NAN+NANj') |

649 | n/a | self.assertEqual(format(complex(1, NAN), 'F'), '1.000000+NANj') |

650 | n/a | self.assertEqual(format(complex(NAN, 1), 'F'), 'NAN+1.000000j') |

651 | n/a | self.assertEqual(format(complex(NAN, -1), 'F'), 'NAN-1.000000j') |

652 | n/a | self.assertEqual(format(complex(INF, INF), 'f'), 'inf+infj') |

653 | n/a | self.assertEqual(format(complex(1, INF), 'f'), '1.000000+infj') |

654 | n/a | self.assertEqual(format(complex(INF, 1), 'f'), 'inf+1.000000j') |

655 | n/a | self.assertEqual(format(complex(INF, -1), 'f'), 'inf-1.000000j') |

656 | n/a | self.assertEqual(format(complex(INF, INF), 'F'), 'INF+INFj') |

657 | n/a | self.assertEqual(format(complex(1, INF), 'F'), '1.000000+INFj') |

658 | n/a | self.assertEqual(format(complex(INF, 1), 'F'), 'INF+1.000000j') |

659 | n/a | self.assertEqual(format(complex(INF, -1), 'F'), 'INF-1.000000j') |

660 | n/a | |

661 | n/a | def test_main(): |

662 | n/a | support.run_unittest(ComplexTest) |

663 | n/a | |

664 | n/a | if __name__ == "__main__": |

665 | n/a | test_main() |