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