1 import unittest
2 import sys
3 from test import support
4 from test.test_grammar import (VALID_UNDERSCORE_LITERALS,
5 INVALID_UNDERSCORE_LITERALS)
6
7 from random import random
8 from math import atan2, isnan, copysign
9 import operator
10
11 INF = float("inf")
12 NAN = float("nan")
13 # These tests ensure that complex math does the right thing
14
15 ZERO_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
23 class ESC[4;38;5;81mComplexTest(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
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 ESC[4;38;5;81mNS:
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 ESC[4;38;5;81mcomplex2(ESC[4;38;5;149mcomplex): 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 ESC[4;38;5;81mEvilExc(ESC[4;38;5;149mException):
438 pass
439
440 class ESC[4;38;5;81mevilcomplex:
441 def __complex__(self):
442 raise EvilExc
443
444 self.assertRaises(EvilExc, complex, evilcomplex())
445
446 class ESC[4;38;5;81mfloat2:
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 ESC[4;38;5;81mMyIndex:
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 ESC[4;38;5;81mMyInt:
468 def __int__(self):
469 return 42
470
471 self.assertRaises(TypeError, complex, MyInt())
472 self.assertRaises(TypeError, complex, 123, MyInt())
473
474 class ESC[4;38;5;81mcomplex0(ESC[4;38;5;149mcomplex):
475 """Test usage of __complex__() when inheriting from 'complex'"""
476 def __complex__(self):
477 return 42j
478
479 class ESC[4;38;5;81mcomplex1(ESC[4;38;5;149mcomplex):
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 ESC[4;38;5;81mcomplex2(ESC[4;38;5;149mcomplex):
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 ESC[4;38;5;81mcomplex_subclass(ESC[4;38;5;149mcomplex):
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 ESC[4;38;5;81mcomplex2(ESC[4;38;5;149mcomplex):
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
788 if __name__ == "__main__":
789 unittest.main()