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 @support.requires_IEEE_754 503 def test_constructor_special_numbers(self): 504 class complex2(complex): 505 pass 506 for x in 0.0, -0.0, INF, -INF, NAN: 507 for y in 0.0, -0.0, INF, -INF, NAN: 508 with self.subTest(x=x, y=y): 509 z = complex(x, y) 510 self.assertFloatsAreIdentical(z.real, x) 511 self.assertFloatsAreIdentical(z.imag, y) 512 z = complex2(x, y) 513 self.assertIs(type(z), complex2) 514 self.assertFloatsAreIdentical(z.real, x) 515 self.assertFloatsAreIdentical(z.imag, y) 516 z = complex(complex2(x, y)) 517 self.assertIs(type(z), complex) 518 self.assertFloatsAreIdentical(z.real, x) 519 self.assertFloatsAreIdentical(z.imag, y) 520 z = complex2(complex(x, y)) 521 self.assertIs(type(z), complex2) 522 self.assertFloatsAreIdentical(z.real, x) 523 self.assertFloatsAreIdentical(z.imag, y) 524 525 def test_underscores(self): 526 # check underscores 527 for lit in VALID_UNDERSCORE_LITERALS: 528 if not any(ch in lit for ch in 'xXoObB'): 529 self.assertEqual(complex(lit), eval(lit)) 530 self.assertEqual(complex(lit), complex(lit.replace('_', ''))) 531 for lit in INVALID_UNDERSCORE_LITERALS: 532 if lit in ('0_7', '09_99'): # octals are not recognized here 533 continue 534 if not any(ch in lit for ch in 'xXoObB'): 535 self.assertRaises(ValueError, complex, lit) 536 537 def test_hash(self): 538 for x in range(-30, 30): 539 self.assertEqual(hash(x), hash(complex(x, 0))) 540 x /= 3.0 # now check against floating point 541 self.assertEqual(hash(x), hash(complex(x, 0.))) 542 543 def test_abs(self): 544 nums = [complex(x/3., y/7.) for x in range(-9,9) for y in range(-9,9)] 545 for num in nums: 546 self.assertAlmostEqual((num.real**2 + num.imag**2) ** 0.5, abs(num)) 547 548 def test_repr_str(self): 549 def test(v, expected, test_fn=self.assertEqual): 550 test_fn(repr(v), expected) 551 test_fn(str(v), expected) 552 553 test(1+6j, '(1+6j)') 554 test(1-6j, '(1-6j)') 555 556 test(-(1+0j), '(-1+-0j)', test_fn=self.assertNotEqual) 557 558 test(complex(1., INF), "(1+infj)") 559 test(complex(1., -INF), "(1-infj)") 560 test(complex(INF, 1), "(inf+1j)") 561 test(complex(-INF, INF), "(-inf+infj)") 562 test(complex(NAN, 1), "(nan+1j)") 563 test(complex(1, NAN), "(1+nanj)") 564 test(complex(NAN, NAN), "(nan+nanj)") 565 566 test(complex(0, INF), "infj") 567 test(complex(0, -INF), "-infj") 568 test(complex(0, NAN), "nanj") 569 570 self.assertEqual(1-6j,complex(repr(1-6j))) 571 self.assertEqual(1+6j,complex(repr(1+6j))) 572 self.assertEqual(-6j,complex(repr(-6j))) 573 self.assertEqual(6j,complex(repr(6j))) 574 575 @support.requires_IEEE_754 576 def test_negative_zero_repr_str(self): 577 def test(v, expected, test_fn=self.assertEqual): 578 test_fn(repr(v), expected) 579 test_fn(str(v), expected) 580 581 test(complex(0., 1.), "1j") 582 test(complex(-0., 1.), "(-0+1j)") 583 test(complex(0., -1.), "-1j") 584 test(complex(-0., -1.), "(-0-1j)") 585 586 test(complex(0., 0.), "0j") 587 test(complex(0., -0.), "-0j") 588 test(complex(-0., 0.), "(-0+0j)") 589 test(complex(-0., -0.), "(-0-0j)") 590 591 def test_neg(self): 592 self.assertEqual(-(1+6j), -1-6j) 593 594 def test_getnewargs(self): 595 self.assertEqual((1+2j).__getnewargs__(), (1.0, 2.0)) 596 self.assertEqual((1-2j).__getnewargs__(), (1.0, -2.0)) 597 self.assertEqual((2j).__getnewargs__(), (0.0, 2.0)) 598 self.assertEqual((-0j).__getnewargs__(), (0.0, -0.0)) 599 self.assertEqual(complex(0, INF).__getnewargs__(), (0.0, INF)) 600 self.assertEqual(complex(INF, 0).__getnewargs__(), (INF, 0.0)) 601 602 @support.requires_IEEE_754 603 def test_plus_minus_0j(self): 604 # test that -0j and 0j literals are not identified 605 z1, z2 = 0j, -0j 606 self.assertEqual(atan2(z1.imag, -1.), atan2(0., -1.)) 607 self.assertEqual(atan2(z2.imag, -1.), atan2(-0., -1.)) 608 609 @support.requires_IEEE_754 610 def test_negated_imaginary_literal(self): 611 z0 = -0j 612 z1 = -7j 613 z2 = -1e1000j 614 # Note: In versions of Python < 3.2, a negated imaginary literal 615 # accidentally ended up with real part 0.0 instead of -0.0, thanks to a 616 # modification during CST -> AST translation (see issue #9011). That's 617 # fixed in Python 3.2. 618 self.assertFloatsAreIdentical(z0.real, -0.0) 619 self.assertFloatsAreIdentical(z0.imag, -0.0) 620 self.assertFloatsAreIdentical(z1.real, -0.0) 621 self.assertFloatsAreIdentical(z1.imag, -7.0) 622 self.assertFloatsAreIdentical(z2.real, -0.0) 623 self.assertFloatsAreIdentical(z2.imag, -INF) 624 625 @support.requires_IEEE_754 626 def test_overflow(self): 627 self.assertEqual(complex("1e500"), complex(INF, 0.0)) 628 self.assertEqual(complex("-1e500j"), complex(0.0, -INF)) 629 self.assertEqual(complex("-1e500+1.8e308j"), complex(-INF, INF)) 630 631 @support.requires_IEEE_754 632 def test_repr_roundtrip(self): 633 vals = [0.0, 1e-500, 1e-315, 1e-200, 0.0123, 3.1415, 1e50, INF, NAN] 634 vals += [-v for v in vals] 635 636 # complex(repr(z)) should recover z exactly, even for complex 637 # numbers involving an infinity, nan, or negative zero 638 for x in vals: 639 for y in vals: 640 z = complex(x, y) 641 roundtrip = complex(repr(z)) 642 self.assertFloatsAreIdentical(z.real, roundtrip.real) 643 self.assertFloatsAreIdentical(z.imag, roundtrip.imag) 644 645 # if we predefine some constants, then eval(repr(z)) should 646 # also work, except that it might change the sign of zeros 647 inf, nan = float('inf'), float('nan') 648 infj, nanj = complex(0.0, inf), complex(0.0, nan) 649 for x in vals: 650 for y in vals: 651 z = complex(x, y) 652 roundtrip = eval(repr(z)) 653 # adding 0.0 has no effect beside changing -0.0 to 0.0 654 self.assertFloatsAreIdentical(0.0 + z.real, 655 0.0 + roundtrip.real) 656 self.assertFloatsAreIdentical(0.0 + z.imag, 657 0.0 + roundtrip.imag) 658 659 def test_format(self): 660 # empty format string is same as str() 661 self.assertEqual(format(1+3j, ''), str(1+3j)) 662 self.assertEqual(format(1.5+3.5j, ''), str(1.5+3.5j)) 663 self.assertEqual(format(3j, ''), str(3j)) 664 self.assertEqual(format(3.2j, ''), str(3.2j)) 665 self.assertEqual(format(3+0j, ''), str(3+0j)) 666 self.assertEqual(format(3.2+0j, ''), str(3.2+0j)) 667 668 # empty presentation type should still be analogous to str, 669 # even when format string is nonempty (issue #5920). 670 self.assertEqual(format(3.2+0j, '-'), str(3.2+0j)) 671 self.assertEqual(format(3.2+0j, '<'), str(3.2+0j)) 672 z = 4/7. - 100j/7. 673 self.assertEqual(format(z, ''), str(z)) 674 self.assertEqual(format(z, '-'), str(z)) 675 self.assertEqual(format(z, '<'), str(z)) 676 self.assertEqual(format(z, '10'), str(z)) 677 z = complex(0.0, 3.0) 678 self.assertEqual(format(z, ''), str(z)) 679 self.assertEqual(format(z, '-'), str(z)) 680 self.assertEqual(format(z, '<'), str(z)) 681 self.assertEqual(format(z, '2'), str(z)) 682 z = complex(-0.0, 2.0) 683 self.assertEqual(format(z, ''), str(z)) 684 self.assertEqual(format(z, '-'), str(z)) 685 self.assertEqual(format(z, '<'), str(z)) 686 self.assertEqual(format(z, '3'), str(z)) 687 688 self.assertEqual(format(1+3j, 'g'), '1+3j') 689 self.assertEqual(format(3j, 'g'), '0+3j') 690 self.assertEqual(format(1.5+3.5j, 'g'), '1.5+3.5j') 691 692 self.assertEqual(format(1.5+3.5j, '+g'), '+1.5+3.5j') 693 self.assertEqual(format(1.5-3.5j, '+g'), '+1.5-3.5j') 694 self.assertEqual(format(1.5-3.5j, '-g'), '1.5-3.5j') 695 self.assertEqual(format(1.5+3.5j, ' g'), ' 1.5+3.5j') 696 self.assertEqual(format(1.5-3.5j, ' g'), ' 1.5-3.5j') 697 self.assertEqual(format(-1.5+3.5j, ' g'), '-1.5+3.5j') 698 self.assertEqual(format(-1.5-3.5j, ' g'), '-1.5-3.5j') 699 700 self.assertEqual(format(-1.5-3.5e-20j, 'g'), '-1.5-3.5e-20j') 701 self.assertEqual(format(-1.5-3.5j, 'f'), '-1.500000-3.500000j') 702 self.assertEqual(format(-1.5-3.5j, 'F'), '-1.500000-3.500000j') 703 self.assertEqual(format(-1.5-3.5j, 'e'), '-1.500000e+00-3.500000e+00j') 704 self.assertEqual(format(-1.5-3.5j, '.2e'), '-1.50e+00-3.50e+00j') 705 self.assertEqual(format(-1.5-3.5j, '.2E'), '-1.50E+00-3.50E+00j') 706 self.assertEqual(format(-1.5e10-3.5e5j, '.2G'), '-1.5E+10-3.5E+05j') 707 708 self.assertEqual(format(1.5+3j, '<20g'), '1.5+3j ') 709 self.assertEqual(format(1.5+3j, '*<20g'), '1.5+3j**************') 710 self.assertEqual(format(1.5+3j, '>20g'), ' 1.5+3j') 711 self.assertEqual(format(1.5+3j, '^20g'), ' 1.5+3j ') 712 self.assertEqual(format(1.5+3j, '<20'), '(1.5+3j) ') 713 self.assertEqual(format(1.5+3j, '>20'), ' (1.5+3j)') 714 self.assertEqual(format(1.5+3j, '^20'), ' (1.5+3j) ') 715 self.assertEqual(format(1.123-3.123j, '^20.2'), ' (1.1-3.1j) ') 716 717 self.assertEqual(format(1.5+3j, '20.2f'), ' 1.50+3.00j') 718 self.assertEqual(format(1.5+3j, '>20.2f'), ' 1.50+3.00j') 719 self.assertEqual(format(1.5+3j, '<20.2f'), '1.50+3.00j ') 720 self.assertEqual(format(1.5e20+3j, '<20.2f'), '150000000000000000000.00+3.00j') 721 self.assertEqual(format(1.5e20+3j, '>40.2f'), ' 150000000000000000000.00+3.00j') 722 self.assertEqual(format(1.5e20+3j, '^40,.2f'), ' 150,000,000,000,000,000,000.00+3.00j ') 723 self.assertEqual(format(1.5e21+3j, '^40,.2f'), ' 1,500,000,000,000,000,000,000.00+3.00j ') 724 self.assertEqual(format(1.5e21+3000j, ',.2f'), '1,500,000,000,000,000,000,000.00+3,000.00j') 725 726 # Issue 7094: Alternate formatting (specified by #) 727 self.assertEqual(format(1+1j, '.0e'), '1e+00+1e+00j') 728 self.assertEqual(format(1+1j, '#.0e'), '1.e+00+1.e+00j') 729 self.assertEqual(format(1+1j, '.0f'), '1+1j') 730 self.assertEqual(format(1+1j, '#.0f'), '1.+1.j') 731 self.assertEqual(format(1.1+1.1j, 'g'), '1.1+1.1j') 732 self.assertEqual(format(1.1+1.1j, '#g'), '1.10000+1.10000j') 733 734 # Alternate doesn't make a difference for these, they format the same with or without it 735 self.assertEqual(format(1+1j, '.1e'), '1.0e+00+1.0e+00j') 736 self.assertEqual(format(1+1j, '#.1e'), '1.0e+00+1.0e+00j') 737 self.assertEqual(format(1+1j, '.1f'), '1.0+1.0j') 738 self.assertEqual(format(1+1j, '#.1f'), '1.0+1.0j') 739 740 # Misc. other alternate tests 741 self.assertEqual(format((-1.5+0.5j), '#f'), '-1.500000+0.500000j') 742 self.assertEqual(format((-1.5+0.5j), '#.0f'), '-2.+0.j') 743 self.assertEqual(format((-1.5+0.5j), '#e'), '-1.500000e+00+5.000000e-01j') 744 self.assertEqual(format((-1.5+0.5j), '#.0e'), '-2.e+00+5.e-01j') 745 self.assertEqual(format((-1.5+0.5j), '#g'), '-1.50000+0.500000j') 746 self.assertEqual(format((-1.5+0.5j), '.0g'), '-2+0.5j') 747 self.assertEqual(format((-1.5+0.5j), '#.0g'), '-2.+0.5j') 748 749 # zero padding is invalid 750 self.assertRaises(ValueError, (1.5+0.5j).__format__, '010f') 751 752 # '=' alignment is invalid 753 self.assertRaises(ValueError, (1.5+3j).__format__, '=20') 754 755 # integer presentation types are an error 756 for t in 'bcdoxX': 757 self.assertRaises(ValueError, (1.5+0.5j).__format__, t) 758 759 # make sure everything works in ''.format() 760 self.assertEqual('*{0:.3f}*'.format(3.14159+2.71828j), '*3.142+2.718j*') 761 762 # issue 3382 763 self.assertEqual(format(complex(NAN, NAN), 'f'), 'nan+nanj') 764 self.assertEqual(format(complex(1, NAN), 'f'), '1.000000+nanj') 765 self.assertEqual(format(complex(NAN, 1), 'f'), 'nan+1.000000j') 766 self.assertEqual(format(complex(NAN, -1), 'f'), 'nan-1.000000j') 767 self.assertEqual(format(complex(NAN, NAN), 'F'), 'NAN+NANj') 768 self.assertEqual(format(complex(1, NAN), 'F'), '1.000000+NANj') 769 self.assertEqual(format(complex(NAN, 1), 'F'), 'NAN+1.000000j') 770 self.assertEqual(format(complex(NAN, -1), 'F'), 'NAN-1.000000j') 771 self.assertEqual(format(complex(INF, INF), 'f'), 'inf+infj') 772 self.assertEqual(format(complex(1, INF), 'f'), '1.000000+infj') 773 self.assertEqual(format(complex(INF, 1), 'f'), 'inf+1.000000j') 774 self.assertEqual(format(complex(INF, -1), 'f'), 'inf-1.000000j') 775 self.assertEqual(format(complex(INF, INF), 'F'), 'INF+INFj') 776 self.assertEqual(format(complex(1, INF), 'F'), '1.000000+INFj') 777 self.assertEqual(format(complex(INF, 1), 'F'), 'INF+1.000000j') 778 self.assertEqual(format(complex(INF, -1), 'F'), 'INF-1.000000j') 779 780 781if __name__ == "__main__": 782 unittest.main() 783