blob: d4089a3fc1cdf8f27d17dbbec7619509eba637a5 [file] [log] [blame]
Zachary Ware2b0a6102014-07-16 14:26:09 -05001"""Tests for the unparse.py script in the Tools/parser directory."""
2
Mark Dickinsonae100052010-06-28 19:44:20 +00003import unittest
4import test.support
Pablo Galindo27fc3b62019-11-24 23:02:40 +00005import pathlib
Mark Dickinsonbe4fb692012-06-23 09:27:47 +01006import random
Mark Dickinsond751c2e2010-06-29 14:08:23 +00007import tokenize
Mark Dickinsonbe4fb692012-06-23 09:27:47 +01008import ast
Mark Dickinsonae100052010-06-28 19:44:20 +00009
Zachary Ware2b0a6102014-07-16 14:26:09 -050010
Mark Dickinsond751c2e2010-06-29 14:08:23 +000011def read_pyfile(filename):
12 """Read and return the contents of a Python source file (as a
13 string), taking into account the file encoding."""
Hakan Çelik6a5bf152020-04-16 13:11:55 +030014 with tokenize.open(filename) as stream:
15 return stream.read()
Mark Dickinsond751c2e2010-06-29 14:08:23 +000016
Pablo Galindo27fc3b62019-11-24 23:02:40 +000017
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +000018for_else = """\
Mark Dickinsonae100052010-06-28 19:44:20 +000019def f():
20 for x in range(10):
21 break
22 else:
23 y = 2
24 z = 3
25"""
26
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +000027while_else = """\
Mark Dickinsonae100052010-06-28 19:44:20 +000028def g():
29 while True:
30 break
31 else:
32 y = 2
33 z = 3
34"""
35
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +000036relative_import = """\
37from . import fred
38from .. import barney
39from .australia import shrimp as prawns
40"""
41
42nonlocal_ex = """\
43def f():
44 x = 1
45 def g():
46 nonlocal x
47 x = 2
48 y = 7
49 def h():
50 nonlocal x, y
51"""
52
53# also acts as test for 'except ... as ...'
54raise_from = """\
55try:
56 1 / 0
57except ZeroDivisionError as e:
58 raise ArithmeticError from e
59"""
60
61class_decorator = """\
62@f1(arg)
63@f2
64class Foo: pass
65"""
66
Mark Dickinson8d6d7602010-06-30 08:32:11 +000067elif1 = """\
68if cond1:
69 suite1
70elif cond2:
71 suite2
72else:
73 suite3
74"""
75
76elif2 = """\
77if cond1:
78 suite1
79elif cond2:
80 suite2
81"""
82
Mark Dickinson81ad8cc2010-06-30 08:46:53 +000083try_except_finally = """\
84try:
85 suite1
86except ex1:
87 suite2
88except ex2:
89 suite3
90else:
91 suite4
92finally:
93 suite5
94"""
Mark Dickinson8d6d7602010-06-30 08:32:11 +000095
Mark Dickinsonfe8440a2012-05-06 17:35:19 +010096with_simple = """\
97with f():
98 suite1
99"""
100
101with_as = """\
102with f() as x:
103 suite1
104"""
105
106with_two_items = """\
107with f() as x, g() as y:
108 suite1
109"""
110
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300111docstring_prefixes = [
112 "",
113 "class foo():\n ",
114 "def foo():\n ",
115 "async def foo():\n ",
116]
Pablo Galindo27fc3b62019-11-24 23:02:40 +0000117
Mark Dickinsond751c2e2010-06-29 14:08:23 +0000118class ASTTestCase(unittest.TestCase):
119 def assertASTEqual(self, ast1, ast2):
120 self.assertEqual(ast.dump(ast1), ast.dump(ast2))
Mark Dickinsonae100052010-06-28 19:44:20 +0000121
Batuhan Taşkaya5b66ec12020-03-15 22:56:57 +0300122 def check_ast_roundtrip(self, code1, **kwargs):
123 ast1 = ast.parse(code1, **kwargs)
Pablo Galindo27fc3b62019-11-24 23:02:40 +0000124 code2 = ast.unparse(ast1)
Batuhan Taşkaya5b66ec12020-03-15 22:56:57 +0300125 ast2 = ast.parse(code2, **kwargs)
Mark Dickinsond751c2e2010-06-29 14:08:23 +0000126 self.assertASTEqual(ast1, ast2)
127
Pablo Galindo27fc3b62019-11-24 23:02:40 +0000128 def check_invalid(self, node, raises=ValueError):
129 self.assertRaises(raises, ast.unparse, node)
130
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300131 def get_source(self, code1, code2=None, strip=True):
Batuhan Taşkaya397b96f2020-03-01 23:12:17 +0300132 code2 = code2 or code1
133 code1 = ast.unparse(ast.parse(code1))
134 if strip:
135 code1 = code1.strip()
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300136 return code1, code2
137
138 def check_src_roundtrip(self, code1, code2=None, strip=True):
139 code1, code2 = self.get_source(code1, code2, strip)
Batuhan Taşkaya397b96f2020-03-01 23:12:17 +0300140 self.assertEqual(code2, code1)
141
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300142 def check_src_dont_roundtrip(self, code1, code2=None, strip=True):
143 code1, code2 = self.get_source(code1, code2, strip)
144 self.assertNotEqual(code2, code1)
Pablo Galindo27fc3b62019-11-24 23:02:40 +0000145
Mark Dickinsond751c2e2010-06-29 14:08:23 +0000146class UnparseTestCase(ASTTestCase):
147 # Tests for specific bugs found in earlier versions of unparse
Mark Dickinsonae100052010-06-28 19:44:20 +0000148
Eric V. Smith608adf92015-09-20 15:09:15 -0400149 def test_fstrings(self):
150 # See issue 25180
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300151 self.check_ast_roundtrip(r"""f'{f"{0}"*3}'""")
152 self.check_ast_roundtrip(r"""f'{f"{y}"*3}'""")
Eric V. Smith608adf92015-09-20 15:09:15 -0400153
Chih-Hsuan Yenaaf47ca2019-05-27 01:08:20 +0800154 def test_strings(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300155 self.check_ast_roundtrip("u'foo'")
156 self.check_ast_roundtrip("r'foo'")
157 self.check_ast_roundtrip("b'foo'")
Chih-Hsuan Yenaaf47ca2019-05-27 01:08:20 +0800158
Mark Dickinsonae100052010-06-28 19:44:20 +0000159 def test_del_statement(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300160 self.check_ast_roundtrip("del x, y, z")
Mark Dickinsonae100052010-06-28 19:44:20 +0000161
162 def test_shifts(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300163 self.check_ast_roundtrip("45 << 2")
164 self.check_ast_roundtrip("13 >> 7")
Mark Dickinsonae100052010-06-28 19:44:20 +0000165
166 def test_for_else(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300167 self.check_ast_roundtrip(for_else)
Mark Dickinsonae100052010-06-28 19:44:20 +0000168
169 def test_while_else(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300170 self.check_ast_roundtrip(while_else)
Mark Dickinsonae100052010-06-28 19:44:20 +0000171
172 def test_unary_parens(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300173 self.check_ast_roundtrip("(-1)**7")
174 self.check_ast_roundtrip("(-1.)**8")
175 self.check_ast_roundtrip("(-1j)**6")
176 self.check_ast_roundtrip("not True or False")
177 self.check_ast_roundtrip("True or not False")
Mark Dickinsonae100052010-06-28 19:44:20 +0000178
Mark Dickinson3eb02902010-06-29 08:52:36 +0000179 def test_integer_parens(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300180 self.check_ast_roundtrip("3 .__abs__()")
Mark Dickinson3eb02902010-06-29 08:52:36 +0000181
Mark Dickinson8042e282010-06-29 10:01:48 +0000182 def test_huge_float(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300183 self.check_ast_roundtrip("1e1000")
184 self.check_ast_roundtrip("-1e1000")
185 self.check_ast_roundtrip("1e1000j")
186 self.check_ast_roundtrip("-1e1000j")
Mark Dickinsoncba8c102010-06-30 11:45:53 +0000187
188 def test_min_int(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300189 self.check_ast_roundtrip(str(-(2 ** 31)))
190 self.check_ast_roundtrip(str(-(2 ** 63)))
Mark Dickinsoncba8c102010-06-30 11:45:53 +0000191
192 def test_imaginary_literals(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300193 self.check_ast_roundtrip("7j")
194 self.check_ast_roundtrip("-7j")
195 self.check_ast_roundtrip("0j")
196 self.check_ast_roundtrip("-0j")
Mark Dickinson8042e282010-06-29 10:01:48 +0000197
198 def test_lambda_parentheses(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300199 self.check_ast_roundtrip("(lambda: int)()")
Mark Dickinson8042e282010-06-29 10:01:48 +0000200
Mark Dickinsonf5451e52010-06-28 20:09:18 +0000201 def test_chained_comparisons(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300202 self.check_ast_roundtrip("1 < 4 <= 5")
203 self.check_ast_roundtrip("a is b is c is not d")
Mark Dickinsonf5451e52010-06-28 20:09:18 +0000204
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000205 def test_function_arguments(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300206 self.check_ast_roundtrip("def f(): pass")
207 self.check_ast_roundtrip("def f(a): pass")
208 self.check_ast_roundtrip("def f(b = 2): pass")
209 self.check_ast_roundtrip("def f(a, b): pass")
210 self.check_ast_roundtrip("def f(a, b = 2): pass")
211 self.check_ast_roundtrip("def f(a = 5, b = 2): pass")
212 self.check_ast_roundtrip("def f(*, a = 1, b = 2): pass")
213 self.check_ast_roundtrip("def f(*, a = 1, b): pass")
214 self.check_ast_roundtrip("def f(*, a, b = 2): pass")
215 self.check_ast_roundtrip("def f(a, b = None, *, c, **kwds): pass")
216 self.check_ast_roundtrip("def f(a=2, *args, c=5, d, **kwds): pass")
217 self.check_ast_roundtrip("def f(*args, **kwargs): pass")
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000218
219 def test_relative_import(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300220 self.check_ast_roundtrip(relative_import)
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000221
222 def test_nonlocal(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300223 self.check_ast_roundtrip(nonlocal_ex)
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000224
225 def test_raise_from(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300226 self.check_ast_roundtrip(raise_from)
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000227
228 def test_bytes(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300229 self.check_ast_roundtrip("b'123'")
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000230
231 def test_annotations(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300232 self.check_ast_roundtrip("def f(a : int): pass")
233 self.check_ast_roundtrip("def f(a: int = 5): pass")
234 self.check_ast_roundtrip("def f(*args: [int]): pass")
235 self.check_ast_roundtrip("def f(**kwargs: dict): pass")
236 self.check_ast_roundtrip("def f() -> None: pass")
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000237
238 def test_set_literal(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300239 self.check_ast_roundtrip("{'a', 'b', 'c'}")
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000240
241 def test_set_comprehension(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300242 self.check_ast_roundtrip("{x for x in range(5)}")
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000243
244 def test_dict_comprehension(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300245 self.check_ast_roundtrip("{x: x*x for x in range(10)}")
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000246
247 def test_class_decorators(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300248 self.check_ast_roundtrip(class_decorator)
Mark Dickinsonae100052010-06-28 19:44:20 +0000249
Mark Dickinson578aa562010-06-29 18:38:59 +0000250 def test_class_definition(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300251 self.check_ast_roundtrip("class A(metaclass=type, *[], **{}): pass")
Mark Dickinsond751c2e2010-06-29 14:08:23 +0000252
Mark Dickinson8d6d7602010-06-30 08:32:11 +0000253 def test_elifs(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300254 self.check_ast_roundtrip(elif1)
255 self.check_ast_roundtrip(elif2)
Mark Dickinson8d6d7602010-06-30 08:32:11 +0000256
Mark Dickinson81ad8cc2010-06-30 08:46:53 +0000257 def test_try_except_finally(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300258 self.check_ast_roundtrip(try_except_finally)
Mark Dickinson81ad8cc2010-06-30 08:46:53 +0000259
Mark Dickinson1b2e9442012-05-06 17:27:39 +0100260 def test_starred_assignment(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300261 self.check_ast_roundtrip("a, *b, c = seq")
262 self.check_ast_roundtrip("a, (*b, c) = seq")
263 self.check_ast_roundtrip("a, *b[0], c = seq")
264 self.check_ast_roundtrip("a, *(b, c) = seq")
Mark Dickinson1b2e9442012-05-06 17:27:39 +0100265
Mark Dickinsonfe8440a2012-05-06 17:35:19 +0100266 def test_with_simple(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300267 self.check_ast_roundtrip(with_simple)
Mark Dickinsonfe8440a2012-05-06 17:35:19 +0100268
269 def test_with_as(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300270 self.check_ast_roundtrip(with_as)
Mark Dickinsonfe8440a2012-05-06 17:35:19 +0100271
272 def test_with_two_items(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300273 self.check_ast_roundtrip(with_two_items)
Mark Dickinsonfe8440a2012-05-06 17:35:19 +0100274
Berker Peksagd66dd5c2016-03-06 16:50:15 +0200275 def test_dict_unpacking_in_dict(self):
276 # See issue 26489
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300277 self.check_ast_roundtrip(r"""{**{'y': 2}, 'x': 1}""")
278 self.check_ast_roundtrip(r"""{**{'y': 2}, **{'x': 1}}""")
Berker Peksagd66dd5c2016-03-06 16:50:15 +0200279
Batuhan Taşkayae7cab7f2020-03-09 23:27:03 +0300280 def test_ext_slices(self):
281 self.check_ast_roundtrip("a[i]")
282 self.check_ast_roundtrip("a[i,]")
283 self.check_ast_roundtrip("a[i, j]")
284 self.check_ast_roundtrip("a[()]")
285 self.check_ast_roundtrip("a[i:j]")
286 self.check_ast_roundtrip("a[:j]")
287 self.check_ast_roundtrip("a[i:]")
288 self.check_ast_roundtrip("a[i:j:k]")
289 self.check_ast_roundtrip("a[:j:k]")
290 self.check_ast_roundtrip("a[i::k]")
291 self.check_ast_roundtrip("a[i:j,]")
292 self.check_ast_roundtrip("a[i:j, k]")
293
Pablo Galindo27fc3b62019-11-24 23:02:40 +0000294 def test_invalid_raise(self):
295 self.check_invalid(ast.Raise(exc=None, cause=ast.Name(id="X")))
296
297 def test_invalid_fstring_constant(self):
298 self.check_invalid(ast.JoinedStr(values=[ast.Constant(value=100)]))
299
300 def test_invalid_fstring_conversion(self):
301 self.check_invalid(
302 ast.FormattedValue(
303 value=ast.Constant(value="a", kind=None),
304 conversion=ord("Y"), # random character
305 format_spec=None,
306 )
307 )
308
309 def test_invalid_set(self):
310 self.check_invalid(ast.Set(elts=[]))
311
Batuhan Taşkaya7b35bef2020-01-02 21:20:04 +0300312 def test_invalid_yield_from(self):
313 self.check_invalid(ast.YieldFrom(value=None))
Mark Dickinson1b2e9442012-05-06 17:27:39 +0100314
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300315 def test_docstrings(self):
316 docstrings = (
317 'this ends with double quote"',
318 'this includes a """triple quote"""'
319 )
320 for docstring in docstrings:
321 # check as Module docstrings for easy testing
322 self.check_ast_roundtrip(f"'{docstring}'")
323
Batuhan Taşkayae7cab7f2020-03-09 23:27:03 +0300324 def test_constant_tuples(self):
325 self.check_src_roundtrip(ast.Constant(value=(1,), kind=None), "(1,)")
326 self.check_src_roundtrip(
327 ast.Constant(value=(1, 2, 3), kind=None), "(1, 2, 3)"
328 )
329
Batuhan Taşkaya5b66ec12020-03-15 22:56:57 +0300330 def test_function_type(self):
331 for function_type in (
332 "() -> int",
333 "(int, int) -> int",
334 "(Callable[complex], More[Complex(call.to_typevar())]) -> None"
335 ):
336 self.check_ast_roundtrip(function_type, mode="func_type")
337
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300338
Batuhan Taşkaya397b96f2020-03-01 23:12:17 +0300339class CosmeticTestCase(ASTTestCase):
340 """Test if there are cosmetic issues caused by unnecesary additions"""
341
342 def test_simple_expressions_parens(self):
343 self.check_src_roundtrip("(a := b)")
344 self.check_src_roundtrip("await x")
345 self.check_src_roundtrip("x if x else y")
346 self.check_src_roundtrip("lambda x: x")
347 self.check_src_roundtrip("1 + 1")
348 self.check_src_roundtrip("1 + 2 / 3")
349 self.check_src_roundtrip("(1 + 2) / 3")
350 self.check_src_roundtrip("(1 + 2) * 3 + 4 * (5 + 2)")
351 self.check_src_roundtrip("(1 + 2) * 3 + 4 * (5 + 2) ** 2")
352 self.check_src_roundtrip("~ x")
353 self.check_src_roundtrip("x and y")
354 self.check_src_roundtrip("x and y and z")
355 self.check_src_roundtrip("x and (y and x)")
356 self.check_src_roundtrip("(x and y) and z")
357 self.check_src_roundtrip("(x ** y) ** z ** q")
358 self.check_src_roundtrip("x >> y")
359 self.check_src_roundtrip("x << y")
360 self.check_src_roundtrip("x >> y and x >> z")
361 self.check_src_roundtrip("x + y - z * q ^ t ** k")
362 self.check_src_roundtrip("P * V if P and V else n * R * T")
363 self.check_src_roundtrip("lambda P, V, n: P * V == n * R * T")
364 self.check_src_roundtrip("flag & (other | foo)")
365 self.check_src_roundtrip("not x == y")
366 self.check_src_roundtrip("x == (not y)")
367 self.check_src_roundtrip("yield x")
368 self.check_src_roundtrip("yield from x")
369 self.check_src_roundtrip("call((yield x))")
370 self.check_src_roundtrip("return x + (yield x)")
371
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300372 def test_docstrings(self):
373 docstrings = (
374 '"""simple doc string"""',
375 '''"""A more complex one
376 with some newlines"""''',
377 '''"""Foo bar baz
378
379 empty newline"""''',
380 '"""With some \t"""',
381 '"""Foo "bar" baz """',
382 )
383
384 for prefix in docstring_prefixes:
385 for docstring in docstrings:
386 self.check_src_roundtrip(f"{prefix}{docstring}")
387
388 def test_docstrings_negative_cases(self):
389 # Test some cases that involve strings in the children of the
390 # first node but aren't docstrings to make sure we don't have
391 # False positives.
392 docstrings_negative = (
393 'a = """false"""',
394 '"""false""" + """unless its optimized"""',
395 '1 + 1\n"""false"""',
396 'f"""no, top level but f-fstring"""'
397 )
398 for prefix in docstring_prefixes:
399 for negative in docstrings_negative:
400 # this cases should be result with single quote
401 # rather then triple quoted docstring
402 src = f"{prefix}{negative}"
403 self.check_ast_roundtrip(src)
404 self.check_src_dont_roundtrip(src)
Batuhan Taşkaya397b96f2020-03-01 23:12:17 +0300405
Mark Dickinsond751c2e2010-06-29 14:08:23 +0000406class DirectoryTestCase(ASTTestCase):
407 """Test roundtrip behaviour on all files in Lib and Lib/test."""
408
Pablo Galindo27fc3b62019-11-24 23:02:40 +0000409 lib_dir = pathlib.Path(__file__).parent / ".."
410 test_directories = (lib_dir, lib_dir / "test")
411 skip_files = {"test_fstring.py"}
Pablo Galindo23a226b2019-12-29 19:20:55 +0000412 run_always_files = {"test_grammar.py", "test_syntax.py", "test_compile.py",
413 "test_ast.py", "test_asdl_parser.py"}
Mark Dickinsond751c2e2010-06-29 14:08:23 +0000414
Pablo Galindoac229112019-12-09 17:57:50 +0000415 _files_to_test = None
416
417 @classmethod
418 def files_to_test(cls):
419
420 if cls._files_to_test is not None:
421 return cls._files_to_test
Mark Dickinsond751c2e2010-06-29 14:08:23 +0000422
Pablo Galindo27fc3b62019-11-24 23:02:40 +0000423 items = [
424 item.resolve()
Pablo Galindoac229112019-12-09 17:57:50 +0000425 for directory in cls.test_directories
Pablo Galindo27fc3b62019-11-24 23:02:40 +0000426 for item in directory.glob("*.py")
427 if not item.name.startswith("bad")
428 ]
Mark Dickinsond751c2e2010-06-29 14:08:23 +0000429
Mark Dickinsonbe4fb692012-06-23 09:27:47 +0100430 # Test limited subset of files unless the 'cpu' resource is specified.
431 if not test.support.is_resource_enabled("cpu"):
Pablo Galindobe287c32019-12-29 20:18:36 +0000432
433 tests_to_run_always = {item for item in items if
434 item.name in cls.run_always_files}
435
Pablo Galindo23a226b2019-12-29 19:20:55 +0000436 items = set(random.sample(items, 10))
437
Pablo Galindobe287c32019-12-29 20:18:36 +0000438 # Make sure that at least tests that heavily use grammar features are
439 # always considered in order to reduce the chance of missing something.
440 items = list(items | tests_to_run_always)
Pablo Galindoac229112019-12-09 17:57:50 +0000441
442 # bpo-31174: Store the names sample to always test the same files.
443 # It prevents false alarms when hunting reference leaks.
444 cls._files_to_test = items
445
Pablo Galindo27fc3b62019-11-24 23:02:40 +0000446 return items
Victor Stinner8e482be2017-10-24 03:33:36 -0700447
448 def test_files(self):
Pablo Galindoac229112019-12-09 17:57:50 +0000449 for item in self.files_to_test():
Mark Dickinsond751c2e2010-06-29 14:08:23 +0000450 if test.support.verbose:
Pablo Galindo27fc3b62019-11-24 23:02:40 +0000451 print(f"Testing {item.absolute()}")
Eric V. Smith06cf6012016-09-03 12:33:38 -0400452
Eric V. Smith451d0e32016-09-09 21:56:20 -0400453 # Some f-strings are not correctly round-tripped by
Pablo Galindo27fc3b62019-11-24 23:02:40 +0000454 # Tools/parser/unparse.py. See issue 28002 for details.
455 # We need to skip files that contain such f-strings.
456 if item.name in self.skip_files:
Eric V. Smith06cf6012016-09-03 12:33:38 -0400457 if test.support.verbose:
Pablo Galindo27fc3b62019-11-24 23:02:40 +0000458 print(f"Skipping {item.absolute()}: see issue 28002")
Eric V. Smith06cf6012016-09-03 12:33:38 -0400459 continue
460
Pablo Galindo27fc3b62019-11-24 23:02:40 +0000461 with self.subTest(filename=item):
462 source = read_pyfile(item)
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300463 self.check_ast_roundtrip(source)
Mark Dickinsond751c2e2010-06-29 14:08:23 +0000464
465
Pablo Galindo27fc3b62019-11-24 23:02:40 +0000466if __name__ == "__main__":
Zachary Ware2b0a6102014-07-16 14:26:09 -0500467 unittest.main()