blob: e4715587d21cf2013465c7777a1a57fde5404ea7 [file] [log] [blame]
Jeremy Hylton62e2c7e2001-02-28 17:48:06 +00001# Test various flavors of legal and illegal future statements
2
Batuhan Taşkaya44540572020-04-22 19:09:03 +03003import __future__
4import ast
Neal Norwitz328f3382003-12-13 22:43:34 +00005import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +00006from test import support
Hai Shi3ddc6342020-06-30 21:46:06 +08007from test.support import import_helper
Guido van Rossum95e4d582018-01-26 08:20:18 -08008from textwrap import dedent
Serhiy Storchaka8b583392016-12-11 14:39:01 +02009import os
Jeremy Hylton62e2c7e2001-02-28 17:48:06 +000010import re
Batuhan Taşkaya258f5172020-04-14 01:51:31 +030011import sys
Jeremy Hylton62e2c7e2001-02-28 17:48:06 +000012
R David Murray44b548d2016-09-08 13:59:53 -040013rx = re.compile(r'\((\S+).py, line (\d+)')
Jeremy Hylton62e2c7e2001-02-28 17:48:06 +000014
Neal Norwitz328f3382003-12-13 22:43:34 +000015def get_error_location(msg):
16 mo = rx.search(str(msg))
17 return mo.group(1, 2)
Jeremy Hylton62e2c7e2001-02-28 17:48:06 +000018
Neal Norwitz328f3382003-12-13 22:43:34 +000019class FutureTest(unittest.TestCase):
Jeremy Hylton62e2c7e2001-02-28 17:48:06 +000020
Ammar Askar025eb982018-09-24 17:12:49 -040021 def check_syntax_error(self, err, basename, lineno, offset=1):
Serhiy Storchaka8b583392016-12-11 14:39:01 +020022 self.assertIn('%s.py, line %d' % (basename, lineno), str(err))
23 self.assertEqual(os.path.basename(err.filename), basename + '.py')
24 self.assertEqual(err.lineno, lineno)
25 self.assertEqual(err.offset, offset)
26
Neal Norwitz328f3382003-12-13 22:43:34 +000027 def test_future1(self):
Hai Shi3ddc6342020-06-30 21:46:06 +080028 with import_helper.CleanImport('future_test1'):
Ezio Melotti1ed6be32013-02-27 10:00:03 +020029 from test import future_test1
30 self.assertEqual(future_test1.result, 6)
Jeremy Hylton62e2c7e2001-02-28 17:48:06 +000031
Neal Norwitz328f3382003-12-13 22:43:34 +000032 def test_future2(self):
Hai Shi3ddc6342020-06-30 21:46:06 +080033 with import_helper.CleanImport('future_test2'):
Ezio Melotti1ed6be32013-02-27 10:00:03 +020034 from test import future_test2
35 self.assertEqual(future_test2.result, 6)
Jeremy Hylton62e2c7e2001-02-28 17:48:06 +000036
Neal Norwitz328f3382003-12-13 22:43:34 +000037 def test_future3(self):
Hai Shi3ddc6342020-06-30 21:46:06 +080038 with import_helper.CleanImport('test_future3'):
Ezio Melotti1ed6be32013-02-27 10:00:03 +020039 from test import test_future3
Jeremy Hylton8471a352001-08-20 20:33:42 +000040
Neal Norwitz328f3382003-12-13 22:43:34 +000041 def test_badfuture3(self):
Serhiy Storchaka8b583392016-12-11 14:39:01 +020042 with self.assertRaises(SyntaxError) as cm:
Neal Norwitz328f3382003-12-13 22:43:34 +000043 from test import badsyntax_future3
Serhiy Storchaka8b583392016-12-11 14:39:01 +020044 self.check_syntax_error(cm.exception, "badsyntax_future3", 3)
Jeremy Hylton62e2c7e2001-02-28 17:48:06 +000045
Neal Norwitz328f3382003-12-13 22:43:34 +000046 def test_badfuture4(self):
Serhiy Storchaka8b583392016-12-11 14:39:01 +020047 with self.assertRaises(SyntaxError) as cm:
Neal Norwitz328f3382003-12-13 22:43:34 +000048 from test import badsyntax_future4
Serhiy Storchaka8b583392016-12-11 14:39:01 +020049 self.check_syntax_error(cm.exception, "badsyntax_future4", 3)
Jeremy Hylton62e2c7e2001-02-28 17:48:06 +000050
Neal Norwitz328f3382003-12-13 22:43:34 +000051 def test_badfuture5(self):
Serhiy Storchaka8b583392016-12-11 14:39:01 +020052 with self.assertRaises(SyntaxError) as cm:
Neal Norwitz328f3382003-12-13 22:43:34 +000053 from test import badsyntax_future5
Serhiy Storchaka8b583392016-12-11 14:39:01 +020054 self.check_syntax_error(cm.exception, "badsyntax_future5", 4)
Jeremy Hylton62e2c7e2001-02-28 17:48:06 +000055
Neal Norwitz328f3382003-12-13 22:43:34 +000056 def test_badfuture6(self):
Serhiy Storchaka8b583392016-12-11 14:39:01 +020057 with self.assertRaises(SyntaxError) as cm:
Neal Norwitz328f3382003-12-13 22:43:34 +000058 from test import badsyntax_future6
Serhiy Storchaka8b583392016-12-11 14:39:01 +020059 self.check_syntax_error(cm.exception, "badsyntax_future6", 3)
Jeremy Hylton62e2c7e2001-02-28 17:48:06 +000060
Neal Norwitz328f3382003-12-13 22:43:34 +000061 def test_badfuture7(self):
Serhiy Storchaka8b583392016-12-11 14:39:01 +020062 with self.assertRaises(SyntaxError) as cm:
Neal Norwitz328f3382003-12-13 22:43:34 +000063 from test import badsyntax_future7
Serhiy Storchaka8b583392016-12-11 14:39:01 +020064 self.check_syntax_error(cm.exception, "badsyntax_future7", 3, 53)
Neal Norwitz328f3382003-12-13 22:43:34 +000065
66 def test_badfuture8(self):
Serhiy Storchaka8b583392016-12-11 14:39:01 +020067 with self.assertRaises(SyntaxError) as cm:
Neal Norwitz328f3382003-12-13 22:43:34 +000068 from test import badsyntax_future8
Serhiy Storchaka8b583392016-12-11 14:39:01 +020069 self.check_syntax_error(cm.exception, "badsyntax_future8", 3)
Neal Norwitz328f3382003-12-13 22:43:34 +000070
71 def test_badfuture9(self):
Serhiy Storchaka8b583392016-12-11 14:39:01 +020072 with self.assertRaises(SyntaxError) as cm:
Neal Norwitz328f3382003-12-13 22:43:34 +000073 from test import badsyntax_future9
Ammar Askar025eb982018-09-24 17:12:49 -040074 self.check_syntax_error(cm.exception, "badsyntax_future9", 3)
Neal Norwitz328f3382003-12-13 22:43:34 +000075
Benjamin Peterson2d6acd22013-03-16 09:15:47 -070076 def test_badfuture10(self):
Serhiy Storchaka8b583392016-12-11 14:39:01 +020077 with self.assertRaises(SyntaxError) as cm:
Benjamin Peterson2d6acd22013-03-16 09:15:47 -070078 from test import badsyntax_future10
Ammar Askar025eb982018-09-24 17:12:49 -040079 self.check_syntax_error(cm.exception, "badsyntax_future10", 3)
Benjamin Peterson2d6acd22013-03-16 09:15:47 -070080
Batuhan Taşkaya44540572020-04-22 19:09:03 +030081 def test_ensure_flags_dont_clash(self):
82 # bpo-39562: test that future flags and compiler flags doesn't clash
83
84 # obtain future flags (CO_FUTURE_***) from the __future__ module
85 flags = {
86 f"CO_FUTURE_{future.upper()}": getattr(__future__, future).compiler_flag
87 for future in __future__.all_feature_names
88 }
89 # obtain some of the exported compiler flags (PyCF_***) from the ast module
90 flags |= {
91 flag: getattr(ast, flag)
92 for flag in dir(ast) if flag.startswith("PyCF_")
93 }
94 self.assertCountEqual(set(flags.values()), flags.values())
95
Thomas Wouters89f507f2006-12-13 04:49:30 +000096 def test_parserhack(self):
97 # test that the parser.c::future_hack function works as expected
98 # Note: although this test must pass, it's not testing the original
99 # bug as of 2.6 since the with statement is not optional and
100 # the parser hack disabled. If a new keyword is introduced in
101 # 2.6, change this to refer to the new future import.
102 try:
Benjamin Peterson9aebc612008-10-26 20:58:53 +0000103 exec("from __future__ import print_function; print 0")
Thomas Wouters89f507f2006-12-13 04:49:30 +0000104 except SyntaxError:
105 pass
106 else:
107 self.fail("syntax error didn't occur")
108
109 try:
Benjamin Peterson9aebc612008-10-26 20:58:53 +0000110 exec("from __future__ import (print_function); print 0")
Thomas Wouters89f507f2006-12-13 04:49:30 +0000111 except SyntaxError:
112 pass
113 else:
114 self.fail("syntax error didn't occur")
115
Benjamin Peterson9aebc612008-10-26 20:58:53 +0000116 def test_multiple_features(self):
Hai Shi3ddc6342020-06-30 21:46:06 +0800117 with import_helper.CleanImport("test.test_future5"):
Ezio Melotti1ed6be32013-02-27 10:00:03 +0200118 from test import test_future5
Benjamin Peterson9aebc612008-10-26 20:58:53 +0000119
Benjamin Petersonf216c942008-10-31 02:28:05 +0000120 def test_unicode_literals_exec(self):
121 scope = {}
122 exec("from __future__ import unicode_literals; x = ''", {}, scope)
Ezio Melottie9615932010-01-24 19:26:24 +0000123 self.assertIsInstance(scope["x"], str)
Benjamin Petersonf216c942008-10-31 02:28:05 +0000124
Guido van Rossum95e4d582018-01-26 08:20:18 -0800125class AnnotationsFutureTestCase(unittest.TestCase):
126 template = dedent(
127 """
128 from __future__ import annotations
129 def f() -> {ann}:
130 ...
131 def g(arg: {ann}) -> None:
132 ...
Pablo Galindod112c602020-03-18 23:02:09 +0000133 async def f2() -> {ann}:
134 ...
135 async def g2(arg: {ann}) -> None:
136 ...
Guido van Rossum95e4d582018-01-26 08:20:18 -0800137 var: {ann}
138 var2: {ann} = None
139 """
140 )
141
142 def getActual(self, annotation):
143 scope = {}
144 exec(self.template.format(ann=annotation), {}, scope)
145 func_ret_ann = scope['f'].__annotations__['return']
146 func_arg_ann = scope['g'].__annotations__['arg']
Pablo Galindod112c602020-03-18 23:02:09 +0000147 async_func_ret_ann = scope['f2'].__annotations__['return']
148 async_func_arg_ann = scope['g2'].__annotations__['arg']
Guido van Rossum95e4d582018-01-26 08:20:18 -0800149 var_ann1 = scope['__annotations__']['var']
150 var_ann2 = scope['__annotations__']['var2']
151 self.assertEqual(func_ret_ann, func_arg_ann)
Pablo Galindod112c602020-03-18 23:02:09 +0000152 self.assertEqual(func_ret_ann, async_func_ret_ann)
153 self.assertEqual(func_ret_ann, async_func_arg_ann)
Guido van Rossum95e4d582018-01-26 08:20:18 -0800154 self.assertEqual(func_ret_ann, var_ann1)
155 self.assertEqual(func_ret_ann, var_ann2)
156 return func_ret_ann
157
158 def assertAnnotationEqual(
159 self, annotation, expected=None, drop_parens=False, is_tuple=False,
160 ):
161 actual = self.getActual(annotation)
162 if expected is None:
163 expected = annotation if not is_tuple else annotation[1:-1]
164 if drop_parens:
165 self.assertNotEqual(actual, expected)
166 actual = actual.replace("(", "").replace(")", "")
167
168 self.assertEqual(actual, expected)
169
170 def test_annotations(self):
171 eq = self.assertAnnotationEqual
172 eq('...')
173 eq("'some_string'")
Batuhan Taşkayaaade1cc2020-04-14 21:55:01 +0300174 eq("u'some_string'")
Guido van Rossum95e4d582018-01-26 08:20:18 -0800175 eq("b'\\xa3'")
176 eq('Name')
177 eq('None')
178 eq('True')
179 eq('False')
180 eq('1')
181 eq('1.0')
182 eq('1j')
183 eq('True or False')
184 eq('True or False or None')
185 eq('True and False')
186 eq('True and False and None')
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300187 eq('Name1 and Name2 or Name3')
188 eq('Name1 and (Name2 or Name3)')
189 eq('Name1 or Name2 and Name3')
190 eq('(Name1 or Name2) and Name3')
191 eq('Name1 and Name2 or Name3 and Name4')
192 eq('Name1 or Name2 and Name3 or Name4')
193 eq('a + b + (c + d)')
194 eq('a * b * (c * d)')
195 eq('(a ** b) ** c ** d')
Guido van Rossum95e4d582018-01-26 08:20:18 -0800196 eq('v1 << 2')
197 eq('1 >> v2')
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300198 eq('1 % finished')
199 eq('1 + v2 - v3 * 4 ^ 5 ** v6 / 7 // 8')
Guido van Rossum95e4d582018-01-26 08:20:18 -0800200 eq('not great')
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300201 eq('not not great')
Guido van Rossum95e4d582018-01-26 08:20:18 -0800202 eq('~great')
203 eq('+value')
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300204 eq('++value')
Guido van Rossum95e4d582018-01-26 08:20:18 -0800205 eq('-1')
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300206 eq('~int and not v1 ^ 123 + v2 | True')
207 eq('a + (not b)')
Serhiy Storchaka2a2940e2018-09-30 21:07:05 +0300208 eq('lambda: None')
Guido van Rossum95e4d582018-01-26 08:20:18 -0800209 eq('lambda arg: None')
210 eq('lambda a=True: a')
211 eq('lambda a, b, c=True: a')
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300212 eq("lambda a, b, c=True, *, d=1 << v2, e='str': a")
Serhiy Storchaka2a2940e2018-09-30 21:07:05 +0300213 eq("lambda a, b, c=True, *vararg, d, e='str', **kwargs: a + b")
Pablo Galindoda6129e2019-05-18 23:40:22 +0100214 eq("lambda a, /, b, c=True, *vararg, d, e='str', **kwargs: a + b")
215 eq('lambda x, /: x')
216 eq('lambda x=1, /: x')
217 eq('lambda x, /, y: x + y')
218 eq('lambda x=1, /, y=2: x + y')
219 eq('lambda x, /, y=1: x + y')
220 eq('lambda x, /, y=1, *, z=3: x + y + z')
221 eq('lambda x=1, /, y=2, *, z=3: x + y + z')
222 eq('lambda x=1, /, y=2, *, z: x + y + z')
223 eq('lambda x=1, y=2, z=3, /, w=4, *, l, l2: x + y + z + w + l + l2')
224 eq('lambda x=1, y=2, z=3, /, w=4, *, l, l2, **kwargs: x + y + z + w + l + l2')
225 eq('lambda x, /, y=1, *, z: x + y + z')
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300226 eq('lambda x: lambda y: x + y')
Guido van Rossum95e4d582018-01-26 08:20:18 -0800227 eq('1 if True else 2')
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300228 eq('str or None if int or True else str or bytes or None')
229 eq('str or None if (1 if True else 2) else str or bytes or None')
230 eq("0 if not x else 1 if x > 0 else -1")
231 eq("(1 if x > 0 else -1) if x else 0")
232 eq("{'2.7': dead, '3.7': long_live or die_hard}")
233 eq("{'2.7': dead, '3.7': long_live or die_hard, **{'3.6': verygood}}")
Guido van Rossum95e4d582018-01-26 08:20:18 -0800234 eq("{**a, **b, **c}")
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300235 eq("{'2.7', '3.6', '3.7', '3.8', '3.9', '4.0' if gilectomy else '3.10'}")
236 eq("{*a, *b, *c}")
237 eq("({'a': 'b'}, True or False, +value, 'string', b'bytes') or None")
Guido van Rossum95e4d582018-01-26 08:20:18 -0800238 eq("()")
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300239 eq("(a,)")
240 eq("(a, b)")
241 eq("(a, b, c)")
242 eq("(*a, *b, *c)")
Guido van Rossum95e4d582018-01-26 08:20:18 -0800243 eq("[]")
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300244 eq("[1, 2, 3, 4, 5, 6, 7, 8, 9, 10 or A, 11 or B, 12 or C]")
245 eq("[*a, *b, *c]")
Guido van Rossum95e4d582018-01-26 08:20:18 -0800246 eq("{i for i in (1, 2, 3)}")
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300247 eq("{i ** 2 for i in (1, 2, 3)}")
248 eq("{i ** 2 for i, _ in ((1, 'a'), (2, 'b'), (3, 'c'))}")
249 eq("{i ** 2 + j for i in (1, 2, 3) for j in (1, 2, 3)}")
Guido van Rossum95e4d582018-01-26 08:20:18 -0800250 eq("[i for i in (1, 2, 3)]")
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300251 eq("[i ** 2 for i in (1, 2, 3)]")
252 eq("[i ** 2 for i, _ in ((1, 'a'), (2, 'b'), (3, 'c'))]")
253 eq("[i ** 2 + j for i in (1, 2, 3) for j in (1, 2, 3)]")
254 eq("(i for i in (1, 2, 3))")
255 eq("(i ** 2 for i in (1, 2, 3))")
256 eq("(i ** 2 for i, _ in ((1, 'a'), (2, 'b'), (3, 'c')))")
257 eq("(i ** 2 + j for i in (1, 2, 3) for j in (1, 2, 3))")
258 eq("{i: 0 for i in (1, 2, 3)}")
Guido van Rossum95e4d582018-01-26 08:20:18 -0800259 eq("{i: j for i, j in ((1, 'a'), (2, 'b'), (3, 'c'))}")
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300260 eq("[(x, y) for x, y in (a, b)]")
261 eq("[(x,) for x, in (a,)]")
Guido van Rossum95e4d582018-01-26 08:20:18 -0800262 eq("Python3 > Python2 > COBOL")
263 eq("Life is Life")
264 eq("call()")
265 eq("call(arg)")
266 eq("call(kwarg='hey')")
267 eq("call(arg, kwarg='hey')")
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300268 eq("call(arg, *args, another, kwarg='hey')")
269 eq("call(arg, another, kwarg='hey', **kwargs, kwarg2='ho')")
Guido van Rossum95e4d582018-01-26 08:20:18 -0800270 eq("lukasz.langa.pl")
271 eq("call.me(maybe)")
272 eq("1 .real")
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300273 eq("1.0.real")
Guido van Rossum95e4d582018-01-26 08:20:18 -0800274 eq("....__class__")
275 eq("list[str]")
276 eq("dict[str, int]")
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300277 eq("set[str,]")
Guido van Rossum95e4d582018-01-26 08:20:18 -0800278 eq("tuple[str, ...]")
Batuhan Taskaya2135e102020-05-18 21:23:48 +0300279 eq("tuple[(str, *types)]")
280 eq("tuple[str, int, (str, int)]")
281 eq("tuple[(*int, str, str, (str, int))]")
Guido van Rossum95e4d582018-01-26 08:20:18 -0800282 eq("tuple[str, int, float, dict[str, int]]")
283 eq("slice[0]")
284 eq("slice[0:1]")
285 eq("slice[0:1:2]")
286 eq("slice[:]")
287 eq("slice[:-1]")
288 eq("slice[1:]")
289 eq("slice[::-1]")
Batuhan Taşkaya185903d2020-03-01 23:07:22 +0300290 eq("slice[:,]")
291 eq("slice[1:2,]")
292 eq("slice[1:2:3,]")
293 eq("slice[1:2, 1]")
294 eq("slice[1:2, 2, 3]")
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300295 eq("slice[()]")
296 eq("slice[a, b:c, d:e:f]")
297 eq("slice[(x for x in a)]")
298 eq('str or None if sys.version_info[0] > (3,) else str or bytes or None')
Guido van Rossum95e4d582018-01-26 08:20:18 -0800299 eq("f'f-string without formatted values is just a string'")
300 eq("f'{{NOT a formatted value}}'")
301 eq("f'some f-string with {a} {few():.2f} {formatted.values!r}'")
302 eq('''f"{f'{nested} inner'} outer"''')
303 eq("f'space between opening braces: { {a for a in (1, 2, 3)}}'")
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300304 eq("f'{(lambda x: x)}'")
305 eq("f'{(None if a else lambda x: x)}'")
Eric V. Smith9a4135e2019-05-08 16:28:48 -0400306 eq("f'{x}'")
307 eq("f'{x!r}'")
308 eq("f'{x!a}'")
Guido van Rossum95e4d582018-01-26 08:20:18 -0800309 eq('(yield from outside_of_generator)')
310 eq('(yield)')
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300311 eq('(yield a + b)')
312 eq('await some.complicated[0].call(with_args=True or 1 is not 1)')
313 eq('[x for x in (a if b else c)]')
314 eq('[x for x in a if (b if c else d)]')
315 eq('f(x for x in a)')
316 eq('f(1, (x for x in a))')
317 eq('f((x for x in a), 2)')
318 eq('(((a)))', 'a')
319 eq('(((a, b)))', '(a, b)')
Hakan Çelikce578832020-04-18 19:17:19 +0300320 eq("(x := 10)")
321 eq("f'{(x := 10):=10}'")
Pablo Galindod112c602020-03-18 23:02:09 +0000322 eq("1 + 2 + 3")
Thomas Wouters89f507f2006-12-13 04:49:30 +0000323
Eric V. Smithf83d1db2019-05-29 03:55:44 -0400324 def test_fstring_debug_annotations(self):
Eric V. Smith6f6ff8a2019-05-27 15:31:52 -0400325 # f-strings with '=' don't round trip very well, so set the expected
326 # result explicitely.
327 self.assertAnnotationEqual("f'{x=!r}'", expected="f'x={x!r}'")
328 self.assertAnnotationEqual("f'{x=:}'", expected="f'x={x:}'")
329 self.assertAnnotationEqual("f'{x=:.2f}'", expected="f'x={x:.2f}'")
330 self.assertAnnotationEqual("f'{x=!r}'", expected="f'x={x!r}'")
331 self.assertAnnotationEqual("f'{x=!a}'", expected="f'x={x!a}'")
332 self.assertAnnotationEqual("f'{x=!s:*^20}'", expected="f'x={x!s:*^20}'")
333
Batuhan Taşkaya258f5172020-04-14 01:51:31 +0300334 def test_infinity_numbers(self):
335 inf = "1e" + repr(sys.float_info.max_10_exp + 1)
336 infj = f"{inf}j"
337 self.assertAnnotationEqual("1e1000", expected=inf)
338 self.assertAnnotationEqual("1e1000j", expected=infj)
339 self.assertAnnotationEqual("-1e1000", expected=f"-{inf}")
340 self.assertAnnotationEqual("3+1e1000j", expected=f"3 + {infj}")
341 self.assertAnnotationEqual("(1e1000, 1e1000j)", expected=f"({inf}, {infj})")
342 self.assertAnnotationEqual("'inf'")
343 self.assertAnnotationEqual("('inf', 1e1000, 'infxxx', 1e1000j)", expected=f"('inf', {inf}, 'infxxx', {infj})")
344 self.assertAnnotationEqual("(1e1000, (1e1000j,))", expected=f"({inf}, ({infj},))")
345
346
Neal Norwitz328f3382003-12-13 22:43:34 +0000347if __name__ == "__main__":
Ezio Melotti1ed6be32013-02-27 10:00:03 +0200348 unittest.main()