1import unittest 2import sys 3from test import support 4from test.test_grammar import (VALID_UNDERSCORE_LITERALS, 5 INVALID_UNDERSCORE_LITERALS) 6 7from random import random 8from math import atan2, isnan, copysign 9import operator 10 11INF = float("inf") 12NAN = float("nan") 13# These tests ensure that complex math does the right thing 14 15ZERO_DIVISION = ( 16 (1+1j, 0+0j), 17 (1+1j, 0.0), 18 (1+1j, 0), 19 (1.0, 0+0j), 20 (1, 0+0j), 21) 22 23class ComplexTest(unittest.TestCase): 24 25 def assertAlmostEqual(self, a, b): 26 if isinstance(a, complex): 27 if isinstance(b, complex): 28 unittest.TestCase.assertAlmostEqual(self, a.real, b.real) 29 unittest.TestCase.assertAlmostEqual(self, a.imag, b.imag) 30 else: 31 unittest.TestCase.assertAlmostEqual(self, a.real, b) 32 unittest.TestCase.assertAlmostEqual(self, a.imag, 0.) 33 else: 34 if isinstance(b, complex): 35 unittest.TestCase.assertAlmostEqual(self, a, b.real) 36 unittest.TestCase.assertAlmostEqual(self, 0., b.imag) 37 else: 38 unittest.TestCase.assertAlmostEqual(self, a, b) 39 40 def assertCloseAbs(self, x, y, eps=1e-9): 41 """Return true iff floats x and y "are close".""" 42 # put the one with larger magnitude second 43 if abs(x) > abs(y): 44 x, y = y, x 45 if y == 0: 46 return abs(x) < eps 47 if x == 0: 48 return abs(y) < eps 49 # check that relative difference < eps 50 self.assertTrue(abs((x-y)/y) < eps) 51 52 def assertFloatsAreIdentical(self, x, y): 53 """assert that floats x and y are identical, in the sense that: 54 (1) both x and y are nans, or 55 (2) both x and y are infinities, with the same sign, or 56 (3) both x and y are zeros, with the same sign, or 57 (4) x and y are both finite and nonzero, and x == y 58 59 """ 60 msg = 'floats {!r} and {!r} are not identical' 61 62 if isnan(x) or isnan(y): 63 if isnan(x) and isnan(y): 64 return 65 elif x == y: 66 if x != 0.0: 67 return 68 # both zero; check that signs match 69 elif copysign(1.0, x) == copysign(1.0, y): 70 return 71 else: 72 msg += ': zeros have different signs' 73 self.fail(msg.format(x, y)) 74 75 def assertClose(self, x, y, eps=1e-9): 76 """Return true iff complexes x and y "are close".""" 77 self.assertCloseAbs(x.real, y.real, eps) 78 self.assertCloseAbs(x.imag, y.imag, eps) 79 80 def check_div(self, x, y): 81 """Compute complex z=x*y, and check that z/x==y and z/y==x.""" 82 z = x * y 83 if x != 0: 84 q = z / x 85 self.assertClose(q, y) 86 q = z.__truediv__(x) 87 self.assertClose(q, y) 88 if y != 0: 89 q = z / y 90 self.assertClose(q, x) 91 q = z.__truediv__(y) 92 self.assertClose(q, x) 93 94 def test_truediv(self): 95 simple_real = [float(i) for i in range(-5, 6)] 96 simple_complex = [complex(x, y) for x in simple_real for y in simple_real] 97 for x in simple_complex: 98 for y in simple_complex: 99 self.check_div(x, y) 100 101 # A naive complex division algorithm (such as in 2.0) is very prone to 102 # nonsense errors for these (overflows and underflows). 103 self.check_div(complex(1e200, 1e200), 1+0j) 104 self.check_div(complex(1e-200, 1e-200), 1+0j) 105 106 # Just for fun. 107 for i in range(100): 108 self.check_div(complex(random(), random()), 109 complex(random(), random())) 110 111 self.assertAlmostEqual(complex.__truediv__(2+0j, 1+1j), 1-1j) 112 113 for denom_real, denom_imag in [(0, NAN), (NAN, 0), (NAN, NAN)]: 114 z = complex(0, 0) / complex(denom_real, denom_imag) 115 self.assertTrue(isnan(z.real)) 116 self.assertTrue(isnan(z.imag)) 117 118 def test_truediv_zero_division(self): 119 for a, b in ZERO_DIVISION: 120 with self.assertRaises(ZeroDivisionError): 121 a / b 122 123 def test_floordiv(self): 124 with self.assertRaises(TypeError): 125 (1+1j) // (1+0j) 126 with self.assertRaises(TypeError): 127 (1+1j) // 1.0 128 with self.assertRaises(TypeError): 129 (1+1j) // 1 130 with self.assertRaises(TypeError): 131 1.0 // (1+0j) 132 with self.assertRaises(TypeError): 133 1 // (1+0j) 134 135 def test_floordiv_zero_division(self): 136 for a, b in ZERO_DIVISION: 137 with self.assertRaises(TypeError): 138 a // b 139 140 def test_richcompare(self): 141 self.assertIs(complex.__eq__(1+1j, 1<<10000), False) 142 self.assertIs(complex.__lt__(1+1j, None), NotImplemented) 143 self.assertIs(complex.__eq__(1+1j, 1+1j), True) 144 self.assertIs(complex.__eq__(1+1j, 2+2j), False) 145 self.assertIs(complex.__ne__(1+1j, 1+1j), False) 146 self.assertIs(complex.__ne__(1+1j, 2+2j), True) 147 for i in range(1, 100): 148 f = i / 100.0 149 self.assertIs(complex.__eq__(f+0j, f), True) 150 self.assertIs(complex.__ne__(f+0j, f), False) 151 self.assertIs(complex.__eq__(complex(f, f), f), False) 152 self.assertIs(complex.__ne__(complex(f, f), f), True) 153 self.assertIs(complex.__lt__(1+1j, 2+2j), NotImplemented) 154 self.assertIs(complex.__le__(1+1j, 2+2j), NotImplemented) 155 self.assertIs(complex.__gt__(1+1j, 2+2j), NotImplemented) 156 self.assertIs(complex.__ge__(1+1j, 2+2j), NotImplemented) 157 self.assertRaises(TypeError, operator.lt, 1+1j, 2+2j) 158 self.assertRaises(TypeError, operator.le, 1+1j, 2+2j) 159 self.assertRaises(TypeError, operator.gt, 1+1j, 2+2j) 160 self.assertRaises(TypeError, operator.ge, 1+1j, 2+2j) 161 self.assertIs(operator.eq(1+1j, 1+1j), True) 162 self.assertIs(operator.eq(1+1j, 2+2j), False) 163 self.assertIs(operator.ne(1+1j, 1+1j), False) 164 self.assertIs(operator.ne(1+1j, 2+2j), True) 165 166 def test_richcompare_boundaries(self): 167 def check(n, deltas, is_equal, imag = 0.0): 168 for delta in deltas: 169 i = n + delta 170 z = complex(i, imag) 171 self.assertIs(complex.__eq__(z, i), is_equal(delta)) 172 self.assertIs(complex.__ne__(z, i), not is_equal(delta)) 173 # For IEEE-754 doubles the following should hold: 174 # x in [2 ** (52 + i), 2 ** (53 + i + 1)] -> x mod 2 ** i == 0 175 # where the interval is representable, of course. 176 for i in range(1, 10): 177 pow = 52 + i 178 mult = 2 ** i 179 check(2 ** pow, range(1, 101), lambda delta: delta % mult == 0) 180 check(2 ** pow, range(1, 101), lambda delta: False, float(i)) 181 check(2 ** 53, range(-100, 0), lambda delta: True) 182 183 def test_mod(self): 184 # % is no longer supported on complex numbers 185 with self.assertRaises(TypeError): 186 (1+1j) % (1+0j) 187 with self.assertRaises(TypeError): 188 (1+1j) % 1.0 189 with self.assertRaises(TypeError): 190 (1+1j) % 1 191 with self.assertRaises(TypeError): 192 1.0 % (1+0j) 193 with self.assertRaises(TypeError): 194 1 % (1+0j) 195 196 def test_mod_zero_division(self): 197 for a, b in ZERO_DIVISION: 198 with self.assertRaises(TypeError): 199 a % b 200 201 def test_divmod(self): 202 self.assertRaises(TypeError, divmod, 1+1j, 1+0j) 203 self.assertRaises(TypeError, divmod, 1+1j, 1.0) 204 self.assertRaises(TypeError, divmod, 1+1j, 1) 205 self.assertRaises(TypeError, divmod, 1.0, 1+0j) 206 self.assertRaises(TypeError, divmod, 1, 1+0j) 207 208 def test_divmod_zero_division(self): 209 for a, b in ZERO_DIVISION: 210 self.assertRaises(TypeError, divmod, a, b) 211 212 def test_pow(self): 213 self.assertAlmostEqual(pow(1+1j, 0+0j), 1.0) 214 self.assertAlmostEqual(pow(0+0j, 2+0j), 0.0) 215 self.assertRaises(ZeroDivisionError, pow, 0+0j, 1j) 216 self.assertAlmostEqual(pow(1j, -1), 1/1j) 217 self.assertAlmostEqual(pow(1j, 200), 1) 218 self.assertRaises(ValueError, pow, 1+1j, 1+1j, 1+1j) 219 self.assertRaises(OverflowError, pow, 1e200+1j, 1e200+1j) 220 221 a = 3.33+4.43j 222 self.assertEqual(a ** 0j, 1) 223 self.assertEqual(a ** 0.+0.j, 1) 224 225 self.assertEqual(3j ** 0j, 1) 226 self.assertEqual(3j ** 0, 1) 227 228 try: 229 0j ** a 230 except ZeroDivisionError: 231 pass 232 else: 233 self.fail("should fail 0.0 to negative or complex power") 234 235 try: 236 0j ** (3-2j) 237 except ZeroDivisionError: 238 pass 239 else: 240 self.fail("should fail 0.0 to negative or complex power") 241 242 # The following is used to exercise certain code paths 243 self.assertEqual(a ** 105, a ** 105) 244 self.assertEqual(a ** -105, a ** -105) 245 self.assertEqual(a ** -30, a ** -30) 246 247 self.assertEqual(0.0j ** 0, 1) 248 249 b = 5.1+2.3j 250 self.assertRaises(ValueError, pow, a, b, 0) 251 252 # Check some boundary conditions; some of these used to invoke 253 # undefined behaviour (https://bugs.python.org/issue44698). We're 254 # not actually checking the results of these operations, just making 255 # sure they don't crash (for example when using clang's 256 # UndefinedBehaviourSanitizer). 257 values = (sys.maxsize, sys.maxsize+1, sys.maxsize-1, 258 -sys.maxsize, -sys.maxsize+1, -sys.maxsize+1) 259 for real in values: 260 for imag in values: 261 with self.subTest(real=real, imag=imag): 262 c = complex(real, imag) 263 try: 264 c ** real 265 except OverflowError: 266 pass 267 try: 268 c ** c 269 except OverflowError: 270 pass 271 272 def test_pow_with_small_integer_exponents(self): 273 # Check that small integer exponents are handled identically 274 # regardless of their type. 275 values = [ 276 complex(5.0, 12.0), 277 complex(5.0e100, 12.0e100), 278 complex(-4.0, INF), 279 complex(INF, 0.0), 280 ] 281 exponents = [-19, -5, -3, -2, -1, 0, 1, 2, 3, 5, 19] 282 for value in values: 283 for exponent in exponents: 284 with self.subTest(value=value, exponent=exponent): 285 try: 286 int_pow = value**exponent 287 except OverflowError: 288 int_pow = "overflow" 289 try: 290 float_pow = value**float(exponent) 291 except OverflowError: 292 float_pow = "overflow" 293 try: 294 complex_pow = value**complex(exponent) 295 except OverflowError: 296 complex_pow = "overflow" 297 self.assertEqual(str(float_pow), str(int_pow)) 298 self.assertEqual(str(complex_pow), str(int_pow)) 299 300 def test_boolcontext(self): 301 for i in range(100): 302 self.assertTrue(complex(random() + 1e-6, random() + 1e-6)) 303 self.assertTrue(not complex(0.0, 0.0)) 304 305 def test_conjugate(self): 306 self.assertClose(complex(5.3, 9.8).conjugate(), 5.3-9.8j) 307 308 def test_constructor(self): 309 class OS: 310 def __init__(self, value): self.value = value 311 def __complex__(self): return self.value 312 class NS(object): 313 def __init__(self, value): self.value = value 314 def __complex__(self): return self.value 315 self.assertEqual(complex(OS(1+10j)), 1+10j) 316 self.assertEqual(complex(NS(1+10j)), 1+10j) 317 self.assertRaises(TypeError, complex, OS(None)) 318 self.assertRaises(TypeError, complex, NS(None)) 319 self.assertRaises(TypeError, complex, {}) 320 self.assertRaises(TypeError, complex, NS(1.5)) 321 self.assertRaises(TypeError, complex, NS(1)) 322 323 self.assertAlmostEqual(complex("1+10j"), 1+10j) 324 self.assertAlmostEqual(complex(10), 10+0j) 325 self.assertAlmostEqual(complex(10.0), 10+0j) 326 self.assertAlmostEqual(complex(10), 10+0j) 327 self.assertAlmostEqual(complex(10+0j), 10+0j) 328 self.assertAlmostEqual(complex(1,10), 1+10j) 329 self.assertAlmostEqual(complex(1,10), 1+10j) 330 self.assertAlmostEqual(complex(1,10.0), 1+10j) 331 self.assertAlmostEqual(complex(1,10), 1+10j) 332 self.assertAlmostEqual(complex(1,10), 1+10j) 333 self.assertAlmostEqual(complex(1,10.0), 1+10j) 334 self.assertAlmostEqual(complex(1.0,10), 1+10j) 335 self.assertAlmostEqual(complex(1.0,10), 1+10j) 336 self.assertAlmostEqual(complex(1.0,10.0), 1+10j) 337 self.assertAlmostEqual(complex(3.14+0j), 3.14+0j) 338 self.assertAlmostEqual(complex(3.14), 3.14+0j) 339 self.assertAlmostEqual(complex(314), 314.0+0j) 340 self.assertAlmostEqual(complex(314), 314.0+0j) 341 self.assertAlmostEqual(complex(3.14+0j, 0j), 3.14+0j) 342 self.assertAlmostEqual(complex(3.14, 0.0), 3.14+0j) 343 self.assertAlmostEqual(complex(314, 0), 314.0+0j) 344 self.assertAlmostEqual(complex(314, 0), 314.0+0j) 345 self.assertAlmostEqual(complex(0j, 3.14j), -3.14+0j) 346 self.assertAlmostEqual(complex(0.0, 3.14j), -3.14+0j) 347 self.assertAlmostEqual(complex(0j, 3.14), 3.14j) 348 self.assertAlmostEqual(complex(0.0, 3.14), 3.14j) 349 self.assertAlmostEqual(complex("1"), 1+0j) 350 self.assertAlmostEqual(complex("1j"), 1j) 351 self.assertAlmostEqual(complex(), 0) 352 self.assertAlmostEqual(complex("-1"), -1) 353 self.assertAlmostEqual(complex("+1"), +1) 354 self.assertAlmostEqual(complex("(1+2j)"), 1+2j) 355 self.assertAlmostEqual(complex("(1.3+2.2j)"), 1.3+2.2j) 356 self.assertAlmostEqual(complex("3.14+1J"), 3.14+1j) 357 self.assertAlmostEqual(complex(" ( +3.14-6J )"), 3.14-6j) 358 self.assertAlmostEqual(complex(" ( +3.14-J )"), 3.14-1j) 359 self.assertAlmostEqual(complex(" ( +3.14+j )"), 3.14+1j) 360 self.assertAlmostEqual(complex("J"), 1j) 361 self.assertAlmostEqual(complex("( j )"), 1j) 362 self.assertAlmostEqual(complex("+J"), 1j) 363 self.assertAlmostEqual(complex("( -j)"), -1j) 364 self.assertAlmostEqual(complex('1e-500'), 0.0 + 0.0j) 365 self.assertAlmostEqual(complex('-1e-500j'), 0.0 - 0.0j) 366 self.assertAlmostEqual(complex('-1e-500+1e-500j'), -0.0 + 0.0j) 367 368 class complex2(complex): pass 369 self.assertAlmostEqual(complex(complex2(1+1j)), 1+1j) 370 self.assertAlmostEqual(complex(real=17, imag=23), 17+23j) 371 self.assertAlmostEqual(complex(real=17+23j), 17+23j) 372 self.assertAlmostEqual(complex(real=17+23j, imag=23), 17+46j) 373 self.assertAlmostEqual(complex(real=1+2j, imag=3+4j), -3+5j) 374 375 # check that the sign of a zero in the real or imaginary part 376 # is preserved when constructing from two floats. (These checks 377 # are harmless on systems without support for signed zeros.) 378 def split_zeros(x): 379 """Function that produces different results for 0. and -0.""" 380 return atan2(x, -1.) 381 382 self.assertEqual(split_zeros(complex(1., 0.).imag), split_zeros(0.)) 383 self.assertEqual(split_zeros(complex(1., -0.).imag), split_zeros(-0.)) 384 self.assertEqual(split_zeros(complex(0., 1.).real), split_zeros(0.)) 385 self.assertEqual(split_zeros(complex(-0., 1.).real), split_zeros(-0.)) 386 387 c = 3.14 + 1j 388 self.assertTrue(complex(c) is c) 389 del c 390 391 self.assertRaises(TypeError, complex, "1", "1") 392 self.assertRaises(TypeError, complex, 1, "1") 393 394 # SF bug 543840: complex(string) accepts strings with \0 395 # Fixed in 2.3. 396 self.assertRaises(ValueError, complex, '1+1j\0j') 397 398 self.assertRaises(TypeError, int, 5+3j) 399 self.assertRaises(TypeError, int, 5+3j) 400 self.assertRaises(TypeError, float, 5+3j) 401 self.assertRaises(ValueError, complex, "") 402 self.assertRaises(TypeError, complex, None) 403 self.assertRaisesRegex(TypeError, "not 'NoneType'", complex, None) 404 self.assertRaises(ValueError, complex, "\0") 405 self.assertRaises(ValueError, complex, "3\09") 406 self.assertRaises(TypeError, complex, "1", "2") 407 self.assertRaises(TypeError, complex, "1", 42) 408 self.assertRaises(TypeError, complex, 1, "2") 409 self.assertRaises(ValueError, complex, "1+") 410 self.assertRaises(ValueError, complex, "1+1j+1j") 411 self.assertRaises(ValueError, complex, "--") 412 self.assertRaises(ValueError, complex, "(1+2j") 413 self.assertRaises(ValueError, complex, "1+2j)") 414 self.assertRaises(ValueError, complex, "1+(2j)") 415 self.assertRaises(ValueError, complex, "(1+2j)123") 416 self.assertRaises(ValueError, complex, "x") 417 self.assertRaises(ValueError, complex, "1j+2") 418 self.assertRaises(ValueError, complex, "1e1ej") 419 self.assertRaises(ValueError, complex, "1e++1ej") 420 self.assertRaises(ValueError, complex, ")1+2j(") 421 self.assertRaisesRegex( 422 TypeError, 423 "first argument must be a string or a number, not 'dict'", 424 complex, {1:2}, 1) 425 self.assertRaisesRegex( 426 TypeError, 427 "second argument must be a number, not 'dict'", 428 complex, 1, {1:2}) 429 # the following three are accepted by Python 2.6 430 self.assertRaises(ValueError, complex, "1..1j") 431 self.assertRaises(ValueError, complex, "1.11.1j") 432 self.assertRaises(ValueError, complex, "1e1.1j") 433 434 # check that complex accepts long unicode strings 435 self.assertEqual(type(complex("1"*500)), complex) 436 # check whitespace processing 437 self.assertEqual(complex('\N{EM SPACE}(\N{EN SPACE}1+1j ) '), 1+1j) 438 # Invalid unicode string 439 # See bpo-34087 440 self.assertRaises(ValueError, complex, '\u3053\u3093\u306b\u3061\u306f') 441 442 class EvilExc(Exception): 443 pass 444 445 class evilcomplex: 446 def __complex__(self): 447 raise EvilExc 448 449 self.assertRaises(EvilExc, complex, evilcomplex()) 450 451 class float2: 452 def __init__(self, value): 453 self.value = value 454 def __float__(self): 455 return self.value 456 457 self.assertAlmostEqual(complex(float2(42.)), 42) 458 self.assertAlmostEqual(complex(real=float2(17.), imag=float2(23.)), 17+23j) 459 self.assertRaises(TypeError, complex, float2(None)) 460 461 class MyIndex: 462 def __init__(self, value): 463 self.value = value 464 def __index__(self): 465 return self.value 466 467 self.assertAlmostEqual(complex(MyIndex(42)), 42.0+0.0j) 468 self.assertAlmostEqual(complex(123, MyIndex(42)), 123.0+42.0j) 469 self.assertRaises(OverflowError, complex, MyIndex(2**2000)) 470 self.assertRaises(OverflowError, complex, 123, MyIndex(2**2000)) 471 472 class MyInt: 473 def __int__(self): 474 return 42 475 476 self.assertRaises(TypeError, complex, MyInt()) 477 self.assertRaises(TypeError, complex, 123, MyInt()) 478 479 class complex0(complex): 480 """Test usage of __complex__() when inheriting from 'complex'""" 481 def __complex__(self): 482 return 42j 483 484 class complex1(complex): 485 """Test usage of __complex__() with a __new__() method""" 486 def __new__(self, value=0j): 487 return complex.__new__(self, 2*value) 488 def __complex__(self): 489 return self 490 491 class complex2(complex): 492 """Make sure that __complex__() calls fail if anything other than a 493 complex is returned""" 494 def __complex__(self): 495 return None 496 497 self.assertEqual(complex(complex0(1j)), 42j) 498 with self.assertWarns(DeprecationWarning): 499 self.assertEqual(complex(complex1(1j)), 2j) 500 self.assertRaises(TypeError, complex, complex2(1j)) 501 502 def test___complex__(self): 503 z = 3 + 4j 504 self.assertEqual(z.__complex__(), z) 505 self.assertEqual(type(z.__complex__()), complex) 506 507 class complex_subclass(complex): 508 pass 509 510 z = complex_subclass(3 + 4j) 511 self.assertEqual(z.__complex__(), 3 + 4j) 512 self.assertEqual(type(z.__complex__()), complex) 513 514 @support.requires_IEEE_754 515 def test_constructor_special_numbers(self): 516 class complex2(complex): 517 pass 518 for x in 0.0, -0.0, INF, -INF, NAN: 519 for y in 0.0, -0.0, INF, -INF, NAN: 520 with self.subTest(x=x, y=y): 521 z = complex(x, y) 522 self.assertFloatsAreIdentical(z.real, x) 523 self.assertFloatsAreIdentical(z.imag, y) 524 z = complex2(x, y) 525 self.assertIs(type(z), complex2) 526 self.assertFloatsAreIdentical(z.real, x) 527 self.assertFloatsAreIdentical(z.imag, y) 528 z = complex(complex2(x, y)) 529 self.assertIs(type(z), complex) 530 self.assertFloatsAreIdentical(z.real, x) 531 self.assertFloatsAreIdentical(z.imag, y) 532 z = complex2(complex(x, y)) 533 self.assertIs(type(z), complex2) 534 self.assertFloatsAreIdentical(z.real, x) 535 self.assertFloatsAreIdentical(z.imag, y) 536 537 def test_underscores(self): 538 # check underscores 539 for lit in VALID_UNDERSCORE_LITERALS: 540 if not any(ch in lit for ch in 'xXoObB'): 541 self.assertEqual(complex(lit), eval(lit)) 542 self.assertEqual(complex(lit), complex(lit.replace('_', ''))) 543 for lit in INVALID_UNDERSCORE_LITERALS: 544 if lit in ('0_7', '09_99'): # octals are not recognized here 545 continue 546 if not any(ch in lit for ch in 'xXoObB'): 547 self.assertRaises(ValueError, complex, lit) 548 549 def test_hash(self): 550 for x in range(-30, 30): 551 self.assertEqual(hash(x), hash(complex(x, 0))) 552 x /= 3.0 # now check against floating point 553 self.assertEqual(hash(x), hash(complex(x, 0.))) 554 555 def test_abs(self): 556 nums = [complex(x/3., y/7.) for x in range(-9,9) for y in range(-9,9)] 557 for num in nums: 558 self.assertAlmostEqual((num.real**2 + num.imag**2) ** 0.5, abs(num)) 559 560 def test_repr_str(self): 561 def test(v, expected, test_fn=self.assertEqual): 562 test_fn(repr(v), expected) 563 test_fn(str(v), expected) 564 565 test(1+6j, '(1+6j)') 566 test(1-6j, '(1-6j)') 567 568 test(-(1+0j), '(-1+-0j)', test_fn=self.assertNotEqual) 569 570 test(complex(1., INF), "(1+infj)") 571 test(complex(1., -INF), "(1-infj)") 572 test(complex(INF, 1), "(inf+1j)") 573 test(complex(-INF, INF), "(-inf+infj)") 574 test(complex(NAN, 1), "(nan+1j)") 575 test(complex(1, NAN), "(1+nanj)") 576 test(complex(NAN, NAN), "(nan+nanj)") 577 578 test(complex(0, INF), "infj") 579 test(complex(0, -INF), "-infj") 580 test(complex(0, NAN), "nanj") 581 582 self.assertEqual(1-6j,complex(repr(1-6j))) 583 self.assertEqual(1+6j,complex(repr(1+6j))) 584 self.assertEqual(-6j,complex(repr(-6j))) 585 self.assertEqual(6j,complex(repr(6j))) 586 587 @support.requires_IEEE_754 588 def test_negative_zero_repr_str(self): 589 def test(v, expected, test_fn=self.assertEqual): 590 test_fn(repr(v), expected) 591 test_fn(str(v), expected) 592 593 test(complex(0., 1.), "1j") 594 test(complex(-0., 1.), "(-0+1j)") 595 test(complex(0., -1.), "-1j") 596 test(complex(-0., -1.), "(-0-1j)") 597 598 test(complex(0., 0.), "0j") 599 test(complex(0., -0.), "-0j") 600 test(complex(-0., 0.), "(-0+0j)") 601 test(complex(-0., -0.), "(-0-0j)") 602 603 def test_neg(self): 604 self.assertEqual(-(1+6j), -1-6j) 605 606 def test_getnewargs(self): 607 self.assertEqual((1+2j).__getnewargs__(), (1.0, 2.0)) 608 self.assertEqual((1-2j).__getnewargs__(), (1.0, -2.0)) 609 self.assertEqual((2j).__getnewargs__(), (0.0, 2.0)) 610 self.assertEqual((-0j).__getnewargs__(), (0.0, -0.0)) 611 self.assertEqual(complex(0, INF).__getnewargs__(), (0.0, INF)) 612 self.assertEqual(complex(INF, 0).__getnewargs__(), (INF, 0.0)) 613 614 @support.requires_IEEE_754 615 def test_plus_minus_0j(self): 616 # test that -0j and 0j literals are not identified 617 z1, z2 = 0j, -0j 618 self.assertEqual(atan2(z1.imag, -1.), atan2(0., -1.)) 619 self.assertEqual(atan2(z2.imag, -1.), atan2(-0., -1.)) 620 621 @support.requires_IEEE_754 622 def test_negated_imaginary_literal(self): 623 z0 = -0j 624 z1 = -7j 625 z2 = -1e1000j 626 # Note: In versions of Python < 3.2, a negated imaginary literal 627 # accidentally ended up with real part 0.0 instead of -0.0, thanks to a 628 # modification during CST -> AST translation (see issue #9011). That's 629 # fixed in Python 3.2. 630 self.assertFloatsAreIdentical(z0.real, -0.0) 631 self.assertFloatsAreIdentical(z0.imag, -0.0) 632 self.assertFloatsAreIdentical(z1.real, -0.0) 633 self.assertFloatsAreIdentical(z1.imag, -7.0) 634 self.assertFloatsAreIdentical(z2.real, -0.0) 635 self.assertFloatsAreIdentical(z2.imag, -INF) 636 637 @support.requires_IEEE_754 638 def test_overflow(self): 639 self.assertEqual(complex("1e500"), complex(INF, 0.0)) 640 self.assertEqual(complex("-1e500j"), complex(0.0, -INF)) 641 self.assertEqual(complex("-1e500+1.8e308j"), complex(-INF, INF)) 642 643 @support.requires_IEEE_754 644 def test_repr_roundtrip(self): 645 vals = [0.0, 1e-500, 1e-315, 1e-200, 0.0123, 3.1415, 1e50, INF, NAN] 646 vals += [-v for v in vals] 647 648 # complex(repr(z)) should recover z exactly, even for complex 649 # numbers involving an infinity, nan, or negative zero 650 for x in vals: 651 for y in vals: 652 z = complex(x, y) 653 roundtrip = complex(repr(z)) 654 self.assertFloatsAreIdentical(z.real, roundtrip.real) 655 self.assertFloatsAreIdentical(z.imag, roundtrip.imag) 656 657 # if we predefine some constants, then eval(repr(z)) should 658 # also work, except that it might change the sign of zeros 659 inf, nan = float('inf'), float('nan') 660 infj, nanj = complex(0.0, inf), complex(0.0, nan) 661 for x in vals: 662 for y in vals: 663 z = complex(x, y) 664 roundtrip = eval(repr(z)) 665 # adding 0.0 has no effect beside changing -0.0 to 0.0 666 self.assertFloatsAreIdentical(0.0 + z.real, 667 0.0 + roundtrip.real) 668 self.assertFloatsAreIdentical(0.0 + z.imag, 669 0.0 + roundtrip.imag) 670 671 def test_format(self): 672 # empty format string is same as str() 673 self.assertEqual(format(1+3j, ''), str(1+3j)) 674 self.assertEqual(format(1.5+3.5j, ''), str(1.5+3.5j)) 675 self.assertEqual(format(3j, ''), str(3j)) 676 self.assertEqual(format(3.2j, ''), str(3.2j)) 677 self.assertEqual(format(3+0j, ''), str(3+0j)) 678 self.assertEqual(format(3.2+0j, ''), str(3.2+0j)) 679 680 # empty presentation type should still be analogous to str, 681 # even when format string is nonempty (issue #5920). 682 self.assertEqual(format(3.2+0j, '-'), str(3.2+0j)) 683 self.assertEqual(format(3.2+0j, '<'), str(3.2+0j)) 684 z = 4/7. - 100j/7. 685 self.assertEqual(format(z, ''), str(z)) 686 self.assertEqual(format(z, '-'), str(z)) 687 self.assertEqual(format(z, '<'), str(z)) 688 self.assertEqual(format(z, '10'), str(z)) 689 z = complex(0.0, 3.0) 690 self.assertEqual(format(z, ''), str(z)) 691 self.assertEqual(format(z, '-'), str(z)) 692 self.assertEqual(format(z, '<'), str(z)) 693 self.assertEqual(format(z, '2'), str(z)) 694 z = complex(-0.0, 2.0) 695 self.assertEqual(format(z, ''), str(z)) 696 self.assertEqual(format(z, '-'), str(z)) 697 self.assertEqual(format(z, '<'), str(z)) 698 self.assertEqual(format(z, '3'), str(z)) 699 700 self.assertEqual(format(1+3j, 'g'), '1+3j') 701 self.assertEqual(format(3j, 'g'), '0+3j') 702 self.assertEqual(format(1.5+3.5j, 'g'), '1.5+3.5j') 703 704 self.assertEqual(format(1.5+3.5j, '+g'), '+1.5+3.5j') 705 self.assertEqual(format(1.5-3.5j, '+g'), '+1.5-3.5j') 706 self.assertEqual(format(1.5-3.5j, '-g'), '1.5-3.5j') 707 self.assertEqual(format(1.5+3.5j, ' g'), ' 1.5+3.5j') 708 self.assertEqual(format(1.5-3.5j, ' g'), ' 1.5-3.5j') 709 self.assertEqual(format(-1.5+3.5j, ' g'), '-1.5+3.5j') 710 self.assertEqual(format(-1.5-3.5j, ' g'), '-1.5-3.5j') 711 712 self.assertEqual(format(-1.5-3.5e-20j, 'g'), '-1.5-3.5e-20j') 713 self.assertEqual(format(-1.5-3.5j, 'f'), '-1.500000-3.500000j') 714 self.assertEqual(format(-1.5-3.5j, 'F'), '-1.500000-3.500000j') 715 self.assertEqual(format(-1.5-3.5j, 'e'), '-1.500000e+00-3.500000e+00j') 716 self.assertEqual(format(-1.5-3.5j, '.2e'), '-1.50e+00-3.50e+00j') 717 self.assertEqual(format(-1.5-3.5j, '.2E'), '-1.50E+00-3.50E+00j') 718 self.assertEqual(format(-1.5e10-3.5e5j, '.2G'), '-1.5E+10-3.5E+05j') 719 720 self.assertEqual(format(1.5+3j, '<20g'), '1.5+3j ') 721 self.assertEqual(format(1.5+3j, '*<20g'), '1.5+3j**************') 722 self.assertEqual(format(1.5+3j, '>20g'), ' 1.5+3j') 723 self.assertEqual(format(1.5+3j, '^20g'), ' 1.5+3j ') 724 self.assertEqual(format(1.5+3j, '<20'), '(1.5+3j) ') 725 self.assertEqual(format(1.5+3j, '>20'), ' (1.5+3j)') 726 self.assertEqual(format(1.5+3j, '^20'), ' (1.5+3j) ') 727 self.assertEqual(format(1.123-3.123j, '^20.2'), ' (1.1-3.1j) ') 728 729 self.assertEqual(format(1.5+3j, '20.2f'), ' 1.50+3.00j') 730 self.assertEqual(format(1.5+3j, '>20.2f'), ' 1.50+3.00j') 731 self.assertEqual(format(1.5+3j, '<20.2f'), '1.50+3.00j ') 732 self.assertEqual(format(1.5e20+3j, '<20.2f'), '150000000000000000000.00+3.00j') 733 self.assertEqual(format(1.5e20+3j, '>40.2f'), ' 150000000000000000000.00+3.00j') 734 self.assertEqual(format(1.5e20+3j, '^40,.2f'), ' 150,000,000,000,000,000,000.00+3.00j ') 735 self.assertEqual(format(1.5e21+3j, '^40,.2f'), ' 1,500,000,000,000,000,000,000.00+3.00j ') 736 self.assertEqual(format(1.5e21+3000j, ',.2f'), '1,500,000,000,000,000,000,000.00+3,000.00j') 737 738 # Issue 7094: Alternate formatting (specified by #) 739 self.assertEqual(format(1+1j, '.0e'), '1e+00+1e+00j') 740 self.assertEqual(format(1+1j, '#.0e'), '1.e+00+1.e+00j') 741 self.assertEqual(format(1+1j, '.0f'), '1+1j') 742 self.assertEqual(format(1+1j, '#.0f'), '1.+1.j') 743 self.assertEqual(format(1.1+1.1j, 'g'), '1.1+1.1j') 744 self.assertEqual(format(1.1+1.1j, '#g'), '1.10000+1.10000j') 745 746 # Alternate doesn't make a difference for these, they format the same with or without it 747 self.assertEqual(format(1+1j, '.1e'), '1.0e+00+1.0e+00j') 748 self.assertEqual(format(1+1j, '#.1e'), '1.0e+00+1.0e+00j') 749 self.assertEqual(format(1+1j, '.1f'), '1.0+1.0j') 750 self.assertEqual(format(1+1j, '#.1f'), '1.0+1.0j') 751 752 # Misc. other alternate tests 753 self.assertEqual(format((-1.5+0.5j), '#f'), '-1.500000+0.500000j') 754 self.assertEqual(format((-1.5+0.5j), '#.0f'), '-2.+0.j') 755 self.assertEqual(format((-1.5+0.5j), '#e'), '-1.500000e+00+5.000000e-01j') 756 self.assertEqual(format((-1.5+0.5j), '#.0e'), '-2.e+00+5.e-01j') 757 self.assertEqual(format((-1.5+0.5j), '#g'), '-1.50000+0.500000j') 758 self.assertEqual(format((-1.5+0.5j), '.0g'), '-2+0.5j') 759 self.assertEqual(format((-1.5+0.5j), '#.0g'), '-2.+0.5j') 760 761 # zero padding is invalid 762 self.assertRaises(ValueError, (1.5+0.5j).__format__, '010f') 763 764 # '=' alignment is invalid 765 self.assertRaises(ValueError, (1.5+3j).__format__, '=20') 766 767 # integer presentation types are an error 768 for t in 'bcdoxX': 769 self.assertRaises(ValueError, (1.5+0.5j).__format__, t) 770 771 # make sure everything works in ''.format() 772 self.assertEqual('*{0:.3f}*'.format(3.14159+2.71828j), '*3.142+2.718j*') 773 774 # issue 3382 775 self.assertEqual(format(complex(NAN, NAN), 'f'), 'nan+nanj') 776 self.assertEqual(format(complex(1, NAN), 'f'), '1.000000+nanj') 777 self.assertEqual(format(complex(NAN, 1), 'f'), 'nan+1.000000j') 778 self.assertEqual(format(complex(NAN, -1), 'f'), 'nan-1.000000j') 779 self.assertEqual(format(complex(NAN, NAN), 'F'), 'NAN+NANj') 780 self.assertEqual(format(complex(1, NAN), 'F'), '1.000000+NANj') 781 self.assertEqual(format(complex(NAN, 1), 'F'), 'NAN+1.000000j') 782 self.assertEqual(format(complex(NAN, -1), 'F'), 'NAN-1.000000j') 783 self.assertEqual(format(complex(INF, INF), 'f'), 'inf+infj') 784 self.assertEqual(format(complex(1, INF), 'f'), '1.000000+infj') 785 self.assertEqual(format(complex(INF, 1), 'f'), 'inf+1.000000j') 786 self.assertEqual(format(complex(INF, -1), 'f'), 'inf-1.000000j') 787 self.assertEqual(format(complex(INF, INF), 'F'), 'INF+INFj') 788 self.assertEqual(format(complex(1, INF), 'F'), '1.000000+INFj') 789 self.assertEqual(format(complex(INF, 1), 'F'), 'INF+1.000000j') 790 self.assertEqual(format(complex(INF, -1), 'F'), 'INF-1.000000j') 791 792 793if __name__ == "__main__": 794 unittest.main() 795