ยปCore Development>Code coverage>Lib/test/test_tools/test_unparse.py

Python code coverage for Lib/test/test_tools/test_unparse.py

#countcontent
1n/a"""Tests for the unparse.py script in the Tools/parser directory."""
2n/a
3n/aimport unittest
4n/aimport test.support
5n/aimport io
6n/aimport os
7n/aimport random
8n/aimport tokenize
9n/aimport ast
10n/a
11n/afrom test.test_tools import basepath, toolsdir, skip_if_missing
12n/a
13n/askip_if_missing()
14n/a
15n/aparser_path = os.path.join(toolsdir, "parser")
16n/a
17n/awith test.support.DirsOnSysPath(parser_path):
18n/a import unparse
19n/a
20n/adef read_pyfile(filename):
21n/a """Read and return the contents of a Python source file (as a
22n/a string), taking into account the file encoding."""
23n/a with open(filename, "rb") as pyfile:
24n/a encoding = tokenize.detect_encoding(pyfile.readline)[0]
25n/a with open(filename, "r", encoding=encoding) as pyfile:
26n/a source = pyfile.read()
27n/a return source
28n/a
29n/afor_else = """\
30n/adef f():
31n/a for x in range(10):
32n/a break
33n/a else:
34n/a y = 2
35n/a z = 3
36n/a"""
37n/a
38n/awhile_else = """\
39n/adef g():
40n/a while True:
41n/a break
42n/a else:
43n/a y = 2
44n/a z = 3
45n/a"""
46n/a
47n/arelative_import = """\
48n/afrom . import fred
49n/afrom .. import barney
50n/afrom .australia import shrimp as prawns
51n/a"""
52n/a
53n/anonlocal_ex = """\
54n/adef f():
55n/a x = 1
56n/a def g():
57n/a nonlocal x
58n/a x = 2
59n/a y = 7
60n/a def h():
61n/a nonlocal x, y
62n/a"""
63n/a
64n/a# also acts as test for 'except ... as ...'
65n/araise_from = """\
66n/atry:
67n/a 1 / 0
68n/aexcept ZeroDivisionError as e:
69n/a raise ArithmeticError from e
70n/a"""
71n/a
72n/aclass_decorator = """\
73n/a@f1(arg)
74n/a@f2
75n/aclass Foo: pass
76n/a"""
77n/a
78n/aelif1 = """\
79n/aif cond1:
80n/a suite1
81n/aelif cond2:
82n/a suite2
83n/aelse:
84n/a suite3
85n/a"""
86n/a
87n/aelif2 = """\
88n/aif cond1:
89n/a suite1
90n/aelif cond2:
91n/a suite2
92n/a"""
93n/a
94n/atry_except_finally = """\
95n/atry:
96n/a suite1
97n/aexcept ex1:
98n/a suite2
99n/aexcept ex2:
100n/a suite3
101n/aelse:
102n/a suite4
103n/afinally:
104n/a suite5
105n/a"""
106n/a
107n/awith_simple = """\
108n/awith f():
109n/a suite1
110n/a"""
111n/a
112n/awith_as = """\
113n/awith f() as x:
114n/a suite1
115n/a"""
116n/a
117n/awith_two_items = """\
118n/awith f() as x, g() as y:
119n/a suite1
120n/a"""
121n/a
122n/aclass ASTTestCase(unittest.TestCase):
123n/a def assertASTEqual(self, ast1, ast2):
124n/a self.assertEqual(ast.dump(ast1), ast.dump(ast2))
125n/a
126n/a def check_roundtrip(self, code1, filename="internal"):
127n/a ast1 = compile(code1, filename, "exec", ast.PyCF_ONLY_AST)
128n/a unparse_buffer = io.StringIO()
129n/a unparse.Unparser(ast1, unparse_buffer)
130n/a code2 = unparse_buffer.getvalue()
131n/a ast2 = compile(code2, filename, "exec", ast.PyCF_ONLY_AST)
132n/a self.assertASTEqual(ast1, ast2)
133n/a
134n/aclass UnparseTestCase(ASTTestCase):
135n/a # Tests for specific bugs found in earlier versions of unparse
136n/a
137n/a def test_fstrings(self):
138n/a # See issue 25180
139n/a self.check_roundtrip(r"""f'{f"{0}"*3}'""")
140n/a self.check_roundtrip(r"""f'{f"{y}"*3}'""")
141n/a
142n/a def test_del_statement(self):
143n/a self.check_roundtrip("del x, y, z")
144n/a
145n/a def test_shifts(self):
146n/a self.check_roundtrip("45 << 2")
147n/a self.check_roundtrip("13 >> 7")
148n/a
149n/a def test_for_else(self):
150n/a self.check_roundtrip(for_else)
151n/a
152n/a def test_while_else(self):
153n/a self.check_roundtrip(while_else)
154n/a
155n/a def test_unary_parens(self):
156n/a self.check_roundtrip("(-1)**7")
157n/a self.check_roundtrip("(-1.)**8")
158n/a self.check_roundtrip("(-1j)**6")
159n/a self.check_roundtrip("not True or False")
160n/a self.check_roundtrip("True or not False")
161n/a
162n/a def test_integer_parens(self):
163n/a self.check_roundtrip("3 .__abs__()")
164n/a
165n/a def test_huge_float(self):
166n/a self.check_roundtrip("1e1000")
167n/a self.check_roundtrip("-1e1000")
168n/a self.check_roundtrip("1e1000j")
169n/a self.check_roundtrip("-1e1000j")
170n/a
171n/a def test_min_int(self):
172n/a self.check_roundtrip(str(-2**31))
173n/a self.check_roundtrip(str(-2**63))
174n/a
175n/a def test_imaginary_literals(self):
176n/a self.check_roundtrip("7j")
177n/a self.check_roundtrip("-7j")
178n/a self.check_roundtrip("0j")
179n/a self.check_roundtrip("-0j")
180n/a
181n/a def test_lambda_parentheses(self):
182n/a self.check_roundtrip("(lambda: int)()")
183n/a
184n/a def test_chained_comparisons(self):
185n/a self.check_roundtrip("1 < 4 <= 5")
186n/a self.check_roundtrip("a is b is c is not d")
187n/a
188n/a def test_function_arguments(self):
189n/a self.check_roundtrip("def f(): pass")
190n/a self.check_roundtrip("def f(a): pass")
191n/a self.check_roundtrip("def f(b = 2): pass")
192n/a self.check_roundtrip("def f(a, b): pass")
193n/a self.check_roundtrip("def f(a, b = 2): pass")
194n/a self.check_roundtrip("def f(a = 5, b = 2): pass")
195n/a self.check_roundtrip("def f(*, a = 1, b = 2): pass")
196n/a self.check_roundtrip("def f(*, a = 1, b): pass")
197n/a self.check_roundtrip("def f(*, a, b = 2): pass")
198n/a self.check_roundtrip("def f(a, b = None, *, c, **kwds): pass")
199n/a self.check_roundtrip("def f(a=2, *args, c=5, d, **kwds): pass")
200n/a self.check_roundtrip("def f(*args, **kwargs): pass")
201n/a
202n/a def test_relative_import(self):
203n/a self.check_roundtrip(relative_import)
204n/a
205n/a def test_nonlocal(self):
206n/a self.check_roundtrip(nonlocal_ex)
207n/a
208n/a def test_raise_from(self):
209n/a self.check_roundtrip(raise_from)
210n/a
211n/a def test_bytes(self):
212n/a self.check_roundtrip("b'123'")
213n/a
214n/a def test_annotations(self):
215n/a self.check_roundtrip("def f(a : int): pass")
216n/a self.check_roundtrip("def f(a: int = 5): pass")
217n/a self.check_roundtrip("def f(*args: [int]): pass")
218n/a self.check_roundtrip("def f(**kwargs: dict): pass")
219n/a self.check_roundtrip("def f() -> None: pass")
220n/a
221n/a def test_set_literal(self):
222n/a self.check_roundtrip("{'a', 'b', 'c'}")
223n/a
224n/a def test_set_comprehension(self):
225n/a self.check_roundtrip("{x for x in range(5)}")
226n/a
227n/a def test_dict_comprehension(self):
228n/a self.check_roundtrip("{x: x*x for x in range(10)}")
229n/a
230n/a def test_class_decorators(self):
231n/a self.check_roundtrip(class_decorator)
232n/a
233n/a def test_class_definition(self):
234n/a self.check_roundtrip("class A(metaclass=type, *[], **{}): pass")
235n/a
236n/a def test_elifs(self):
237n/a self.check_roundtrip(elif1)
238n/a self.check_roundtrip(elif2)
239n/a
240n/a def test_try_except_finally(self):
241n/a self.check_roundtrip(try_except_finally)
242n/a
243n/a def test_starred_assignment(self):
244n/a self.check_roundtrip("a, *b, c = seq")
245n/a self.check_roundtrip("a, (*b, c) = seq")
246n/a self.check_roundtrip("a, *b[0], c = seq")
247n/a self.check_roundtrip("a, *(b, c) = seq")
248n/a
249n/a def test_with_simple(self):
250n/a self.check_roundtrip(with_simple)
251n/a
252n/a def test_with_as(self):
253n/a self.check_roundtrip(with_as)
254n/a
255n/a def test_with_two_items(self):
256n/a self.check_roundtrip(with_two_items)
257n/a
258n/a def test_dict_unpacking_in_dict(self):
259n/a # See issue 26489
260n/a self.check_roundtrip(r"""{**{'y': 2}, 'x': 1}""")
261n/a self.check_roundtrip(r"""{**{'y': 2}, **{'x': 1}}""")
262n/a
263n/a
264n/aclass DirectoryTestCase(ASTTestCase):
265n/a """Test roundtrip behaviour on all files in Lib and Lib/test."""
266n/a
267n/a # test directories, relative to the root of the distribution
268n/a test_directories = 'Lib', os.path.join('Lib', 'test')
269n/a
270n/a def test_files(self):
271n/a # get names of files to test
272n/a
273n/a names = []
274n/a for d in self.test_directories:
275n/a test_dir = os.path.join(basepath, d)
276n/a for n in os.listdir(test_dir):
277n/a if n.endswith('.py') and not n.startswith('bad'):
278n/a names.append(os.path.join(test_dir, n))
279n/a
280n/a # Test limited subset of files unless the 'cpu' resource is specified.
281n/a if not test.support.is_resource_enabled("cpu"):
282n/a names = random.sample(names, 10)
283n/a
284n/a for filename in names:
285n/a if test.support.verbose:
286n/a print('Testing %s' % filename)
287n/a
288n/a # Some f-strings are not correctly round-tripped by
289n/a # Tools/parser/unparse.py. See issue 28002 for details.
290n/a # We need to skip files that contain such f-strings.
291n/a if os.path.basename(filename) in ('test_fstring.py', ):
292n/a if test.support.verbose:
293n/a print(f'Skipping {filename}: see issue 28002')
294n/a continue
295n/a
296n/a with self.subTest(filename=filename):
297n/a source = read_pyfile(filename)
298n/a self.check_roundtrip(source)
299n/a
300n/a
301n/aif __name__ == '__main__':
302n/a unittest.main()