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