blob: 8a09853d1f78f8c333adbd037e909e5fe61d6ed3 [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 ...
Batuhan Taskaya8cc3cfa2021-04-25 05:31:20 +0300137 class H:
138 var: {ann}
139 object.attr: {ann}
Guido van Rossum95e4d582018-01-26 08:20:18 -0800140 var: {ann}
141 var2: {ann} = None
Batuhan Taskaya8cc3cfa2021-04-25 05:31:20 +0300142 object.attr: {ann}
Guido van Rossum95e4d582018-01-26 08:20:18 -0800143 """
144 )
145
146 def getActual(self, annotation):
147 scope = {}
148 exec(self.template.format(ann=annotation), {}, scope)
149 func_ret_ann = scope['f'].__annotations__['return']
150 func_arg_ann = scope['g'].__annotations__['arg']
Pablo Galindod112c602020-03-18 23:02:09 +0000151 async_func_ret_ann = scope['f2'].__annotations__['return']
152 async_func_arg_ann = scope['g2'].__annotations__['arg']
Guido van Rossum95e4d582018-01-26 08:20:18 -0800153 var_ann1 = scope['__annotations__']['var']
154 var_ann2 = scope['__annotations__']['var2']
155 self.assertEqual(func_ret_ann, func_arg_ann)
Pablo Galindod112c602020-03-18 23:02:09 +0000156 self.assertEqual(func_ret_ann, async_func_ret_ann)
157 self.assertEqual(func_ret_ann, async_func_arg_ann)
Guido van Rossum95e4d582018-01-26 08:20:18 -0800158 self.assertEqual(func_ret_ann, var_ann1)
159 self.assertEqual(func_ret_ann, var_ann2)
160 return func_ret_ann
161
162 def assertAnnotationEqual(
163 self, annotation, expected=None, drop_parens=False, is_tuple=False,
164 ):
165 actual = self.getActual(annotation)
166 if expected is None:
167 expected = annotation if not is_tuple else annotation[1:-1]
168 if drop_parens:
169 self.assertNotEqual(actual, expected)
170 actual = actual.replace("(", "").replace(")", "")
171
172 self.assertEqual(actual, expected)
173
174 def test_annotations(self):
175 eq = self.assertAnnotationEqual
176 eq('...')
177 eq("'some_string'")
Batuhan Taşkayaaade1cc2020-04-14 21:55:01 +0300178 eq("u'some_string'")
Guido van Rossum95e4d582018-01-26 08:20:18 -0800179 eq("b'\\xa3'")
180 eq('Name')
181 eq('None')
182 eq('True')
183 eq('False')
184 eq('1')
185 eq('1.0')
186 eq('1j')
187 eq('True or False')
188 eq('True or False or None')
189 eq('True and False')
190 eq('True and False and None')
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300191 eq('Name1 and Name2 or Name3')
192 eq('Name1 and (Name2 or Name3)')
193 eq('Name1 or Name2 and Name3')
194 eq('(Name1 or Name2) and Name3')
195 eq('Name1 and Name2 or Name3 and Name4')
196 eq('Name1 or Name2 and Name3 or Name4')
197 eq('a + b + (c + d)')
198 eq('a * b * (c * d)')
199 eq('(a ** b) ** c ** d')
Guido van Rossum95e4d582018-01-26 08:20:18 -0800200 eq('v1 << 2')
201 eq('1 >> v2')
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300202 eq('1 % finished')
203 eq('1 + v2 - v3 * 4 ^ 5 ** v6 / 7 // 8')
Guido van Rossum95e4d582018-01-26 08:20:18 -0800204 eq('not great')
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300205 eq('not not great')
Guido van Rossum95e4d582018-01-26 08:20:18 -0800206 eq('~great')
207 eq('+value')
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300208 eq('++value')
Guido van Rossum95e4d582018-01-26 08:20:18 -0800209 eq('-1')
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300210 eq('~int and not v1 ^ 123 + v2 | True')
211 eq('a + (not b)')
Serhiy Storchaka2a2940e2018-09-30 21:07:05 +0300212 eq('lambda: None')
Guido van Rossum95e4d582018-01-26 08:20:18 -0800213 eq('lambda arg: None')
214 eq('lambda a=True: a')
215 eq('lambda a, b, c=True: a')
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300216 eq("lambda a, b, c=True, *, d=1 << v2, e='str': a")
Serhiy Storchaka2a2940e2018-09-30 21:07:05 +0300217 eq("lambda a, b, c=True, *vararg, d, e='str', **kwargs: a + b")
Pablo Galindoda6129e2019-05-18 23:40:22 +0100218 eq("lambda a, /, b, c=True, *vararg, d, e='str', **kwargs: a + b")
219 eq('lambda x, /: x')
220 eq('lambda x=1, /: x')
221 eq('lambda x, /, y: x + y')
222 eq('lambda x=1, /, y=2: x + y')
223 eq('lambda x, /, y=1: x + y')
224 eq('lambda x, /, y=1, *, z=3: x + y + z')
225 eq('lambda x=1, /, y=2, *, z=3: x + y + z')
226 eq('lambda x=1, /, y=2, *, z: x + y + z')
227 eq('lambda x=1, y=2, z=3, /, w=4, *, l, l2: x + y + z + w + l + l2')
228 eq('lambda x=1, y=2, z=3, /, w=4, *, l, l2, **kwargs: x + y + z + w + l + l2')
229 eq('lambda x, /, y=1, *, z: x + y + z')
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300230 eq('lambda x: lambda y: x + y')
Guido van Rossum95e4d582018-01-26 08:20:18 -0800231 eq('1 if True else 2')
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300232 eq('str or None if int or True else str or bytes or None')
233 eq('str or None if (1 if True else 2) else str or bytes or None')
234 eq("0 if not x else 1 if x > 0 else -1")
235 eq("(1 if x > 0 else -1) if x else 0")
236 eq("{'2.7': dead, '3.7': long_live or die_hard}")
237 eq("{'2.7': dead, '3.7': long_live or die_hard, **{'3.6': verygood}}")
Guido van Rossum95e4d582018-01-26 08:20:18 -0800238 eq("{**a, **b, **c}")
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300239 eq("{'2.7', '3.6', '3.7', '3.8', '3.9', '4.0' if gilectomy else '3.10'}")
240 eq("{*a, *b, *c}")
241 eq("({'a': 'b'}, True or False, +value, 'string', b'bytes') or None")
Guido van Rossum95e4d582018-01-26 08:20:18 -0800242 eq("()")
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300243 eq("(a,)")
244 eq("(a, b)")
245 eq("(a, b, c)")
246 eq("(*a, *b, *c)")
Guido van Rossum95e4d582018-01-26 08:20:18 -0800247 eq("[]")
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300248 eq("[1, 2, 3, 4, 5, 6, 7, 8, 9, 10 or A, 11 or B, 12 or C]")
249 eq("[*a, *b, *c]")
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)}")
Guido van Rossum95e4d582018-01-26 08:20:18 -0800254 eq("[i for i in (1, 2, 3)]")
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300255 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 for i in (1, 2, 3))")
259 eq("(i ** 2 for i in (1, 2, 3))")
260 eq("(i ** 2 for i, _ in ((1, 'a'), (2, 'b'), (3, 'c')))")
261 eq("(i ** 2 + j for i in (1, 2, 3) for j in (1, 2, 3))")
262 eq("{i: 0 for i in (1, 2, 3)}")
Guido van Rossum95e4d582018-01-26 08:20:18 -0800263 eq("{i: j for i, j in ((1, 'a'), (2, 'b'), (3, 'c'))}")
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300264 eq("[(x, y) for x, y in (a, b)]")
265 eq("[(x,) for x, in (a,)]")
Guido van Rossum95e4d582018-01-26 08:20:18 -0800266 eq("Python3 > Python2 > COBOL")
267 eq("Life is Life")
268 eq("call()")
269 eq("call(arg)")
270 eq("call(kwarg='hey')")
271 eq("call(arg, kwarg='hey')")
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300272 eq("call(arg, *args, another, kwarg='hey')")
273 eq("call(arg, another, kwarg='hey', **kwargs, kwarg2='ho')")
Guido van Rossum95e4d582018-01-26 08:20:18 -0800274 eq("lukasz.langa.pl")
275 eq("call.me(maybe)")
276 eq("1 .real")
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300277 eq("1.0.real")
Guido van Rossum95e4d582018-01-26 08:20:18 -0800278 eq("....__class__")
279 eq("list[str]")
280 eq("dict[str, int]")
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300281 eq("set[str,]")
Guido van Rossum95e4d582018-01-26 08:20:18 -0800282 eq("tuple[str, ...]")
Batuhan Taskaya2135e102020-05-18 21:23:48 +0300283 eq("tuple[(str, *types)]")
284 eq("tuple[str, int, (str, int)]")
285 eq("tuple[(*int, str, str, (str, int))]")
Guido van Rossum95e4d582018-01-26 08:20:18 -0800286 eq("tuple[str, int, float, dict[str, int]]")
287 eq("slice[0]")
288 eq("slice[0:1]")
289 eq("slice[0:1:2]")
290 eq("slice[:]")
291 eq("slice[:-1]")
292 eq("slice[1:]")
293 eq("slice[::-1]")
Batuhan Taşkaya185903d2020-03-01 23:07:22 +0300294 eq("slice[:,]")
295 eq("slice[1:2,]")
296 eq("slice[1:2:3,]")
297 eq("slice[1:2, 1]")
298 eq("slice[1:2, 2, 3]")
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300299 eq("slice[()]")
300 eq("slice[a, b:c, d:e:f]")
301 eq("slice[(x for x in a)]")
302 eq('str or None if sys.version_info[0] > (3,) else str or bytes or None')
Guido van Rossum95e4d582018-01-26 08:20:18 -0800303 eq("f'f-string without formatted values is just a string'")
304 eq("f'{{NOT a formatted value}}'")
305 eq("f'some f-string with {a} {few():.2f} {formatted.values!r}'")
306 eq('''f"{f'{nested} inner'} outer"''')
307 eq("f'space between opening braces: { {a for a in (1, 2, 3)}}'")
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300308 eq("f'{(lambda x: x)}'")
309 eq("f'{(None if a else lambda x: x)}'")
Eric V. Smith9a4135e2019-05-08 16:28:48 -0400310 eq("f'{x}'")
311 eq("f'{x!r}'")
312 eq("f'{x!a}'")
Guido van Rossum95e4d582018-01-26 08:20:18 -0800313 eq('(yield from outside_of_generator)')
314 eq('(yield)')
Serhiy Storchaka64fddc42018-05-17 06:17:48 +0300315 eq('(yield a + b)')
316 eq('await some.complicated[0].call(with_args=True or 1 is not 1)')
317 eq('[x for x in (a if b else c)]')
318 eq('[x for x in a if (b if c else d)]')
319 eq('f(x for x in a)')
320 eq('f(1, (x for x in a))')
321 eq('f((x for x in a), 2)')
322 eq('(((a)))', 'a')
323 eq('(((a, b)))', '(a, b)')
Hakan Çelikce578832020-04-18 19:17:19 +0300324 eq("(x := 10)")
325 eq("f'{(x := 10):=10}'")
Pablo Galindod112c602020-03-18 23:02:09 +0000326 eq("1 + 2 + 3")
Thomas Wouters89f507f2006-12-13 04:49:30 +0000327
Eric V. Smithf83d1db2019-05-29 03:55:44 -0400328 def test_fstring_debug_annotations(self):
Eric V. Smith6f6ff8a2019-05-27 15:31:52 -0400329 # f-strings with '=' don't round trip very well, so set the expected
330 # result explicitely.
331 self.assertAnnotationEqual("f'{x=!r}'", expected="f'x={x!r}'")
332 self.assertAnnotationEqual("f'{x=:}'", expected="f'x={x:}'")
333 self.assertAnnotationEqual("f'{x=:.2f}'", expected="f'x={x:.2f}'")
334 self.assertAnnotationEqual("f'{x=!r}'", expected="f'x={x!r}'")
335 self.assertAnnotationEqual("f'{x=!a}'", expected="f'x={x!a}'")
336 self.assertAnnotationEqual("f'{x=!s:*^20}'", expected="f'x={x!s:*^20}'")
337
Batuhan Taşkaya258f5172020-04-14 01:51:31 +0300338 def test_infinity_numbers(self):
339 inf = "1e" + repr(sys.float_info.max_10_exp + 1)
340 infj = f"{inf}j"
341 self.assertAnnotationEqual("1e1000", expected=inf)
342 self.assertAnnotationEqual("1e1000j", expected=infj)
343 self.assertAnnotationEqual("-1e1000", expected=f"-{inf}")
344 self.assertAnnotationEqual("3+1e1000j", expected=f"3 + {infj}")
345 self.assertAnnotationEqual("(1e1000, 1e1000j)", expected=f"({inf}, {infj})")
346 self.assertAnnotationEqual("'inf'")
347 self.assertAnnotationEqual("('inf', 1e1000, 'infxxx', 1e1000j)", expected=f"('inf', {inf}, 'infxxx', {infj})")
348 self.assertAnnotationEqual("(1e1000, (1e1000j,))", expected=f"({inf}, ({infj},))")
349
Batuhan Taskaya8cc3cfa2021-04-25 05:31:20 +0300350 def test_annotation_with_complex_target(self):
351 with self.assertRaises(SyntaxError):
352 exec(
353 "from __future__ import annotations\n"
354 "object.__debug__: int"
355 )
356
Batuhan Taşkaya258f5172020-04-14 01:51:31 +0300357
Neal Norwitz328f3382003-12-13 22:43:34 +0000358if __name__ == "__main__":
Ezio Melotti1ed6be32013-02-27 10:00:03 +0200359 unittest.main()