blob: af39ee878dc913df11a572d60b3455215d25ec94 [file] [log] [blame]
Florent Xicluna41fe6152010-04-02 18:52:12 +00001import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002from test import support
Brett Cannona721aba2016-09-09 14:57:09 -07003from test.test_grammar import (VALID_UNDERSCORE_LITERALS,
4 INVALID_UNDERSCORE_LITERALS)
Walter Dörwald5edd7852003-06-18 14:26:18 +00005
Tim Peters0f336042001-03-18 08:21:57 +00006from random import random
Mark Dickinsonad476da2009-04-23 19:14:16 +00007from math import atan2, isnan, copysign
Mark Dickinsonf673f0c2010-03-13 09:48:39 +00008import operator
Tim Peters0f336042001-03-18 08:21:57 +00009
Christian Heimesa156e092008-02-16 07:38:31 +000010INF = float("inf")
11NAN = float("nan")
Walter Dörwald5edd7852003-06-18 14:26:18 +000012# These tests ensure that complex math does the right thing
Fred Drake68773e72001-12-13 19:57:53 +000013
Serhiy Storchakae2ec0b22020-10-09 14:14:37 +030014ZERO_DIVISION = (
15 (1+1j, 0+0j),
16 (1+1j, 0.0),
17 (1+1j, 0),
18 (1.0, 0+0j),
19 (1, 0+0j),
20)
21
Walter Dörwald5edd7852003-06-18 14:26:18 +000022class ComplexTest(unittest.TestCase):
Tim Peters0f336042001-03-18 08:21:57 +000023
Walter Dörwald5edd7852003-06-18 14:26:18 +000024 def assertAlmostEqual(self, a, b):
25 if isinstance(a, complex):
26 if isinstance(b, complex):
27 unittest.TestCase.assertAlmostEqual(self, a.real, b.real)
28 unittest.TestCase.assertAlmostEqual(self, a.imag, b.imag)
29 else:
30 unittest.TestCase.assertAlmostEqual(self, a.real, b)
31 unittest.TestCase.assertAlmostEqual(self, a.imag, 0.)
32 else:
33 if isinstance(b, complex):
34 unittest.TestCase.assertAlmostEqual(self, a, b.real)
35 unittest.TestCase.assertAlmostEqual(self, 0., b.imag)
36 else:
37 unittest.TestCase.assertAlmostEqual(self, a, b)
Tim Peters0f336042001-03-18 08:21:57 +000038
Walter Dörwald5edd7852003-06-18 14:26:18 +000039 def assertCloseAbs(self, x, y, eps=1e-9):
Antoine Pitrou9086f922014-10-10 23:49:32 +020040 """Return true iff floats x and y "are close"."""
Walter Dörwald5edd7852003-06-18 14:26:18 +000041 # put the one with larger magnitude second
42 if abs(x) > abs(y):
43 x, y = y, x
44 if y == 0:
45 return abs(x) < eps
46 if x == 0:
47 return abs(y) < eps
48 # check that relative difference < eps
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000049 self.assertTrue(abs((x-y)/y) < eps)
Tim Petersc5b235c2001-09-06 23:00:21 +000050
Mark Dickinsonad476da2009-04-23 19:14:16 +000051 def assertFloatsAreIdentical(self, x, y):
52 """assert that floats x and y are identical, in the sense that:
53 (1) both x and y are nans, or
54 (2) both x and y are infinities, with the same sign, or
55 (3) both x and y are zeros, with the same sign, or
56 (4) x and y are both finite and nonzero, and x == y
57
58 """
59 msg = 'floats {!r} and {!r} are not identical'
60
61 if isnan(x) or isnan(y):
62 if isnan(x) and isnan(y):
63 return
64 elif x == y:
65 if x != 0.0:
66 return
67 # both zero; check that signs match
68 elif copysign(1.0, x) == copysign(1.0, y):
69 return
70 else:
71 msg += ': zeros have different signs'
72 self.fail(msg.format(x, y))
73
Walter Dörwald5edd7852003-06-18 14:26:18 +000074 def assertClose(self, x, y, eps=1e-9):
Antoine Pitrou9086f922014-10-10 23:49:32 +020075 """Return true iff complexes x and y "are close"."""
Walter Dörwald5edd7852003-06-18 14:26:18 +000076 self.assertCloseAbs(x.real, y.real, eps)
77 self.assertCloseAbs(x.imag, y.imag, eps)
Tim Peters0f336042001-03-18 08:21:57 +000078
Walter Dörwald5edd7852003-06-18 14:26:18 +000079 def check_div(self, x, y):
80 """Compute complex z=x*y, and check that z/x==y and z/y==x."""
81 z = x * y
82 if x != 0:
83 q = z / x
84 self.assertClose(q, y)
Walter Dörwaldb27cca62003-08-05 15:34:34 +000085 q = z.__truediv__(x)
86 self.assertClose(q, y)
Walter Dörwald5edd7852003-06-18 14:26:18 +000087 if y != 0:
88 q = z / y
89 self.assertClose(q, x)
Walter Dörwaldb27cca62003-08-05 15:34:34 +000090 q = z.__truediv__(y)
91 self.assertClose(q, x)
Tim Peters0f336042001-03-18 08:21:57 +000092
Neal Norwitzbcc0db82006-03-24 08:14:36 +000093 def test_truediv(self):
Guido van Rossum805365e2007-05-07 22:24:25 +000094 simple_real = [float(i) for i in range(-5, 6)]
Walter Dörwald5edd7852003-06-18 14:26:18 +000095 simple_complex = [complex(x, y) for x in simple_real for y in simple_real]
96 for x in simple_complex:
97 for y in simple_complex:
98 self.check_div(x, y)
Tim Peters0f336042001-03-18 08:21:57 +000099
Walter Dörwald5edd7852003-06-18 14:26:18 +0000100 # A naive complex division algorithm (such as in 2.0) is very prone to
101 # nonsense errors for these (overflows and underflows).
102 self.check_div(complex(1e200, 1e200), 1+0j)
103 self.check_div(complex(1e-200, 1e-200), 1+0j)
Tim Peters0f336042001-03-18 08:21:57 +0000104
Walter Dörwald5edd7852003-06-18 14:26:18 +0000105 # Just for fun.
Guido van Rossum805365e2007-05-07 22:24:25 +0000106 for i in range(100):
Walter Dörwald5edd7852003-06-18 14:26:18 +0000107 self.check_div(complex(random(), random()),
108 complex(random(), random()))
Neal Norwitzfc37af82001-12-29 01:02:21 +0000109
Walter Dörwald5edd7852003-06-18 14:26:18 +0000110 self.assertAlmostEqual(complex.__truediv__(2+0j, 1+1j), 1-1j)
Neal Norwitz5a0f0102001-12-29 14:31:46 +0000111
Antoine Pitrou9086f922014-10-10 23:49:32 +0200112 for denom_real, denom_imag in [(0, NAN), (NAN, 0), (NAN, NAN)]:
113 z = complex(0, 0) / complex(denom_real, denom_imag)
114 self.assertTrue(isnan(z.real))
115 self.assertTrue(isnan(z.imag))
116
Serhiy Storchakae2ec0b22020-10-09 14:14:37 +0300117 def test_truediv_zero_division(self):
118 for a, b in ZERO_DIVISION:
119 with self.assertRaises(ZeroDivisionError):
120 a / b
121
Walter Dörwald5edd7852003-06-18 14:26:18 +0000122 def test_floordiv(self):
Serhiy Storchakae2ec0b22020-10-09 14:14:37 +0300123 with self.assertRaises(TypeError):
124 (1+1j) // (1+0j)
125 with self.assertRaises(TypeError):
126 (1+1j) // 1.0
127 with self.assertRaises(TypeError):
128 (1+1j) // 1
129 with self.assertRaises(TypeError):
130 1.0 // (1+0j)
131 with self.assertRaises(TypeError):
132 1 // (1+0j)
133
134 def test_floordiv_zero_division(self):
135 for a, b in ZERO_DIVISION:
136 with self.assertRaises(TypeError):
137 a // b
Neal Norwitzfc37af82001-12-29 01:02:21 +0000138
Walter Dörwald5edd7852003-06-18 14:26:18 +0000139 def test_richcompare(self):
Mark Dickinsoncc6a9822010-05-21 14:55:26 +0000140 self.assertIs(complex.__eq__(1+1j, 1<<10000), False)
Mark Dickinsonf673f0c2010-03-13 09:48:39 +0000141 self.assertIs(complex.__lt__(1+1j, None), NotImplemented)
Walter Dörwald5edd7852003-06-18 14:26:18 +0000142 self.assertIs(complex.__eq__(1+1j, 1+1j), True)
143 self.assertIs(complex.__eq__(1+1j, 2+2j), False)
144 self.assertIs(complex.__ne__(1+1j, 1+1j), False)
145 self.assertIs(complex.__ne__(1+1j, 2+2j), True)
Mark Dickinsoncc6a9822010-05-21 14:55:26 +0000146 for i in range(1, 100):
147 f = i / 100.0
148 self.assertIs(complex.__eq__(f+0j, f), True)
149 self.assertIs(complex.__ne__(f+0j, f), False)
150 self.assertIs(complex.__eq__(complex(f, f), f), False)
151 self.assertIs(complex.__ne__(complex(f, f), f), True)
Mark Dickinsonf673f0c2010-03-13 09:48:39 +0000152 self.assertIs(complex.__lt__(1+1j, 2+2j), NotImplemented)
153 self.assertIs(complex.__le__(1+1j, 2+2j), NotImplemented)
154 self.assertIs(complex.__gt__(1+1j, 2+2j), NotImplemented)
155 self.assertIs(complex.__ge__(1+1j, 2+2j), NotImplemented)
156 self.assertRaises(TypeError, operator.lt, 1+1j, 2+2j)
157 self.assertRaises(TypeError, operator.le, 1+1j, 2+2j)
158 self.assertRaises(TypeError, operator.gt, 1+1j, 2+2j)
159 self.assertRaises(TypeError, operator.ge, 1+1j, 2+2j)
160 self.assertIs(operator.eq(1+1j, 1+1j), True)
161 self.assertIs(operator.eq(1+1j, 2+2j), False)
162 self.assertIs(operator.ne(1+1j, 1+1j), False)
163 self.assertIs(operator.ne(1+1j, 2+2j), True)
Tim Peters0f336042001-03-18 08:21:57 +0000164
Mark Dickinsoncc6a9822010-05-21 14:55:26 +0000165 def test_richcompare_boundaries(self):
166 def check(n, deltas, is_equal, imag = 0.0):
167 for delta in deltas:
168 i = n + delta
169 z = complex(i, imag)
170 self.assertIs(complex.__eq__(z, i), is_equal(delta))
171 self.assertIs(complex.__ne__(z, i), not is_equal(delta))
172 # For IEEE-754 doubles the following should hold:
173 # x in [2 ** (52 + i), 2 ** (53 + i + 1)] -> x mod 2 ** i == 0
174 # where the interval is representable, of course.
175 for i in range(1, 10):
176 pow = 52 + i
177 mult = 2 ** i
178 check(2 ** pow, range(1, 101), lambda delta: delta % mult == 0)
179 check(2 ** pow, range(1, 101), lambda delta: False, float(i))
180 check(2 ** 53, range(-100, 0), lambda delta: True)
181
Walter Dörwald5edd7852003-06-18 14:26:18 +0000182 def test_mod(self):
Guido van Rossum9648d622007-08-03 20:40:44 +0000183 # % is no longer supported on complex numbers
Serhiy Storchakae2ec0b22020-10-09 14:14:37 +0300184 with self.assertRaises(TypeError):
185 (1+1j) % (1+0j)
186 with self.assertRaises(TypeError):
187 (1+1j) % 1.0
188 with self.assertRaises(TypeError):
189 (1+1j) % 1
190 with self.assertRaises(TypeError):
191 1.0 % (1+0j)
192 with self.assertRaises(TypeError):
193 1 % (1+0j)
194
195 def test_mod_zero_division(self):
196 for a, b in ZERO_DIVISION:
197 with self.assertRaises(TypeError):
198 a % b
Walter Dörwaldf393fc62003-07-15 18:47:27 +0000199
Walter Dörwald5edd7852003-06-18 14:26:18 +0000200 def test_divmod(self):
Guido van Rossum9648d622007-08-03 20:40:44 +0000201 self.assertRaises(TypeError, divmod, 1+1j, 1+0j)
Serhiy Storchakae2ec0b22020-10-09 14:14:37 +0300202 self.assertRaises(TypeError, divmod, 1+1j, 1.0)
203 self.assertRaises(TypeError, divmod, 1+1j, 1)
204 self.assertRaises(TypeError, divmod, 1.0, 1+0j)
205 self.assertRaises(TypeError, divmod, 1, 1+0j)
206
207 def test_divmod_zero_division(self):
208 for a, b in ZERO_DIVISION:
209 self.assertRaises(TypeError, divmod, a, b)
Walter Dörwald5edd7852003-06-18 14:26:18 +0000210
211 def test_pow(self):
212 self.assertAlmostEqual(pow(1+1j, 0+0j), 1.0)
213 self.assertAlmostEqual(pow(0+0j, 2+0j), 0.0)
214 self.assertRaises(ZeroDivisionError, pow, 0+0j, 1j)
215 self.assertAlmostEqual(pow(1j, -1), 1/1j)
216 self.assertAlmostEqual(pow(1j, 200), 1)
217 self.assertRaises(ValueError, pow, 1+1j, 1+1j, 1+1j)
Serhiy Storchakae2ec0b22020-10-09 14:14:37 +0300218 self.assertRaises(OverflowError, pow, 1e200+1j, 1e200+1j)
Walter Dörwald5edd7852003-06-18 14:26:18 +0000219
Walter Dörwaldf393fc62003-07-15 18:47:27 +0000220 a = 3.33+4.43j
221 self.assertEqual(a ** 0j, 1)
222 self.assertEqual(a ** 0.+0.j, 1)
223
224 self.assertEqual(3j ** 0j, 1)
225 self.assertEqual(3j ** 0, 1)
226
227 try:
228 0j ** a
229 except ZeroDivisionError:
230 pass
231 else:
232 self.fail("should fail 0.0 to negative or complex power")
233
234 try:
235 0j ** (3-2j)
236 except ZeroDivisionError:
237 pass
238 else:
239 self.fail("should fail 0.0 to negative or complex power")
240
241 # The following is used to exercise certain code paths
242 self.assertEqual(a ** 105, a ** 105)
243 self.assertEqual(a ** -105, a ** -105)
244 self.assertEqual(a ** -30, a ** -30)
245
246 self.assertEqual(0.0j ** 0, 1)
247
248 b = 5.1+2.3j
249 self.assertRaises(ValueError, pow, a, b, 0)
250
Walter Dörwald5edd7852003-06-18 14:26:18 +0000251 def test_boolcontext(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000252 for i in range(100):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000253 self.assertTrue(complex(random() + 1e-6, random() + 1e-6))
254 self.assertTrue(not complex(0.0, 0.0))
Walter Dörwald5edd7852003-06-18 14:26:18 +0000255
256 def test_conjugate(self):
257 self.assertClose(complex(5.3, 9.8).conjugate(), 5.3-9.8j)
258
259 def test_constructor(self):
260 class OS:
261 def __init__(self, value): self.value = value
262 def __complex__(self): return self.value
263 class NS(object):
264 def __init__(self, value): self.value = value
265 def __complex__(self): return self.value
266 self.assertEqual(complex(OS(1+10j)), 1+10j)
267 self.assertEqual(complex(NS(1+10j)), 1+10j)
268 self.assertRaises(TypeError, complex, OS(None))
269 self.assertRaises(TypeError, complex, NS(None))
Alexander Belopolsky942af5a2010-12-04 03:38:46 +0000270 self.assertRaises(TypeError, complex, {})
Mark Dickinsond20fb822012-11-14 17:08:31 +0000271 self.assertRaises(TypeError, complex, NS(1.5))
272 self.assertRaises(TypeError, complex, NS(1))
Walter Dörwald5edd7852003-06-18 14:26:18 +0000273
274 self.assertAlmostEqual(complex("1+10j"), 1+10j)
275 self.assertAlmostEqual(complex(10), 10+0j)
276 self.assertAlmostEqual(complex(10.0), 10+0j)
Guido van Rossume2a383d2007-01-15 16:59:06 +0000277 self.assertAlmostEqual(complex(10), 10+0j)
Walter Dörwald5edd7852003-06-18 14:26:18 +0000278 self.assertAlmostEqual(complex(10+0j), 10+0j)
279 self.assertAlmostEqual(complex(1,10), 1+10j)
Guido van Rossume2a383d2007-01-15 16:59:06 +0000280 self.assertAlmostEqual(complex(1,10), 1+10j)
Walter Dörwald5edd7852003-06-18 14:26:18 +0000281 self.assertAlmostEqual(complex(1,10.0), 1+10j)
Guido van Rossume2a383d2007-01-15 16:59:06 +0000282 self.assertAlmostEqual(complex(1,10), 1+10j)
283 self.assertAlmostEqual(complex(1,10), 1+10j)
284 self.assertAlmostEqual(complex(1,10.0), 1+10j)
Walter Dörwald5edd7852003-06-18 14:26:18 +0000285 self.assertAlmostEqual(complex(1.0,10), 1+10j)
Guido van Rossume2a383d2007-01-15 16:59:06 +0000286 self.assertAlmostEqual(complex(1.0,10), 1+10j)
Walter Dörwald5edd7852003-06-18 14:26:18 +0000287 self.assertAlmostEqual(complex(1.0,10.0), 1+10j)
288 self.assertAlmostEqual(complex(3.14+0j), 3.14+0j)
289 self.assertAlmostEqual(complex(3.14), 3.14+0j)
290 self.assertAlmostEqual(complex(314), 314.0+0j)
Guido van Rossume2a383d2007-01-15 16:59:06 +0000291 self.assertAlmostEqual(complex(314), 314.0+0j)
Walter Dörwald5edd7852003-06-18 14:26:18 +0000292 self.assertAlmostEqual(complex(3.14+0j, 0j), 3.14+0j)
293 self.assertAlmostEqual(complex(3.14, 0.0), 3.14+0j)
294 self.assertAlmostEqual(complex(314, 0), 314.0+0j)
Guido van Rossume2a383d2007-01-15 16:59:06 +0000295 self.assertAlmostEqual(complex(314, 0), 314.0+0j)
Walter Dörwald5edd7852003-06-18 14:26:18 +0000296 self.assertAlmostEqual(complex(0j, 3.14j), -3.14+0j)
297 self.assertAlmostEqual(complex(0.0, 3.14j), -3.14+0j)
298 self.assertAlmostEqual(complex(0j, 3.14), 3.14j)
299 self.assertAlmostEqual(complex(0.0, 3.14), 3.14j)
300 self.assertAlmostEqual(complex("1"), 1+0j)
301 self.assertAlmostEqual(complex("1j"), 1j)
302 self.assertAlmostEqual(complex(), 0)
303 self.assertAlmostEqual(complex("-1"), -1)
304 self.assertAlmostEqual(complex("+1"), +1)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000305 self.assertAlmostEqual(complex("(1+2j)"), 1+2j)
306 self.assertAlmostEqual(complex("(1.3+2.2j)"), 1.3+2.2j)
Mark Dickinsonad476da2009-04-23 19:14:16 +0000307 self.assertAlmostEqual(complex("3.14+1J"), 3.14+1j)
308 self.assertAlmostEqual(complex(" ( +3.14-6J )"), 3.14-6j)
Mark Dickinson6649fa42009-04-24 13:25:20 +0000309 self.assertAlmostEqual(complex(" ( +3.14-J )"), 3.14-1j)
310 self.assertAlmostEqual(complex(" ( +3.14+j )"), 3.14+1j)
311 self.assertAlmostEqual(complex("J"), 1j)
312 self.assertAlmostEqual(complex("( j )"), 1j)
313 self.assertAlmostEqual(complex("+J"), 1j)
314 self.assertAlmostEqual(complex("( -j)"), -1j)
315 self.assertAlmostEqual(complex('1e-500'), 0.0 + 0.0j)
316 self.assertAlmostEqual(complex('-1e-500j'), 0.0 - 0.0j)
317 self.assertAlmostEqual(complex('-1e-500+1e-500j'), -0.0 + 0.0j)
Walter Dörwald5edd7852003-06-18 14:26:18 +0000318
319 class complex2(complex): pass
320 self.assertAlmostEqual(complex(complex2(1+1j)), 1+1j)
321 self.assertAlmostEqual(complex(real=17, imag=23), 17+23j)
322 self.assertAlmostEqual(complex(real=17+23j), 17+23j)
323 self.assertAlmostEqual(complex(real=17+23j, imag=23), 17+46j)
324 self.assertAlmostEqual(complex(real=1+2j, imag=3+4j), -3+5j)
325
Christian Heimes69a79632007-11-28 10:04:30 +0000326 # check that the sign of a zero in the real or imaginary part
327 # is preserved when constructing from two floats. (These checks
328 # are harmless on systems without support for signed zeros.)
329 def split_zeros(x):
330 """Function that produces different results for 0. and -0."""
331 return atan2(x, -1.)
332
333 self.assertEqual(split_zeros(complex(1., 0.).imag), split_zeros(0.))
334 self.assertEqual(split_zeros(complex(1., -0.).imag), split_zeros(-0.))
335 self.assertEqual(split_zeros(complex(0., 1.).real), split_zeros(0.))
336 self.assertEqual(split_zeros(complex(-0., 1.).real), split_zeros(-0.))
337
Walter Dörwald5edd7852003-06-18 14:26:18 +0000338 c = 3.14 + 1j
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000339 self.assertTrue(complex(c) is c)
Walter Dörwald5edd7852003-06-18 14:26:18 +0000340 del c
341
342 self.assertRaises(TypeError, complex, "1", "1")
343 self.assertRaises(TypeError, complex, 1, "1")
344
Walter Dörwald5edd7852003-06-18 14:26:18 +0000345 # SF bug 543840: complex(string) accepts strings with \0
346 # Fixed in 2.3.
347 self.assertRaises(ValueError, complex, '1+1j\0j')
348
349 self.assertRaises(TypeError, int, 5+3j)
Guido van Rossume2a383d2007-01-15 16:59:06 +0000350 self.assertRaises(TypeError, int, 5+3j)
Walter Dörwald5edd7852003-06-18 14:26:18 +0000351 self.assertRaises(TypeError, float, 5+3j)
352 self.assertRaises(ValueError, complex, "")
353 self.assertRaises(TypeError, complex, None)
Ezio Melottia5b95992013-11-07 19:18:34 +0200354 self.assertRaisesRegex(TypeError, "not 'NoneType'", complex, None)
Walter Dörwald5edd7852003-06-18 14:26:18 +0000355 self.assertRaises(ValueError, complex, "\0")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000356 self.assertRaises(ValueError, complex, "3\09")
Walter Dörwald5edd7852003-06-18 14:26:18 +0000357 self.assertRaises(TypeError, complex, "1", "2")
358 self.assertRaises(TypeError, complex, "1", 42)
359 self.assertRaises(TypeError, complex, 1, "2")
360 self.assertRaises(ValueError, complex, "1+")
361 self.assertRaises(ValueError, complex, "1+1j+1j")
362 self.assertRaises(ValueError, complex, "--")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000363 self.assertRaises(ValueError, complex, "(1+2j")
364 self.assertRaises(ValueError, complex, "1+2j)")
365 self.assertRaises(ValueError, complex, "1+(2j)")
366 self.assertRaises(ValueError, complex, "(1+2j)123")
Walter Dörwald1f5947b2007-05-22 16:52:54 +0000367 self.assertRaises(ValueError, complex, "x")
Mark Dickinsonad476da2009-04-23 19:14:16 +0000368 self.assertRaises(ValueError, complex, "1j+2")
369 self.assertRaises(ValueError, complex, "1e1ej")
370 self.assertRaises(ValueError, complex, "1e++1ej")
371 self.assertRaises(ValueError, complex, ")1+2j(")
Mark Dickinson613f8e52016-09-24 15:26:36 +0100372 self.assertRaisesRegex(
373 TypeError,
374 "first argument must be a string or a number, not 'dict'",
375 complex, {1:2}, 1)
376 self.assertRaisesRegex(
377 TypeError,
378 "second argument must be a number, not 'dict'",
379 complex, 1, {1:2})
Mark Dickinson6649fa42009-04-24 13:25:20 +0000380 # the following three are accepted by Python 2.6
381 self.assertRaises(ValueError, complex, "1..1j")
382 self.assertRaises(ValueError, complex, "1.11.1j")
383 self.assertRaises(ValueError, complex, "1e1.1j")
Walter Dörwald5edd7852003-06-18 14:26:18 +0000384
Mark Dickinsonf9724882009-10-26 21:51:18 +0000385 # check that complex accepts long unicode strings
386 self.assertEqual(type(complex("1"*500)), complex)
Alexander Belopolsky942af5a2010-12-04 03:38:46 +0000387 # check whitespace processing
388 self.assertEqual(complex('\N{EM SPACE}(\N{EN SPACE}1+1j ) '), 1+1j)
INADA Naoki16dfca42018-07-14 12:06:43 +0900389 # Invalid unicode string
390 # See bpo-34087
391 self.assertRaises(ValueError, complex, '\u3053\u3093\u306b\u3061\u306f')
Mark Dickinsonf9724882009-10-26 21:51:18 +0000392
Walter Dörwald5edd7852003-06-18 14:26:18 +0000393 class EvilExc(Exception):
Tim Peters478c1052003-06-29 05:46:54 +0000394 pass
Walter Dörwald5edd7852003-06-18 14:26:18 +0000395
396 class evilcomplex:
397 def __complex__(self):
398 raise EvilExc
399
400 self.assertRaises(EvilExc, complex, evilcomplex())
401
402 class float2:
403 def __init__(self, value):
404 self.value = value
405 def __float__(self):
406 return self.value
407
408 self.assertAlmostEqual(complex(float2(42.)), 42)
409 self.assertAlmostEqual(complex(real=float2(17.), imag=float2(23.)), 17+23j)
410 self.assertRaises(TypeError, complex, float2(None))
411
Serhiy Storchakabdbad712019-06-02 00:05:48 +0300412 class MyIndex:
413 def __init__(self, value):
414 self.value = value
415 def __index__(self):
416 return self.value
417
418 self.assertAlmostEqual(complex(MyIndex(42)), 42.0+0.0j)
419 self.assertAlmostEqual(complex(123, MyIndex(42)), 123.0+42.0j)
420 self.assertRaises(OverflowError, complex, MyIndex(2**2000))
421 self.assertRaises(OverflowError, complex, 123, MyIndex(2**2000))
422
423 class MyInt:
424 def __int__(self):
425 return 42
426
427 self.assertRaises(TypeError, complex, MyInt())
428 self.assertRaises(TypeError, complex, 123, MyInt())
429
Brett Cannonc3647ac2005-04-26 03:45:26 +0000430 class complex0(complex):
431 """Test usage of __complex__() when inheriting from 'complex'"""
432 def __complex__(self):
433 return 42j
434
435 class complex1(complex):
436 """Test usage of __complex__() with a __new__() method"""
437 def __new__(self, value=0j):
438 return complex.__new__(self, 2*value)
439 def __complex__(self):
440 return self
441
442 class complex2(complex):
443 """Make sure that __complex__() calls fail if anything other than a
444 complex is returned"""
445 def __complex__(self):
446 return None
447
Serhiy Storchaka671079e2017-03-24 21:28:43 +0200448 self.assertEqual(complex(complex0(1j)), 42j)
449 with self.assertWarns(DeprecationWarning):
450 self.assertEqual(complex(complex1(1j)), 2j)
Brett Cannonc3647ac2005-04-26 03:45:26 +0000451 self.assertRaises(TypeError, complex, complex2(1j))
452
Mark Dickinson112ec382017-02-20 20:28:15 +0000453 @support.requires_IEEE_754
454 def test_constructor_special_numbers(self):
455 class complex2(complex):
456 pass
457 for x in 0.0, -0.0, INF, -INF, NAN:
458 for y in 0.0, -0.0, INF, -INF, NAN:
459 with self.subTest(x=x, y=y):
460 z = complex(x, y)
461 self.assertFloatsAreIdentical(z.real, x)
462 self.assertFloatsAreIdentical(z.imag, y)
463 z = complex2(x, y)
464 self.assertIs(type(z), complex2)
465 self.assertFloatsAreIdentical(z.real, x)
466 self.assertFloatsAreIdentical(z.imag, y)
467 z = complex(complex2(x, y))
468 self.assertIs(type(z), complex)
469 self.assertFloatsAreIdentical(z.real, x)
470 self.assertFloatsAreIdentical(z.imag, y)
471 z = complex2(complex(x, y))
472 self.assertIs(type(z), complex2)
473 self.assertFloatsAreIdentical(z.real, x)
474 self.assertFloatsAreIdentical(z.imag, y)
475
Brett Cannona721aba2016-09-09 14:57:09 -0700476 def test_underscores(self):
477 # check underscores
478 for lit in VALID_UNDERSCORE_LITERALS:
479 if not any(ch in lit for ch in 'xXoObB'):
480 self.assertEqual(complex(lit), eval(lit))
481 self.assertEqual(complex(lit), complex(lit.replace('_', '')))
482 for lit in INVALID_UNDERSCORE_LITERALS:
483 if lit in ('0_7', '09_99'): # octals are not recognized here
484 continue
485 if not any(ch in lit for ch in 'xXoObB'):
486 self.assertRaises(ValueError, complex, lit)
487
Walter Dörwald5edd7852003-06-18 14:26:18 +0000488 def test_hash(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000489 for x in range(-30, 30):
Walter Dörwald5edd7852003-06-18 14:26:18 +0000490 self.assertEqual(hash(x), hash(complex(x, 0)))
491 x /= 3.0 # now check against floating point
492 self.assertEqual(hash(x), hash(complex(x, 0.)))
493
494 def test_abs(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000495 nums = [complex(x/3., y/7.) for x in range(-9,9) for y in range(-9,9)]
Walter Dörwald5edd7852003-06-18 14:26:18 +0000496 for num in nums:
497 self.assertAlmostEqual((num.real**2 + num.imag**2) ** 0.5, abs(num))
498
Eric Smith70099a12010-12-04 13:27:34 +0000499 def test_repr_str(self):
500 def test(v, expected, test_fn=self.assertEqual):
501 test_fn(repr(v), expected)
502 test_fn(str(v), expected)
Walter Dörwald5edd7852003-06-18 14:26:18 +0000503
Eric Smith70099a12010-12-04 13:27:34 +0000504 test(1+6j, '(1+6j)')
505 test(1-6j, '(1-6j)')
506
507 test(-(1+0j), '(-1+-0j)', test_fn=self.assertNotEqual)
508
509 test(complex(1., INF), "(1+infj)")
510 test(complex(1., -INF), "(1-infj)")
511 test(complex(INF, 1), "(inf+1j)")
512 test(complex(-INF, INF), "(-inf+infj)")
513 test(complex(NAN, 1), "(nan+1j)")
514 test(complex(1, NAN), "(1+nanj)")
515 test(complex(NAN, NAN), "(nan+nanj)")
516
517 test(complex(0, INF), "infj")
518 test(complex(0, -INF), "-infj")
519 test(complex(0, NAN), "nanj")
Georg Brandl9e281072005-09-17 07:51:15 +0000520
Guido van Rossumd8faa362007-04-27 19:54:29 +0000521 self.assertEqual(1-6j,complex(repr(1-6j)))
522 self.assertEqual(1+6j,complex(repr(1+6j)))
523 self.assertEqual(-6j,complex(repr(-6j)))
524 self.assertEqual(6j,complex(repr(6j)))
525
Eric Smith1ed77f32010-12-04 15:26:13 +0000526 @support.requires_IEEE_754
527 def test_negative_zero_repr_str(self):
528 def test(v, expected, test_fn=self.assertEqual):
529 test_fn(repr(v), expected)
530 test_fn(str(v), expected)
531
532 test(complex(0., 1.), "1j")
533 test(complex(-0., 1.), "(-0+1j)")
534 test(complex(0., -1.), "-1j")
535 test(complex(-0., -1.), "(-0-1j)")
536
537 test(complex(0., 0.), "0j")
538 test(complex(0., -0.), "-0j")
539 test(complex(-0., 0.), "(-0+0j)")
540 test(complex(-0., -0.), "(-0-0j)")
541
Walter Dörwald5edd7852003-06-18 14:26:18 +0000542 def test_neg(self):
543 self.assertEqual(-(1+6j), -1-6j)
544
Georg Brandl0c77a822008-06-10 16:37:50 +0000545 def test_getnewargs(self):
546 self.assertEqual((1+2j).__getnewargs__(), (1.0, 2.0))
547 self.assertEqual((1-2j).__getnewargs__(), (1.0, -2.0))
548 self.assertEqual((2j).__getnewargs__(), (0.0, 2.0))
549 self.assertEqual((-0j).__getnewargs__(), (0.0, -0.0))
550 self.assertEqual(complex(0, INF).__getnewargs__(), (0.0, INF))
551 self.assertEqual(complex(INF, 0).__getnewargs__(), (INF, 0.0))
552
Eric Smith3ab08ca2010-12-04 15:17:38 +0000553 @support.requires_IEEE_754
554 def test_plus_minus_0j(self):
555 # test that -0j and 0j literals are not identified
556 z1, z2 = 0j, -0j
557 self.assertEqual(atan2(z1.imag, -1.), atan2(0., -1.))
558 self.assertEqual(atan2(z2.imag, -1.), atan2(-0., -1.))
Christian Heimes400adb02008-02-01 08:12:03 +0000559
Eric Smith3ab08ca2010-12-04 15:17:38 +0000560 @support.requires_IEEE_754
Mark Dickinson50b79a82010-06-30 11:13:36 +0000561 def test_negated_imaginary_literal(self):
562 z0 = -0j
563 z1 = -7j
564 z2 = -1e1000j
565 # Note: In versions of Python < 3.2, a negated imaginary literal
566 # accidentally ended up with real part 0.0 instead of -0.0, thanks to a
567 # modification during CST -> AST translation (see issue #9011). That's
568 # fixed in Python 3.2.
569 self.assertFloatsAreIdentical(z0.real, -0.0)
570 self.assertFloatsAreIdentical(z0.imag, -0.0)
571 self.assertFloatsAreIdentical(z1.real, -0.0)
572 self.assertFloatsAreIdentical(z1.imag, -7.0)
573 self.assertFloatsAreIdentical(z2.real, -0.0)
574 self.assertFloatsAreIdentical(z2.imag, -INF)
575
Eric Smith3ab08ca2010-12-04 15:17:38 +0000576 @support.requires_IEEE_754
Mark Dickinson6b1e43b2009-05-20 18:41:04 +0000577 def test_overflow(self):
578 self.assertEqual(complex("1e500"), complex(INF, 0.0))
579 self.assertEqual(complex("-1e500j"), complex(0.0, -INF))
580 self.assertEqual(complex("-1e500+1.8e308j"), complex(-INF, INF))
581
Eric Smith3ab08ca2010-12-04 15:17:38 +0000582 @support.requires_IEEE_754
Mark Dickinsonad476da2009-04-23 19:14:16 +0000583 def test_repr_roundtrip(self):
Mark Dickinsonde8a7102009-04-25 10:11:40 +0000584 vals = [0.0, 1e-500, 1e-315, 1e-200, 0.0123, 3.1415, 1e50, INF, NAN]
Mark Dickinsonad476da2009-04-23 19:14:16 +0000585 vals += [-v for v in vals]
Mark Dickinsonde8a7102009-04-25 10:11:40 +0000586
587 # complex(repr(z)) should recover z exactly, even for complex
588 # numbers involving an infinity, nan, or negative zero
Mark Dickinsonad476da2009-04-23 19:14:16 +0000589 for x in vals:
590 for y in vals:
591 z = complex(x, y)
592 roundtrip = complex(repr(z))
593 self.assertFloatsAreIdentical(z.real, roundtrip.real)
594 self.assertFloatsAreIdentical(z.imag, roundtrip.imag)
595
Mark Dickinsonde8a7102009-04-25 10:11:40 +0000596 # if we predefine some constants, then eval(repr(z)) should
597 # also work, except that it might change the sign of zeros
598 inf, nan = float('inf'), float('nan')
599 infj, nanj = complex(0.0, inf), complex(0.0, nan)
600 for x in vals:
601 for y in vals:
602 z = complex(x, y)
603 roundtrip = eval(repr(z))
604 # adding 0.0 has no effect beside changing -0.0 to 0.0
605 self.assertFloatsAreIdentical(0.0 + z.real,
606 0.0 + roundtrip.real)
607 self.assertFloatsAreIdentical(0.0 + z.imag,
608 0.0 + roundtrip.imag)
609
Eric Smith58a42242009-04-30 01:00:33 +0000610 def test_format(self):
611 # empty format string is same as str()
612 self.assertEqual(format(1+3j, ''), str(1+3j))
613 self.assertEqual(format(1.5+3.5j, ''), str(1.5+3.5j))
614 self.assertEqual(format(3j, ''), str(3j))
615 self.assertEqual(format(3.2j, ''), str(3.2j))
616 self.assertEqual(format(3+0j, ''), str(3+0j))
617 self.assertEqual(format(3.2+0j, ''), str(3.2+0j))
Mark Dickinsonde8a7102009-04-25 10:11:40 +0000618
Eric Smith63376222009-05-05 14:04:18 +0000619 # empty presentation type should still be analogous to str,
620 # even when format string is nonempty (issue #5920).
621 self.assertEqual(format(3.2+0j, '-'), str(3.2+0j))
622 self.assertEqual(format(3.2+0j, '<'), str(3.2+0j))
623 z = 4/7. - 100j/7.
624 self.assertEqual(format(z, ''), str(z))
625 self.assertEqual(format(z, '-'), str(z))
626 self.assertEqual(format(z, '<'), str(z))
627 self.assertEqual(format(z, '10'), str(z))
Mark Dickinson5b65df72010-08-01 10:41:49 +0000628 z = complex(0.0, 3.0)
629 self.assertEqual(format(z, ''), str(z))
630 self.assertEqual(format(z, '-'), str(z))
631 self.assertEqual(format(z, '<'), str(z))
632 self.assertEqual(format(z, '2'), str(z))
633 z = complex(-0.0, 2.0)
634 self.assertEqual(format(z, ''), str(z))
635 self.assertEqual(format(z, '-'), str(z))
636 self.assertEqual(format(z, '<'), str(z))
637 self.assertEqual(format(z, '3'), str(z))
Eric Smith63376222009-05-05 14:04:18 +0000638
Eric Smith58a42242009-04-30 01:00:33 +0000639 self.assertEqual(format(1+3j, 'g'), '1+3j')
640 self.assertEqual(format(3j, 'g'), '0+3j')
641 self.assertEqual(format(1.5+3.5j, 'g'), '1.5+3.5j')
642
643 self.assertEqual(format(1.5+3.5j, '+g'), '+1.5+3.5j')
644 self.assertEqual(format(1.5-3.5j, '+g'), '+1.5-3.5j')
645 self.assertEqual(format(1.5-3.5j, '-g'), '1.5-3.5j')
646 self.assertEqual(format(1.5+3.5j, ' g'), ' 1.5+3.5j')
647 self.assertEqual(format(1.5-3.5j, ' g'), ' 1.5-3.5j')
648 self.assertEqual(format(-1.5+3.5j, ' g'), '-1.5+3.5j')
649 self.assertEqual(format(-1.5-3.5j, ' g'), '-1.5-3.5j')
650
651 self.assertEqual(format(-1.5-3.5e-20j, 'g'), '-1.5-3.5e-20j')
652 self.assertEqual(format(-1.5-3.5j, 'f'), '-1.500000-3.500000j')
653 self.assertEqual(format(-1.5-3.5j, 'F'), '-1.500000-3.500000j')
654 self.assertEqual(format(-1.5-3.5j, 'e'), '-1.500000e+00-3.500000e+00j')
655 self.assertEqual(format(-1.5-3.5j, '.2e'), '-1.50e+00-3.50e+00j')
656 self.assertEqual(format(-1.5-3.5j, '.2E'), '-1.50E+00-3.50E+00j')
657 self.assertEqual(format(-1.5e10-3.5e5j, '.2G'), '-1.5E+10-3.5E+05j')
658
659 self.assertEqual(format(1.5+3j, '<20g'), '1.5+3j ')
660 self.assertEqual(format(1.5+3j, '*<20g'), '1.5+3j**************')
661 self.assertEqual(format(1.5+3j, '>20g'), ' 1.5+3j')
662 self.assertEqual(format(1.5+3j, '^20g'), ' 1.5+3j ')
663 self.assertEqual(format(1.5+3j, '<20'), '(1.5+3j) ')
664 self.assertEqual(format(1.5+3j, '>20'), ' (1.5+3j)')
665 self.assertEqual(format(1.5+3j, '^20'), ' (1.5+3j) ')
666 self.assertEqual(format(1.123-3.123j, '^20.2'), ' (1.1-3.1j) ')
667
Eric Smith4e260c52010-02-22 18:54:44 +0000668 self.assertEqual(format(1.5+3j, '20.2f'), ' 1.50+3.00j')
669 self.assertEqual(format(1.5+3j, '>20.2f'), ' 1.50+3.00j')
Eric Smith58a42242009-04-30 01:00:33 +0000670 self.assertEqual(format(1.5+3j, '<20.2f'), '1.50+3.00j ')
671 self.assertEqual(format(1.5e20+3j, '<20.2f'), '150000000000000000000.00+3.00j')
672 self.assertEqual(format(1.5e20+3j, '>40.2f'), ' 150000000000000000000.00+3.00j')
673 self.assertEqual(format(1.5e20+3j, '^40,.2f'), ' 150,000,000,000,000,000,000.00+3.00j ')
674 self.assertEqual(format(1.5e21+3j, '^40,.2f'), ' 1,500,000,000,000,000,000,000.00+3.00j ')
675 self.assertEqual(format(1.5e21+3000j, ',.2f'), '1,500,000,000,000,000,000,000.00+3,000.00j')
676
Eric Smith984bb582010-11-25 16:08:06 +0000677 # Issue 7094: Alternate formatting (specified by #)
678 self.assertEqual(format(1+1j, '.0e'), '1e+00+1e+00j')
679 self.assertEqual(format(1+1j, '#.0e'), '1.e+00+1.e+00j')
680 self.assertEqual(format(1+1j, '.0f'), '1+1j')
681 self.assertEqual(format(1+1j, '#.0f'), '1.+1.j')
682 self.assertEqual(format(1.1+1.1j, 'g'), '1.1+1.1j')
683 self.assertEqual(format(1.1+1.1j, '#g'), '1.10000+1.10000j')
684
685 # Alternate doesn't make a difference for these, they format the same with or without it
686 self.assertEqual(format(1+1j, '.1e'), '1.0e+00+1.0e+00j')
687 self.assertEqual(format(1+1j, '#.1e'), '1.0e+00+1.0e+00j')
688 self.assertEqual(format(1+1j, '.1f'), '1.0+1.0j')
689 self.assertEqual(format(1+1j, '#.1f'), '1.0+1.0j')
690
691 # Misc. other alternate tests
692 self.assertEqual(format((-1.5+0.5j), '#f'), '-1.500000+0.500000j')
693 self.assertEqual(format((-1.5+0.5j), '#.0f'), '-2.+0.j')
694 self.assertEqual(format((-1.5+0.5j), '#e'), '-1.500000e+00+5.000000e-01j')
695 self.assertEqual(format((-1.5+0.5j), '#.0e'), '-2.e+00+5.e-01j')
696 self.assertEqual(format((-1.5+0.5j), '#g'), '-1.50000+0.500000j')
697 self.assertEqual(format((-1.5+0.5j), '.0g'), '-2+0.5j')
698 self.assertEqual(format((-1.5+0.5j), '#.0g'), '-2.+0.5j')
Eric Smith58a42242009-04-30 01:00:33 +0000699
700 # zero padding is invalid
701 self.assertRaises(ValueError, (1.5+0.5j).__format__, '010f')
702
703 # '=' alignment is invalid
704 self.assertRaises(ValueError, (1.5+3j).__format__, '=20')
705
706 # integer presentation types are an error
707 for t in 'bcdoxX':
708 self.assertRaises(ValueError, (1.5+0.5j).__format__, t)
709
710 # make sure everything works in ''.format()
711 self.assertEqual('*{0:.3f}*'.format(3.14159+2.71828j), '*3.142+2.718j*')
Mark Dickinsonad476da2009-04-23 19:14:16 +0000712
Eric Smith741191f2009-05-06 13:08:15 +0000713 # issue 3382
714 self.assertEqual(format(complex(NAN, NAN), 'f'), 'nan+nanj')
715 self.assertEqual(format(complex(1, NAN), 'f'), '1.000000+nanj')
716 self.assertEqual(format(complex(NAN, 1), 'f'), 'nan+1.000000j')
717 self.assertEqual(format(complex(NAN, -1), 'f'), 'nan-1.000000j')
718 self.assertEqual(format(complex(NAN, NAN), 'F'), 'NAN+NANj')
719 self.assertEqual(format(complex(1, NAN), 'F'), '1.000000+NANj')
720 self.assertEqual(format(complex(NAN, 1), 'F'), 'NAN+1.000000j')
721 self.assertEqual(format(complex(NAN, -1), 'F'), 'NAN-1.000000j')
722 self.assertEqual(format(complex(INF, INF), 'f'), 'inf+infj')
723 self.assertEqual(format(complex(1, INF), 'f'), '1.000000+infj')
724 self.assertEqual(format(complex(INF, 1), 'f'), 'inf+1.000000j')
725 self.assertEqual(format(complex(INF, -1), 'f'), 'inf-1.000000j')
726 self.assertEqual(format(complex(INF, INF), 'F'), 'INF+INFj')
727 self.assertEqual(format(complex(1, INF), 'F'), '1.000000+INFj')
728 self.assertEqual(format(complex(INF, 1), 'F'), 'INF+1.000000j')
729 self.assertEqual(format(complex(INF, -1), 'F'), 'INF-1.000000j')
730
Walter Dörwald5edd7852003-06-18 14:26:18 +0000731def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000732 support.run_unittest(ComplexTest)
Walter Dörwald5edd7852003-06-18 14:26:18 +0000733
734if __name__ == "__main__":
735 test_main()