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 NS: 310 def __init__(self, value): self.value = value 311 def __complex__(self): return self.value 312 self.assertEqual(complex(NS(1+10j)), 1+10j) 313 self.assertRaises(TypeError, complex, NS(None)) 314 self.assertRaises(TypeError, complex, {}) 315 self.assertRaises(TypeError, complex, NS(1.5)) 316 self.assertRaises(TypeError, complex, NS(1)) 317 318 self.assertAlmostEqual(complex("1+10j"), 1+10j) 319 self.assertAlmostEqual(complex(10), 10+0j) 320 self.assertAlmostEqual(complex(10.0), 10+0j) 321 self.assertAlmostEqual(complex(10), 10+0j) 322 self.assertAlmostEqual(complex(10+0j), 10+0j) 323 self.assertAlmostEqual(complex(1,10), 1+10j) 324 self.assertAlmostEqual(complex(1,10), 1+10j) 325 self.assertAlmostEqual(complex(1,10.0), 1+10j) 326 self.assertAlmostEqual(complex(1,10), 1+10j) 327 self.assertAlmostEqual(complex(1,10), 1+10j) 328 self.assertAlmostEqual(complex(1,10.0), 1+10j) 329 self.assertAlmostEqual(complex(1.0,10), 1+10j) 330 self.assertAlmostEqual(complex(1.0,10), 1+10j) 331 self.assertAlmostEqual(complex(1.0,10.0), 1+10j) 332 self.assertAlmostEqual(complex(3.14+0j), 3.14+0j) 333 self.assertAlmostEqual(complex(3.14), 3.14+0j) 334 self.assertAlmostEqual(complex(314), 314.0+0j) 335 self.assertAlmostEqual(complex(314), 314.0+0j) 336 self.assertAlmostEqual(complex(3.14+0j, 0j), 3.14+0j) 337 self.assertAlmostEqual(complex(3.14, 0.0), 3.14+0j) 338 self.assertAlmostEqual(complex(314, 0), 314.0+0j) 339 self.assertAlmostEqual(complex(314, 0), 314.0+0j) 340 self.assertAlmostEqual(complex(0j, 3.14j), -3.14+0j) 341 self.assertAlmostEqual(complex(0.0, 3.14j), -3.14+0j) 342 self.assertAlmostEqual(complex(0j, 3.14), 3.14j) 343 self.assertAlmostEqual(complex(0.0, 3.14), 3.14j) 344 self.assertAlmostEqual(complex("1"), 1+0j) 345 self.assertAlmostEqual(complex("1j"), 1j) 346 self.assertAlmostEqual(complex(), 0) 347 self.assertAlmostEqual(complex("-1"), -1) 348 self.assertAlmostEqual(complex("+1"), +1) 349 self.assertAlmostEqual(complex("(1+2j)"), 1+2j) 350 self.assertAlmostEqual(complex("(1.3+2.2j)"), 1.3+2.2j) 351 self.assertAlmostEqual(complex("3.14+1J"), 3.14+1j) 352 self.assertAlmostEqual(complex(" ( +3.14-6J )"), 3.14-6j) 353 self.assertAlmostEqual(complex(" ( +3.14-J )"), 3.14-1j) 354 self.assertAlmostEqual(complex(" ( +3.14+j )"), 3.14+1j) 355 self.assertAlmostEqual(complex("J"), 1j) 356 self.assertAlmostEqual(complex("( j )"), 1j) 357 self.assertAlmostEqual(complex("+J"), 1j) 358 self.assertAlmostEqual(complex("( -j)"), -1j) 359 self.assertAlmostEqual(complex('1e-500'), 0.0 + 0.0j) 360 self.assertAlmostEqual(complex('-1e-500j'), 0.0 - 0.0j) 361 self.assertAlmostEqual(complex('-1e-500+1e-500j'), -0.0 + 0.0j) 362 363 class complex2(complex): pass 364 self.assertAlmostEqual(complex(complex2(1+1j)), 1+1j) 365 self.assertAlmostEqual(complex(real=17, imag=23), 17+23j) 366 self.assertAlmostEqual(complex(real=17+23j), 17+23j) 367 self.assertAlmostEqual(complex(real=17+23j, imag=23), 17+46j) 368 self.assertAlmostEqual(complex(real=1+2j, imag=3+4j), -3+5j) 369 370 # check that the sign of a zero in the real or imaginary part 371 # is preserved when constructing from two floats. (These checks 372 # are harmless on systems without support for signed zeros.) 373 def split_zeros(x): 374 """Function that produces different results for 0. and -0.""" 375 return atan2(x, -1.) 376 377 self.assertEqual(split_zeros(complex(1., 0.).imag), split_zeros(0.)) 378 self.assertEqual(split_zeros(complex(1., -0.).imag), split_zeros(-0.)) 379 self.assertEqual(split_zeros(complex(0., 1.).real), split_zeros(0.)) 380 self.assertEqual(split_zeros(complex(-0., 1.).real), split_zeros(-0.)) 381 382 c = 3.14 + 1j 383 self.assertTrue(complex(c) is c) 384 del c 385 386 self.assertRaises(TypeError, complex, "1", "1") 387 self.assertRaises(TypeError, complex, 1, "1") 388 389 # SF bug 543840: complex(string) accepts strings with \0 390 # Fixed in 2.3. 391 self.assertRaises(ValueError, complex, '1+1j\0j') 392 393 self.assertRaises(TypeError, int, 5+3j) 394 self.assertRaises(TypeError, int, 5+3j) 395 self.assertRaises(TypeError, float, 5+3j) 396 self.assertRaises(ValueError, complex, "") 397 self.assertRaises(TypeError, complex, None) 398 self.assertRaisesRegex(TypeError, "not 'NoneType'", complex, None) 399 self.assertRaises(ValueError, complex, "\0") 400 self.assertRaises(ValueError, complex, "3\09") 401 self.assertRaises(TypeError, complex, "1", "2") 402 self.assertRaises(TypeError, complex, "1", 42) 403 self.assertRaises(TypeError, complex, 1, "2") 404 self.assertRaises(ValueError, complex, "1+") 405 self.assertRaises(ValueError, complex, "1+1j+1j") 406 self.assertRaises(ValueError, complex, "--") 407 self.assertRaises(ValueError, complex, "(1+2j") 408 self.assertRaises(ValueError, complex, "1+2j)") 409 self.assertRaises(ValueError, complex, "1+(2j)") 410 self.assertRaises(ValueError, complex, "(1+2j)123") 411 self.assertRaises(ValueError, complex, "x") 412 self.assertRaises(ValueError, complex, "1j+2") 413 self.assertRaises(ValueError, complex, "1e1ej") 414 self.assertRaises(ValueError, complex, "1e++1ej") 415 self.assertRaises(ValueError, complex, ")1+2j(") 416 self.assertRaisesRegex( 417 TypeError, 418 "first argument must be a string or a number, not 'dict'", 419 complex, {1:2}, 1) 420 self.assertRaisesRegex( 421 TypeError, 422 "second argument must be a number, not 'dict'", 423 complex, 1, {1:2}) 424 # the following three are accepted by Python 2.6 425 self.assertRaises(ValueError, complex, "1..1j") 426 self.assertRaises(ValueError, complex, "1.11.1j") 427 self.assertRaises(ValueError, complex, "1e1.1j") 428 429 # check that complex accepts long unicode strings 430 self.assertEqual(type(complex("1"*500)), complex) 431 # check whitespace processing 432 self.assertEqual(complex('\N{EM SPACE}(\N{EN SPACE}1+1j ) '), 1+1j) 433 # Invalid unicode string 434 # See bpo-34087 435 self.assertRaises(ValueError, complex, '\u3053\u3093\u306b\u3061\u306f') 436 437 class EvilExc(Exception): 438 pass 439 440 class evilcomplex: 441 def __complex__(self): 442 raise EvilExc 443 444 self.assertRaises(EvilExc, complex, evilcomplex()) 445 446 class float2: 447 def __init__(self, value): 448 self.value = value 449 def __float__(self): 450 return self.value 451 452 self.assertAlmostEqual(complex(float2(42.)), 42) 453 self.assertAlmostEqual(complex(real=float2(17.), imag=float2(23.)), 17+23j) 454 self.assertRaises(TypeError, complex, float2(None)) 455 456 class MyIndex: 457 def __init__(self, value): 458 self.value = value 459 def __index__(self): 460 return self.value 461 462 self.assertAlmostEqual(complex(MyIndex(42)), 42.0+0.0j) 463 self.assertAlmostEqual(complex(123, MyIndex(42)), 123.0+42.0j) 464 self.assertRaises(OverflowError, complex, MyIndex(2**2000)) 465 self.assertRaises(OverflowError, complex, 123, MyIndex(2**2000)) 466 467 class MyInt: 468 def __int__(self): 469 return 42 470 471 self.assertRaises(TypeError, complex, MyInt()) 472 self.assertRaises(TypeError, complex, 123, MyInt()) 473 474 class complex0(complex): 475 """Test usage of __complex__() when inheriting from 'complex'""" 476 def __complex__(self): 477 return 42j 478 479 class complex1(complex): 480 """Test usage of __complex__() with a __new__() method""" 481 def __new__(self, value=0j): 482 return complex.__new__(self, 2*value) 483 def __complex__(self): 484 return self 485 486 class complex2(complex): 487 """Make sure that __complex__() calls fail if anything other than a 488 complex is returned""" 489 def __complex__(self): 490 return None 491 492 self.assertEqual(complex(complex0(1j)), 42j) 493 with self.assertWarns(DeprecationWarning): 494 self.assertEqual(complex(complex1(1j)), 2j) 495 self.assertRaises(TypeError, complex, complex2(1j)) 496 497 def test___complex__(self): 498 z = 3 + 4j 499 self.assertEqual(z.__complex__(), z) 500 self.assertEqual(type(z.__complex__()), complex) 501 502 class complex_subclass(complex): 503 pass 504 505 z = complex_subclass(3 + 4j) 506 self.assertEqual(z.__complex__(), 3 + 4j) 507 self.assertEqual(type(z.__complex__()), complex) 508 509 @support.requires_IEEE_754 510 def test_constructor_special_numbers(self): 511 class complex2(complex): 512 pass 513 for x in 0.0, -0.0, INF, -INF, NAN: 514 for y in 0.0, -0.0, INF, -INF, NAN: 515 with self.subTest(x=x, y=y): 516 z = complex(x, y) 517 self.assertFloatsAreIdentical(z.real, x) 518 self.assertFloatsAreIdentical(z.imag, y) 519 z = complex2(x, y) 520 self.assertIs(type(z), complex2) 521 self.assertFloatsAreIdentical(z.real, x) 522 self.assertFloatsAreIdentical(z.imag, y) 523 z = complex(complex2(x, y)) 524 self.assertIs(type(z), complex) 525 self.assertFloatsAreIdentical(z.real, x) 526 self.assertFloatsAreIdentical(z.imag, y) 527 z = complex2(complex(x, y)) 528 self.assertIs(type(z), complex2) 529 self.assertFloatsAreIdentical(z.real, x) 530 self.assertFloatsAreIdentical(z.imag, y) 531 532 def test_underscores(self): 533 # check underscores 534 for lit in VALID_UNDERSCORE_LITERALS: 535 if not any(ch in lit for ch in 'xXoObB'): 536 self.assertEqual(complex(lit), eval(lit)) 537 self.assertEqual(complex(lit), complex(lit.replace('_', ''))) 538 for lit in INVALID_UNDERSCORE_LITERALS: 539 if lit in ('0_7', '09_99'): # octals are not recognized here 540 continue 541 if not any(ch in lit for ch in 'xXoObB'): 542 self.assertRaises(ValueError, complex, lit) 543 544 def test_hash(self): 545 for x in range(-30, 30): 546 self.assertEqual(hash(x), hash(complex(x, 0))) 547 x /= 3.0 # now check against floating point 548 self.assertEqual(hash(x), hash(complex(x, 0.))) 549 550 def test_abs(self): 551 nums = [complex(x/3., y/7.) for x in range(-9,9) for y in range(-9,9)] 552 for num in nums: 553 self.assertAlmostEqual((num.real**2 + num.imag**2) ** 0.5, abs(num)) 554 555 def test_repr_str(self): 556 def test(v, expected, test_fn=self.assertEqual): 557 test_fn(repr(v), expected) 558 test_fn(str(v), expected) 559 560 test(1+6j, '(1+6j)') 561 test(1-6j, '(1-6j)') 562 563 test(-(1+0j), '(-1+-0j)', test_fn=self.assertNotEqual) 564 565 test(complex(1., INF), "(1+infj)") 566 test(complex(1., -INF), "(1-infj)") 567 test(complex(INF, 1), "(inf+1j)") 568 test(complex(-INF, INF), "(-inf+infj)") 569 test(complex(NAN, 1), "(nan+1j)") 570 test(complex(1, NAN), "(1+nanj)") 571 test(complex(NAN, NAN), "(nan+nanj)") 572 573 test(complex(0, INF), "infj") 574 test(complex(0, -INF), "-infj") 575 test(complex(0, NAN), "nanj") 576 577 self.assertEqual(1-6j,complex(repr(1-6j))) 578 self.assertEqual(1+6j,complex(repr(1+6j))) 579 self.assertEqual(-6j,complex(repr(-6j))) 580 self.assertEqual(6j,complex(repr(6j))) 581 582 @support.requires_IEEE_754 583 def test_negative_zero_repr_str(self): 584 def test(v, expected, test_fn=self.assertEqual): 585 test_fn(repr(v), expected) 586 test_fn(str(v), expected) 587 588 test(complex(0., 1.), "1j") 589 test(complex(-0., 1.), "(-0+1j)") 590 test(complex(0., -1.), "-1j") 591 test(complex(-0., -1.), "(-0-1j)") 592 593 test(complex(0., 0.), "0j") 594 test(complex(0., -0.), "-0j") 595 test(complex(-0., 0.), "(-0+0j)") 596 test(complex(-0., -0.), "(-0-0j)") 597 598 def test_neg(self): 599 self.assertEqual(-(1+6j), -1-6j) 600 601 def test_getnewargs(self): 602 self.assertEqual((1+2j).__getnewargs__(), (1.0, 2.0)) 603 self.assertEqual((1-2j).__getnewargs__(), (1.0, -2.0)) 604 self.assertEqual((2j).__getnewargs__(), (0.0, 2.0)) 605 self.assertEqual((-0j).__getnewargs__(), (0.0, -0.0)) 606 self.assertEqual(complex(0, INF).__getnewargs__(), (0.0, INF)) 607 self.assertEqual(complex(INF, 0).__getnewargs__(), (INF, 0.0)) 608 609 @support.requires_IEEE_754 610 def test_plus_minus_0j(self): 611 # test that -0j and 0j literals are not identified 612 z1, z2 = 0j, -0j 613 self.assertEqual(atan2(z1.imag, -1.), atan2(0., -1.)) 614 self.assertEqual(atan2(z2.imag, -1.), atan2(-0., -1.)) 615 616 @support.requires_IEEE_754 617 def test_negated_imaginary_literal(self): 618 z0 = -0j 619 z1 = -7j 620 z2 = -1e1000j 621 # Note: In versions of Python < 3.2, a negated imaginary literal 622 # accidentally ended up with real part 0.0 instead of -0.0, thanks to a 623 # modification during CST -> AST translation (see issue #9011). That's 624 # fixed in Python 3.2. 625 self.assertFloatsAreIdentical(z0.real, -0.0) 626 self.assertFloatsAreIdentical(z0.imag, -0.0) 627 self.assertFloatsAreIdentical(z1.real, -0.0) 628 self.assertFloatsAreIdentical(z1.imag, -7.0) 629 self.assertFloatsAreIdentical(z2.real, -0.0) 630 self.assertFloatsAreIdentical(z2.imag, -INF) 631 632 @support.requires_IEEE_754 633 def test_overflow(self): 634 self.assertEqual(complex("1e500"), complex(INF, 0.0)) 635 self.assertEqual(complex("-1e500j"), complex(0.0, -INF)) 636 self.assertEqual(complex("-1e500+1.8e308j"), complex(-INF, INF)) 637 638 @support.requires_IEEE_754 639 def test_repr_roundtrip(self): 640 vals = [0.0, 1e-500, 1e-315, 1e-200, 0.0123, 3.1415, 1e50, INF, NAN] 641 vals += [-v for v in vals] 642 643 # complex(repr(z)) should recover z exactly, even for complex 644 # numbers involving an infinity, nan, or negative zero 645 for x in vals: 646 for y in vals: 647 z = complex(x, y) 648 roundtrip = complex(repr(z)) 649 self.assertFloatsAreIdentical(z.real, roundtrip.real) 650 self.assertFloatsAreIdentical(z.imag, roundtrip.imag) 651 652 # if we predefine some constants, then eval(repr(z)) should 653 # also work, except that it might change the sign of zeros 654 inf, nan = float('inf'), float('nan') 655 infj, nanj = complex(0.0, inf), complex(0.0, nan) 656 for x in vals: 657 for y in vals: 658 z = complex(x, y) 659 roundtrip = eval(repr(z)) 660 # adding 0.0 has no effect beside changing -0.0 to 0.0 661 self.assertFloatsAreIdentical(0.0 + z.real, 662 0.0 + roundtrip.real) 663 self.assertFloatsAreIdentical(0.0 + z.imag, 664 0.0 + roundtrip.imag) 665 666 def test_format(self): 667 # empty format string is same as str() 668 self.assertEqual(format(1+3j, ''), str(1+3j)) 669 self.assertEqual(format(1.5+3.5j, ''), str(1.5+3.5j)) 670 self.assertEqual(format(3j, ''), str(3j)) 671 self.assertEqual(format(3.2j, ''), str(3.2j)) 672 self.assertEqual(format(3+0j, ''), str(3+0j)) 673 self.assertEqual(format(3.2+0j, ''), str(3.2+0j)) 674 675 # empty presentation type should still be analogous to str, 676 # even when format string is nonempty (issue #5920). 677 self.assertEqual(format(3.2+0j, '-'), str(3.2+0j)) 678 self.assertEqual(format(3.2+0j, '<'), str(3.2+0j)) 679 z = 4/7. - 100j/7. 680 self.assertEqual(format(z, ''), str(z)) 681 self.assertEqual(format(z, '-'), str(z)) 682 self.assertEqual(format(z, '<'), str(z)) 683 self.assertEqual(format(z, '10'), str(z)) 684 z = complex(0.0, 3.0) 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, '2'), str(z)) 689 z = complex(-0.0, 2.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, '3'), str(z)) 694 695 self.assertEqual(format(1+3j, 'g'), '1+3j') 696 self.assertEqual(format(3j, 'g'), '0+3j') 697 self.assertEqual(format(1.5+3.5j, 'g'), '1.5+3.5j') 698 699 self.assertEqual(format(1.5+3.5j, '+g'), '+1.5+3.5j') 700 self.assertEqual(format(1.5-3.5j, '+g'), '+1.5-3.5j') 701 self.assertEqual(format(1.5-3.5j, '-g'), '1.5-3.5j') 702 self.assertEqual(format(1.5+3.5j, ' g'), ' 1.5+3.5j') 703 self.assertEqual(format(1.5-3.5j, ' g'), ' 1.5-3.5j') 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 707 self.assertEqual(format(-1.5-3.5e-20j, 'g'), '-1.5-3.5e-20j') 708 self.assertEqual(format(-1.5-3.5j, 'f'), '-1.500000-3.500000j') 709 self.assertEqual(format(-1.5-3.5j, 'F'), '-1.500000-3.500000j') 710 self.assertEqual(format(-1.5-3.5j, 'e'), '-1.500000e+00-3.500000e+00j') 711 self.assertEqual(format(-1.5-3.5j, '.2e'), '-1.50e+00-3.50e+00j') 712 self.assertEqual(format(-1.5-3.5j, '.2E'), '-1.50E+00-3.50E+00j') 713 self.assertEqual(format(-1.5e10-3.5e5j, '.2G'), '-1.5E+10-3.5E+05j') 714 715 self.assertEqual(format(1.5+3j, '<20g'), '1.5+3j ') 716 self.assertEqual(format(1.5+3j, '*<20g'), '1.5+3j**************') 717 self.assertEqual(format(1.5+3j, '>20g'), ' 1.5+3j') 718 self.assertEqual(format(1.5+3j, '^20g'), ' 1.5+3j ') 719 self.assertEqual(format(1.5+3j, '<20'), '(1.5+3j) ') 720 self.assertEqual(format(1.5+3j, '>20'), ' (1.5+3j)') 721 self.assertEqual(format(1.5+3j, '^20'), ' (1.5+3j) ') 722 self.assertEqual(format(1.123-3.123j, '^20.2'), ' (1.1-3.1j) ') 723 724 self.assertEqual(format(1.5+3j, '20.2f'), ' 1.50+3.00j') 725 self.assertEqual(format(1.5+3j, '>20.2f'), ' 1.50+3.00j') 726 self.assertEqual(format(1.5+3j, '<20.2f'), '1.50+3.00j ') 727 self.assertEqual(format(1.5e20+3j, '<20.2f'), '150000000000000000000.00+3.00j') 728 self.assertEqual(format(1.5e20+3j, '>40.2f'), ' 150000000000000000000.00+3.00j') 729 self.assertEqual(format(1.5e20+3j, '^40,.2f'), ' 150,000,000,000,000,000,000.00+3.00j ') 730 self.assertEqual(format(1.5e21+3j, '^40,.2f'), ' 1,500,000,000,000,000,000,000.00+3.00j ') 731 self.assertEqual(format(1.5e21+3000j, ',.2f'), '1,500,000,000,000,000,000,000.00+3,000.00j') 732 733 # Issue 7094: Alternate formatting (specified by #) 734 self.assertEqual(format(1+1j, '.0e'), '1e+00+1e+00j') 735 self.assertEqual(format(1+1j, '#.0e'), '1.e+00+1.e+00j') 736 self.assertEqual(format(1+1j, '.0f'), '1+1j') 737 self.assertEqual(format(1+1j, '#.0f'), '1.+1.j') 738 self.assertEqual(format(1.1+1.1j, 'g'), '1.1+1.1j') 739 self.assertEqual(format(1.1+1.1j, '#g'), '1.10000+1.10000j') 740 741 # Alternate doesn't make a difference for these, they format the same with or without it 742 self.assertEqual(format(1+1j, '.1e'), '1.0e+00+1.0e+00j') 743 self.assertEqual(format(1+1j, '#.1e'), '1.0e+00+1.0e+00j') 744 self.assertEqual(format(1+1j, '.1f'), '1.0+1.0j') 745 self.assertEqual(format(1+1j, '#.1f'), '1.0+1.0j') 746 747 # Misc. other alternate tests 748 self.assertEqual(format((-1.5+0.5j), '#f'), '-1.500000+0.500000j') 749 self.assertEqual(format((-1.5+0.5j), '#.0f'), '-2.+0.j') 750 self.assertEqual(format((-1.5+0.5j), '#e'), '-1.500000e+00+5.000000e-01j') 751 self.assertEqual(format((-1.5+0.5j), '#.0e'), '-2.e+00+5.e-01j') 752 self.assertEqual(format((-1.5+0.5j), '#g'), '-1.50000+0.500000j') 753 self.assertEqual(format((-1.5+0.5j), '.0g'), '-2+0.5j') 754 self.assertEqual(format((-1.5+0.5j), '#.0g'), '-2.+0.5j') 755 756 # zero padding is invalid 757 self.assertRaises(ValueError, (1.5+0.5j).__format__, '010f') 758 759 # '=' alignment is invalid 760 self.assertRaises(ValueError, (1.5+3j).__format__, '=20') 761 762 # integer presentation types are an error 763 for t in 'bcdoxX': 764 self.assertRaises(ValueError, (1.5+0.5j).__format__, t) 765 766 # make sure everything works in ''.format() 767 self.assertEqual('*{0:.3f}*'.format(3.14159+2.71828j), '*3.142+2.718j*') 768 769 # issue 3382 770 self.assertEqual(format(complex(NAN, NAN), 'f'), 'nan+nanj') 771 self.assertEqual(format(complex(1, NAN), 'f'), '1.000000+nanj') 772 self.assertEqual(format(complex(NAN, 1), 'f'), 'nan+1.000000j') 773 self.assertEqual(format(complex(NAN, -1), 'f'), 'nan-1.000000j') 774 self.assertEqual(format(complex(NAN, NAN), 'F'), 'NAN+NANj') 775 self.assertEqual(format(complex(1, NAN), 'F'), '1.000000+NANj') 776 self.assertEqual(format(complex(NAN, 1), 'F'), 'NAN+1.000000j') 777 self.assertEqual(format(complex(NAN, -1), 'F'), 'NAN-1.000000j') 778 self.assertEqual(format(complex(INF, INF), 'f'), 'inf+infj') 779 self.assertEqual(format(complex(1, INF), 'f'), '1.000000+infj') 780 self.assertEqual(format(complex(INF, 1), 'f'), 'inf+1.000000j') 781 self.assertEqual(format(complex(INF, -1), 'f'), 'inf-1.000000j') 782 self.assertEqual(format(complex(INF, INF), 'F'), 'INF+INFj') 783 self.assertEqual(format(complex(1, INF), 'F'), '1.000000+INFj') 784 self.assertEqual(format(complex(INF, 1), 'F'), 'INF+1.000000j') 785 self.assertEqual(format(complex(INF, -1), 'F'), 'INF-1.000000j') 786 787 788if __name__ == "__main__": 789 unittest.main() 790