blob: 23292640086b9370b8eccbf8272fde6de95a4ce1 [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."""
14 with open(filename, "rb") as pyfile:
15 encoding = tokenize.detect_encoding(pyfile.readline)[0]
16 with open(filename, "r", encoding=encoding) as pyfile:
17 source = pyfile.read()
18 return source
19
Pablo Galindo27fc3b62019-11-24 23:02:40 +000020
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +000021for_else = """\
Mark Dickinsonae100052010-06-28 19:44:20 +000022def f():
23 for x in range(10):
24 break
25 else:
26 y = 2
27 z = 3
28"""
29
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +000030while_else = """\
Mark Dickinsonae100052010-06-28 19:44:20 +000031def g():
32 while True:
33 break
34 else:
35 y = 2
36 z = 3
37"""
38
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +000039relative_import = """\
40from . import fred
41from .. import barney
42from .australia import shrimp as prawns
43"""
44
45nonlocal_ex = """\
46def f():
47 x = 1
48 def g():
49 nonlocal x
50 x = 2
51 y = 7
52 def h():
53 nonlocal x, y
54"""
55
56# also acts as test for 'except ... as ...'
57raise_from = """\
58try:
59 1 / 0
60except ZeroDivisionError as e:
61 raise ArithmeticError from e
62"""
63
64class_decorator = """\
65@f1(arg)
66@f2
67class Foo: pass
68"""
69
Mark Dickinson8d6d7602010-06-30 08:32:11 +000070elif1 = """\
71if cond1:
72 suite1
73elif cond2:
74 suite2
75else:
76 suite3
77"""
78
79elif2 = """\
80if cond1:
81 suite1
82elif cond2:
83 suite2
84"""
85
Mark Dickinson81ad8cc2010-06-30 08:46:53 +000086try_except_finally = """\
87try:
88 suite1
89except ex1:
90 suite2
91except ex2:
92 suite3
93else:
94 suite4
95finally:
96 suite5
97"""
Mark Dickinson8d6d7602010-06-30 08:32:11 +000098
Mark Dickinsonfe8440a2012-05-06 17:35:19 +010099with_simple = """\
100with f():
101 suite1
102"""
103
104with_as = """\
105with f() as x:
106 suite1
107"""
108
109with_two_items = """\
110with f() as x, g() as y:
111 suite1
112"""
113
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300114docstring_prefixes = [
115 "",
116 "class foo():\n ",
117 "def foo():\n ",
118 "async def foo():\n ",
119]
Pablo Galindo27fc3b62019-11-24 23:02:40 +0000120
Mark Dickinsond751c2e2010-06-29 14:08:23 +0000121class ASTTestCase(unittest.TestCase):
122 def assertASTEqual(self, ast1, ast2):
123 self.assertEqual(ast.dump(ast1), ast.dump(ast2))
Mark Dickinsonae100052010-06-28 19:44:20 +0000124
Batuhan Taşkaya5b66ec12020-03-15 22:56:57 +0300125 def check_ast_roundtrip(self, code1, **kwargs):
126 ast1 = ast.parse(code1, **kwargs)
Pablo Galindo27fc3b62019-11-24 23:02:40 +0000127 code2 = ast.unparse(ast1)
Batuhan Taşkaya5b66ec12020-03-15 22:56:57 +0300128 ast2 = ast.parse(code2, **kwargs)
Mark Dickinsond751c2e2010-06-29 14:08:23 +0000129 self.assertASTEqual(ast1, ast2)
130
Pablo Galindo27fc3b62019-11-24 23:02:40 +0000131 def check_invalid(self, node, raises=ValueError):
132 self.assertRaises(raises, ast.unparse, node)
133
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300134 def get_source(self, code1, code2=None, strip=True):
Batuhan Taşkaya397b96f2020-03-01 23:12:17 +0300135 code2 = code2 or code1
136 code1 = ast.unparse(ast.parse(code1))
137 if strip:
138 code1 = code1.strip()
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300139 return code1, code2
140
141 def check_src_roundtrip(self, code1, code2=None, strip=True):
142 code1, code2 = self.get_source(code1, code2, strip)
Batuhan Taşkaya397b96f2020-03-01 23:12:17 +0300143 self.assertEqual(code2, code1)
144
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300145 def check_src_dont_roundtrip(self, code1, code2=None, strip=True):
146 code1, code2 = self.get_source(code1, code2, strip)
147 self.assertNotEqual(code2, code1)
Pablo Galindo27fc3b62019-11-24 23:02:40 +0000148
Mark Dickinsond751c2e2010-06-29 14:08:23 +0000149class UnparseTestCase(ASTTestCase):
150 # Tests for specific bugs found in earlier versions of unparse
Mark Dickinsonae100052010-06-28 19:44:20 +0000151
Eric V. Smith608adf92015-09-20 15:09:15 -0400152 def test_fstrings(self):
153 # See issue 25180
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300154 self.check_ast_roundtrip(r"""f'{f"{0}"*3}'""")
155 self.check_ast_roundtrip(r"""f'{f"{y}"*3}'""")
Eric V. Smith608adf92015-09-20 15:09:15 -0400156
Chih-Hsuan Yenaaf47ca2019-05-27 01:08:20 +0800157 def test_strings(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300158 self.check_ast_roundtrip("u'foo'")
159 self.check_ast_roundtrip("r'foo'")
160 self.check_ast_roundtrip("b'foo'")
Chih-Hsuan Yenaaf47ca2019-05-27 01:08:20 +0800161
Mark Dickinsonae100052010-06-28 19:44:20 +0000162 def test_del_statement(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300163 self.check_ast_roundtrip("del x, y, z")
Mark Dickinsonae100052010-06-28 19:44:20 +0000164
165 def test_shifts(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300166 self.check_ast_roundtrip("45 << 2")
167 self.check_ast_roundtrip("13 >> 7")
Mark Dickinsonae100052010-06-28 19:44:20 +0000168
169 def test_for_else(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300170 self.check_ast_roundtrip(for_else)
Mark Dickinsonae100052010-06-28 19:44:20 +0000171
172 def test_while_else(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300173 self.check_ast_roundtrip(while_else)
Mark Dickinsonae100052010-06-28 19:44:20 +0000174
175 def test_unary_parens(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300176 self.check_ast_roundtrip("(-1)**7")
177 self.check_ast_roundtrip("(-1.)**8")
178 self.check_ast_roundtrip("(-1j)**6")
179 self.check_ast_roundtrip("not True or False")
180 self.check_ast_roundtrip("True or not False")
Mark Dickinsonae100052010-06-28 19:44:20 +0000181
Mark Dickinson3eb02902010-06-29 08:52:36 +0000182 def test_integer_parens(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300183 self.check_ast_roundtrip("3 .__abs__()")
Mark Dickinson3eb02902010-06-29 08:52:36 +0000184
Mark Dickinson8042e282010-06-29 10:01:48 +0000185 def test_huge_float(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300186 self.check_ast_roundtrip("1e1000")
187 self.check_ast_roundtrip("-1e1000")
188 self.check_ast_roundtrip("1e1000j")
189 self.check_ast_roundtrip("-1e1000j")
Mark Dickinsoncba8c102010-06-30 11:45:53 +0000190
191 def test_min_int(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300192 self.check_ast_roundtrip(str(-(2 ** 31)))
193 self.check_ast_roundtrip(str(-(2 ** 63)))
Mark Dickinsoncba8c102010-06-30 11:45:53 +0000194
195 def test_imaginary_literals(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300196 self.check_ast_roundtrip("7j")
197 self.check_ast_roundtrip("-7j")
198 self.check_ast_roundtrip("0j")
199 self.check_ast_roundtrip("-0j")
Mark Dickinson8042e282010-06-29 10:01:48 +0000200
201 def test_lambda_parentheses(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300202 self.check_ast_roundtrip("(lambda: int)()")
Mark Dickinson8042e282010-06-29 10:01:48 +0000203
Mark Dickinsonf5451e52010-06-28 20:09:18 +0000204 def test_chained_comparisons(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300205 self.check_ast_roundtrip("1 < 4 <= 5")
206 self.check_ast_roundtrip("a is b is c is not d")
Mark Dickinsonf5451e52010-06-28 20:09:18 +0000207
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000208 def test_function_arguments(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300209 self.check_ast_roundtrip("def f(): pass")
210 self.check_ast_roundtrip("def f(a): pass")
211 self.check_ast_roundtrip("def f(b = 2): pass")
212 self.check_ast_roundtrip("def f(a, b): pass")
213 self.check_ast_roundtrip("def f(a, b = 2): pass")
214 self.check_ast_roundtrip("def f(a = 5, b = 2): pass")
215 self.check_ast_roundtrip("def f(*, a = 1, b = 2): pass")
216 self.check_ast_roundtrip("def f(*, a = 1, b): pass")
217 self.check_ast_roundtrip("def f(*, a, b = 2): pass")
218 self.check_ast_roundtrip("def f(a, b = None, *, c, **kwds): pass")
219 self.check_ast_roundtrip("def f(a=2, *args, c=5, d, **kwds): pass")
220 self.check_ast_roundtrip("def f(*args, **kwargs): pass")
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000221
222 def test_relative_import(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300223 self.check_ast_roundtrip(relative_import)
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000224
225 def test_nonlocal(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300226 self.check_ast_roundtrip(nonlocal_ex)
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000227
228 def test_raise_from(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300229 self.check_ast_roundtrip(raise_from)
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000230
231 def test_bytes(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300232 self.check_ast_roundtrip("b'123'")
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000233
234 def test_annotations(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300235 self.check_ast_roundtrip("def f(a : int): pass")
236 self.check_ast_roundtrip("def f(a: int = 5): pass")
237 self.check_ast_roundtrip("def f(*args: [int]): pass")
238 self.check_ast_roundtrip("def f(**kwargs: dict): pass")
239 self.check_ast_roundtrip("def f() -> None: pass")
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000240
241 def test_set_literal(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300242 self.check_ast_roundtrip("{'a', 'b', 'c'}")
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000243
244 def test_set_comprehension(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300245 self.check_ast_roundtrip("{x for x in range(5)}")
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000246
247 def test_dict_comprehension(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300248 self.check_ast_roundtrip("{x: x*x for x in range(10)}")
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000249
250 def test_class_decorators(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300251 self.check_ast_roundtrip(class_decorator)
Mark Dickinsonae100052010-06-28 19:44:20 +0000252
Mark Dickinson578aa562010-06-29 18:38:59 +0000253 def test_class_definition(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300254 self.check_ast_roundtrip("class A(metaclass=type, *[], **{}): pass")
Mark Dickinsond751c2e2010-06-29 14:08:23 +0000255
Mark Dickinson8d6d7602010-06-30 08:32:11 +0000256 def test_elifs(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300257 self.check_ast_roundtrip(elif1)
258 self.check_ast_roundtrip(elif2)
Mark Dickinson8d6d7602010-06-30 08:32:11 +0000259
Mark Dickinson81ad8cc2010-06-30 08:46:53 +0000260 def test_try_except_finally(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300261 self.check_ast_roundtrip(try_except_finally)
Mark Dickinson81ad8cc2010-06-30 08:46:53 +0000262
Mark Dickinson1b2e9442012-05-06 17:27:39 +0100263 def test_starred_assignment(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300264 self.check_ast_roundtrip("a, *b, c = seq")
265 self.check_ast_roundtrip("a, (*b, c) = seq")
266 self.check_ast_roundtrip("a, *b[0], c = seq")
267 self.check_ast_roundtrip("a, *(b, c) = seq")
Mark Dickinson1b2e9442012-05-06 17:27:39 +0100268
Mark Dickinsonfe8440a2012-05-06 17:35:19 +0100269 def test_with_simple(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300270 self.check_ast_roundtrip(with_simple)
Mark Dickinsonfe8440a2012-05-06 17:35:19 +0100271
272 def test_with_as(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300273 self.check_ast_roundtrip(with_as)
Mark Dickinsonfe8440a2012-05-06 17:35:19 +0100274
275 def test_with_two_items(self):
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300276 self.check_ast_roundtrip(with_two_items)
Mark Dickinsonfe8440a2012-05-06 17:35:19 +0100277
Berker Peksagd66dd5c2016-03-06 16:50:15 +0200278 def test_dict_unpacking_in_dict(self):
279 # See issue 26489
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300280 self.check_ast_roundtrip(r"""{**{'y': 2}, 'x': 1}""")
281 self.check_ast_roundtrip(r"""{**{'y': 2}, **{'x': 1}}""")
Berker Peksagd66dd5c2016-03-06 16:50:15 +0200282
Batuhan Taşkayae7cab7f2020-03-09 23:27:03 +0300283 def test_ext_slices(self):
284 self.check_ast_roundtrip("a[i]")
285 self.check_ast_roundtrip("a[i,]")
286 self.check_ast_roundtrip("a[i, j]")
287 self.check_ast_roundtrip("a[()]")
288 self.check_ast_roundtrip("a[i:j]")
289 self.check_ast_roundtrip("a[:j]")
290 self.check_ast_roundtrip("a[i:]")
291 self.check_ast_roundtrip("a[i:j:k]")
292 self.check_ast_roundtrip("a[:j:k]")
293 self.check_ast_roundtrip("a[i::k]")
294 self.check_ast_roundtrip("a[i:j,]")
295 self.check_ast_roundtrip("a[i:j, k]")
296
Pablo Galindo27fc3b62019-11-24 23:02:40 +0000297 def test_invalid_raise(self):
298 self.check_invalid(ast.Raise(exc=None, cause=ast.Name(id="X")))
299
300 def test_invalid_fstring_constant(self):
301 self.check_invalid(ast.JoinedStr(values=[ast.Constant(value=100)]))
302
303 def test_invalid_fstring_conversion(self):
304 self.check_invalid(
305 ast.FormattedValue(
306 value=ast.Constant(value="a", kind=None),
307 conversion=ord("Y"), # random character
308 format_spec=None,
309 )
310 )
311
312 def test_invalid_set(self):
313 self.check_invalid(ast.Set(elts=[]))
314
Batuhan Taşkaya7b35bef2020-01-02 21:20:04 +0300315 def test_invalid_yield_from(self):
316 self.check_invalid(ast.YieldFrom(value=None))
Mark Dickinson1b2e9442012-05-06 17:27:39 +0100317
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300318 def test_docstrings(self):
319 docstrings = (
320 'this ends with double quote"',
321 'this includes a """triple quote"""'
322 )
323 for docstring in docstrings:
324 # check as Module docstrings for easy testing
325 self.check_ast_roundtrip(f"'{docstring}'")
326
Batuhan Taşkayae7cab7f2020-03-09 23:27:03 +0300327 def test_constant_tuples(self):
328 self.check_src_roundtrip(ast.Constant(value=(1,), kind=None), "(1,)")
329 self.check_src_roundtrip(
330 ast.Constant(value=(1, 2, 3), kind=None), "(1, 2, 3)"
331 )
332
Batuhan Taşkaya5b66ec12020-03-15 22:56:57 +0300333 def test_function_type(self):
334 for function_type in (
335 "() -> int",
336 "(int, int) -> int",
337 "(Callable[complex], More[Complex(call.to_typevar())]) -> None"
338 ):
339 self.check_ast_roundtrip(function_type, mode="func_type")
340
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300341
Batuhan Taşkaya397b96f2020-03-01 23:12:17 +0300342class CosmeticTestCase(ASTTestCase):
343 """Test if there are cosmetic issues caused by unnecesary additions"""
344
345 def test_simple_expressions_parens(self):
346 self.check_src_roundtrip("(a := b)")
347 self.check_src_roundtrip("await x")
348 self.check_src_roundtrip("x if x else y")
349 self.check_src_roundtrip("lambda x: x")
350 self.check_src_roundtrip("1 + 1")
351 self.check_src_roundtrip("1 + 2 / 3")
352 self.check_src_roundtrip("(1 + 2) / 3")
353 self.check_src_roundtrip("(1 + 2) * 3 + 4 * (5 + 2)")
354 self.check_src_roundtrip("(1 + 2) * 3 + 4 * (5 + 2) ** 2")
355 self.check_src_roundtrip("~ x")
356 self.check_src_roundtrip("x and y")
357 self.check_src_roundtrip("x and y and z")
358 self.check_src_roundtrip("x and (y and x)")
359 self.check_src_roundtrip("(x and y) and z")
360 self.check_src_roundtrip("(x ** y) ** z ** q")
361 self.check_src_roundtrip("x >> y")
362 self.check_src_roundtrip("x << y")
363 self.check_src_roundtrip("x >> y and x >> z")
364 self.check_src_roundtrip("x + y - z * q ^ t ** k")
365 self.check_src_roundtrip("P * V if P and V else n * R * T")
366 self.check_src_roundtrip("lambda P, V, n: P * V == n * R * T")
367 self.check_src_roundtrip("flag & (other | foo)")
368 self.check_src_roundtrip("not x == y")
369 self.check_src_roundtrip("x == (not y)")
370 self.check_src_roundtrip("yield x")
371 self.check_src_roundtrip("yield from x")
372 self.check_src_roundtrip("call((yield x))")
373 self.check_src_roundtrip("return x + (yield x)")
374
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300375 def test_docstrings(self):
376 docstrings = (
377 '"""simple doc string"""',
378 '''"""A more complex one
379 with some newlines"""''',
380 '''"""Foo bar baz
381
382 empty newline"""''',
383 '"""With some \t"""',
384 '"""Foo "bar" baz """',
385 )
386
387 for prefix in docstring_prefixes:
388 for docstring in docstrings:
389 self.check_src_roundtrip(f"{prefix}{docstring}")
390
391 def test_docstrings_negative_cases(self):
392 # Test some cases that involve strings in the children of the
393 # first node but aren't docstrings to make sure we don't have
394 # False positives.
395 docstrings_negative = (
396 'a = """false"""',
397 '"""false""" + """unless its optimized"""',
398 '1 + 1\n"""false"""',
399 'f"""no, top level but f-fstring"""'
400 )
401 for prefix in docstring_prefixes:
402 for negative in docstrings_negative:
403 # this cases should be result with single quote
404 # rather then triple quoted docstring
405 src = f"{prefix}{negative}"
406 self.check_ast_roundtrip(src)
407 self.check_src_dont_roundtrip(src)
Batuhan Taşkaya397b96f2020-03-01 23:12:17 +0300408
Mark Dickinsond751c2e2010-06-29 14:08:23 +0000409class DirectoryTestCase(ASTTestCase):
410 """Test roundtrip behaviour on all files in Lib and Lib/test."""
411
Pablo Galindo27fc3b62019-11-24 23:02:40 +0000412 lib_dir = pathlib.Path(__file__).parent / ".."
413 test_directories = (lib_dir, lib_dir / "test")
414 skip_files = {"test_fstring.py"}
Pablo Galindo23a226b2019-12-29 19:20:55 +0000415 run_always_files = {"test_grammar.py", "test_syntax.py", "test_compile.py",
416 "test_ast.py", "test_asdl_parser.py"}
Mark Dickinsond751c2e2010-06-29 14:08:23 +0000417
Pablo Galindoac229112019-12-09 17:57:50 +0000418 _files_to_test = None
419
420 @classmethod
421 def files_to_test(cls):
422
423 if cls._files_to_test is not None:
424 return cls._files_to_test
Mark Dickinsond751c2e2010-06-29 14:08:23 +0000425
Pablo Galindo27fc3b62019-11-24 23:02:40 +0000426 items = [
427 item.resolve()
Pablo Galindoac229112019-12-09 17:57:50 +0000428 for directory in cls.test_directories
Pablo Galindo27fc3b62019-11-24 23:02:40 +0000429 for item in directory.glob("*.py")
430 if not item.name.startswith("bad")
431 ]
Mark Dickinsond751c2e2010-06-29 14:08:23 +0000432
Mark Dickinsonbe4fb692012-06-23 09:27:47 +0100433 # Test limited subset of files unless the 'cpu' resource is specified.
434 if not test.support.is_resource_enabled("cpu"):
Pablo Galindobe287c32019-12-29 20:18:36 +0000435
436 tests_to_run_always = {item for item in items if
437 item.name in cls.run_always_files}
438
Pablo Galindo23a226b2019-12-29 19:20:55 +0000439 items = set(random.sample(items, 10))
440
Pablo Galindobe287c32019-12-29 20:18:36 +0000441 # Make sure that at least tests that heavily use grammar features are
442 # always considered in order to reduce the chance of missing something.
443 items = list(items | tests_to_run_always)
Pablo Galindoac229112019-12-09 17:57:50 +0000444
445 # bpo-31174: Store the names sample to always test the same files.
446 # It prevents false alarms when hunting reference leaks.
447 cls._files_to_test = items
448
Pablo Galindo27fc3b62019-11-24 23:02:40 +0000449 return items
Victor Stinner8e482be2017-10-24 03:33:36 -0700450
451 def test_files(self):
Pablo Galindoac229112019-12-09 17:57:50 +0000452 for item in self.files_to_test():
Mark Dickinsond751c2e2010-06-29 14:08:23 +0000453 if test.support.verbose:
Pablo Galindo27fc3b62019-11-24 23:02:40 +0000454 print(f"Testing {item.absolute()}")
Eric V. Smith06cf6012016-09-03 12:33:38 -0400455
Eric V. Smith451d0e32016-09-09 21:56:20 -0400456 # Some f-strings are not correctly round-tripped by
Pablo Galindo27fc3b62019-11-24 23:02:40 +0000457 # Tools/parser/unparse.py. See issue 28002 for details.
458 # We need to skip files that contain such f-strings.
459 if item.name in self.skip_files:
Eric V. Smith06cf6012016-09-03 12:33:38 -0400460 if test.support.verbose:
Pablo Galindo27fc3b62019-11-24 23:02:40 +0000461 print(f"Skipping {item.absolute()}: see issue 28002")
Eric V. Smith06cf6012016-09-03 12:33:38 -0400462 continue
463
Pablo Galindo27fc3b62019-11-24 23:02:40 +0000464 with self.subTest(filename=item):
465 source = read_pyfile(item)
Batuhan Taşkaya89aa4692020-03-02 21:59:01 +0300466 self.check_ast_roundtrip(source)
Mark Dickinsond751c2e2010-06-29 14:08:23 +0000467
468
Pablo Galindo27fc3b62019-11-24 23:02:40 +0000469if __name__ == "__main__":
Zachary Ware2b0a6102014-07-16 14:26:09 -0500470 unittest.main()