python (3.12.0)
1 """
2 Test cases for codeop.py
3 Nick Mathewson
4 """
5 import unittest
6 import warnings
7 from test.support import warnings_helper
8
9 from codeop import compile_command, PyCF_DONT_IMPLY_DEDENT
10
11 class ESC[4;38;5;81mCodeopTests(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
12
13 def assertValid(self, str, symbol='single'):
14 '''succeed iff str is a valid piece of code'''
15 expected = compile(str, "<input>", symbol, PyCF_DONT_IMPLY_DEDENT)
16 self.assertEqual(compile_command(str, "<input>", symbol), expected)
17
18 def assertIncomplete(self, str, symbol='single'):
19 '''succeed iff str is the start of a valid piece of code'''
20 self.assertEqual(compile_command(str, symbol=symbol), None)
21
22 def assertInvalid(self, str, symbol='single', is_syntax=1):
23 '''succeed iff str is the start of an invalid piece of code'''
24 try:
25 compile_command(str,symbol=symbol)
26 self.fail("No exception raised for invalid code")
27 except SyntaxError:
28 self.assertTrue(is_syntax)
29 except OverflowError:
30 self.assertTrue(not is_syntax)
31
32 def test_valid(self):
33 av = self.assertValid
34
35 # special case
36 self.assertEqual(compile_command(""),
37 compile("pass", "<input>", 'single',
38 PyCF_DONT_IMPLY_DEDENT))
39 self.assertEqual(compile_command("\n"),
40 compile("pass", "<input>", 'single',
41 PyCF_DONT_IMPLY_DEDENT))
42
43 av("a = 1")
44 av("\na = 1")
45 av("a = 1\n")
46 av("a = 1\n\n")
47 av("\n\na = 1\n\n")
48
49 av("def x():\n pass\n")
50 av("if 1:\n pass\n")
51
52 av("\n\nif 1: pass\n")
53 av("\n\nif 1: pass\n\n")
54
55 av("def x():\n\n pass\n")
56 av("def x():\n pass\n \n")
57 av("def x():\n pass\n \n")
58
59 av("pass\n")
60 av("3**3\n")
61
62 av("if 9==3:\n pass\nelse:\n pass\n")
63 av("if 1:\n pass\n if 1:\n pass\n else:\n pass\n")
64
65 av("#a\n#b\na = 3\n")
66 av("#a\n\n \na=3\n")
67 av("a=3\n\n")
68 av("a = 9+ \\\n3")
69
70 av("3**3","eval")
71 av("(lambda z: \n z**3)","eval")
72
73 av("9+ \\\n3","eval")
74 av("9+ \\\n3\n","eval")
75
76 av("\n\na**3","eval")
77 av("\n \na**3","eval")
78 av("#a\n#b\na**3","eval")
79
80 av("\n\na = 1\n\n")
81 av("\n\nif 1: a=1\n\n")
82
83 av("if 1:\n pass\n if 1:\n pass\n else:\n pass\n")
84 av("#a\n\n \na=3\n\n")
85
86 av("\n\na**3","eval")
87 av("\n \na**3","eval")
88 av("#a\n#b\na**3","eval")
89
90 av("def f():\n try: pass\n finally: [x for x in (1,2)]\n")
91 av("def f():\n pass\n#foo\n")
92 av("@a.b.c\ndef f():\n pass\n")
93
94 def test_incomplete(self):
95 ai = self.assertIncomplete
96
97 ai("(a **")
98 ai("(a,b,")
99 ai("(a,b,(")
100 ai("(a,b,(")
101 ai("a = (")
102 ai("a = {")
103 ai("b + {")
104
105 ai("print([1,\n2,")
106 ai("print({1:1,\n2:3,")
107 ai("print((1,\n2,")
108
109 ai("if 9==3:\n pass\nelse:")
110 ai("if 9==3:\n pass\nelse:\n")
111 ai("if 9==3:\n pass\nelse:\n pass")
112 ai("if 1:")
113 ai("if 1:\n")
114 ai("if 1:\n pass\n if 1:\n pass\n else:")
115 ai("if 1:\n pass\n if 1:\n pass\n else:\n")
116 ai("if 1:\n pass\n if 1:\n pass\n else:\n pass")
117
118 ai("def x():")
119 ai("def x():\n")
120 ai("def x():\n\n")
121
122 ai("def x():\n pass")
123 ai("def x():\n pass\n ")
124 ai("def x():\n pass\n ")
125 ai("\n\ndef x():\n pass")
126
127 ai("a = 9+ \\")
128 ai("a = 'a\\")
129 ai("a = '''xy")
130
131 ai("","eval")
132 ai("\n","eval")
133 ai("(","eval")
134 ai("(9+","eval")
135 ai("9+ \\","eval")
136 ai("lambda z: \\","eval")
137
138 ai("if True:\n if True:\n if True: \n")
139
140 ai("@a(")
141 ai("@a(b")
142 ai("@a(b,")
143 ai("@a(b,c")
144 ai("@a(b,c,")
145
146 ai("from a import (")
147 ai("from a import (b")
148 ai("from a import (b,")
149 ai("from a import (b,c")
150 ai("from a import (b,c,")
151
152 ai("[")
153 ai("[a")
154 ai("[a,")
155 ai("[a,b")
156 ai("[a,b,")
157
158 ai("{")
159 ai("{a")
160 ai("{a:")
161 ai("{a:b")
162 ai("{a:b,")
163 ai("{a:b,c")
164 ai("{a:b,c:")
165 ai("{a:b,c:d")
166 ai("{a:b,c:d,")
167
168 ai("a(")
169 ai("a(b")
170 ai("a(b,")
171 ai("a(b,c")
172 ai("a(b,c,")
173
174 ai("a[")
175 ai("a[b")
176 ai("a[b,")
177 ai("a[b:")
178 ai("a[b:c")
179 ai("a[b:c:")
180 ai("a[b:c:d")
181
182 ai("def a(")
183 ai("def a(b")
184 ai("def a(b,")
185 ai("def a(b,c")
186 ai("def a(b,c,")
187
188 ai("(")
189 ai("(a")
190 ai("(a,")
191 ai("(a,b")
192 ai("(a,b,")
193
194 ai("if a:\n pass\nelif b:")
195 ai("if a:\n pass\nelif b:\n pass\nelse:")
196
197 ai("while a:")
198 ai("while a:\n pass\nelse:")
199
200 ai("for a in b:")
201 ai("for a in b:\n pass\nelse:")
202
203 ai("try:")
204 ai("try:\n pass\nexcept:")
205 ai("try:\n pass\nfinally:")
206 ai("try:\n pass\nexcept:\n pass\nfinally:")
207
208 ai("with a:")
209 ai("with a as b:")
210
211 ai("class a:")
212 ai("class a(")
213 ai("class a(b")
214 ai("class a(b,")
215 ai("class a():")
216
217 ai("[x for")
218 ai("[x for x in")
219 ai("[x for x in (")
220
221 ai("(x for")
222 ai("(x for x in")
223 ai("(x for x in (")
224
225 def test_invalid(self):
226 ai = self.assertInvalid
227 ai("a b")
228
229 ai("a @")
230 ai("a b @")
231 ai("a ** @")
232
233 ai("a = ")
234 ai("a = 9 +")
235
236 ai("def x():\n\npass\n")
237
238 ai("\n\n if 1: pass\n\npass")
239
240 ai("a = 9+ \\\n")
241 ai("a = 'a\\ ")
242 ai("a = 'a\\\n")
243
244 ai("a = 1","eval")
245 ai("]","eval")
246 ai("())","eval")
247 ai("[}","eval")
248 ai("9+","eval")
249 ai("lambda z:","eval")
250 ai("a b","eval")
251
252 ai("return 2.3")
253 ai("if (a == 1 and b = 2): pass")
254
255 ai("del 1")
256 ai("del (1,)")
257 ai("del [1]")
258 ai("del '1'")
259
260 ai("[i for i in range(10)] = (1, 2, 3)")
261
262 def test_invalid_exec(self):
263 ai = self.assertInvalid
264 ai("raise = 4", symbol="exec")
265 ai('def a-b', symbol='exec')
266 ai('await?', symbol='exec')
267 ai('=!=', symbol='exec')
268 ai('a await raise b', symbol='exec')
269 ai('a await raise b?+1', symbol='exec')
270
271 def test_filename(self):
272 self.assertEqual(compile_command("a = 1\n", "abc").co_filename,
273 compile("a = 1\n", "abc", 'single').co_filename)
274 self.assertNotEqual(compile_command("a = 1\n", "abc").co_filename,
275 compile("a = 1\n", "def", 'single').co_filename)
276
277 def test_warning(self):
278 # Test that the warning is only returned once.
279 with warnings_helper.check_warnings(
280 ('"is" with \'str\' literal', SyntaxWarning),
281 ("invalid escape sequence", SyntaxWarning),
282 ) as w:
283 compile_command(r"'\e' is 0")
284 self.assertEqual(len(w.warnings), 2)
285
286 # bpo-41520: check SyntaxWarning treated as an SyntaxError
287 with warnings.catch_warnings(), self.assertRaises(SyntaxError):
288 warnings.simplefilter('error', SyntaxWarning)
289 compile_command('1 is 1', symbol='exec')
290
291 # Check SyntaxWarning treated as an SyntaxError
292 with warnings.catch_warnings(), self.assertRaises(SyntaxError):
293 warnings.simplefilter('error', SyntaxWarning)
294 compile_command(r"'\e'", symbol='exec')
295
296 def test_incomplete_warning(self):
297 with warnings.catch_warnings(record=True) as w:
298 warnings.simplefilter('always')
299 self.assertIncomplete("'\\e' + (")
300 self.assertEqual(w, [])
301
302 def test_invalid_warning(self):
303 with warnings.catch_warnings(record=True) as w:
304 warnings.simplefilter('always')
305 self.assertInvalid("'\\e' 1")
306 self.assertEqual(len(w), 1)
307 self.assertEqual(w[0].category, SyntaxWarning)
308 self.assertRegex(str(w[0].message), 'invalid escape sequence')
309 self.assertEqual(w[0].filename, '<input>')
310
311
312 if __name__ == "__main__":
313 unittest.main()