test_compile.py revision 28746aba9bf636d03eb1c1c5f4550c6f2dbf5300
1import unittest 2import warnings 3import sys 4from test import test_support 5 6class TestSpecifics(unittest.TestCase): 7 8 def test_debug_assignment(self): 9 # catch assignments to __debug__ 10 self.assertRaises(SyntaxError, compile, '__debug__ = 1', '?', 'single') 11 import __builtin__ 12 prev = __builtin__.__debug__ 13 setattr(__builtin__, '__debug__', 'sure') 14 setattr(__builtin__, '__debug__', prev) 15 16 def test_argument_handling(self): 17 # detect duplicate positional and keyword arguments 18 self.assertRaises(SyntaxError, eval, 'lambda a,a:0') 19 self.assertRaises(SyntaxError, eval, 'lambda a,a=1:0') 20 self.assertRaises(SyntaxError, eval, 'lambda a=1,a=1:0') 21 try: 22 exec 'def f(a, a): pass' 23 self.fail("duplicate arguments") 24 except SyntaxError: 25 pass 26 try: 27 exec 'def f(a = 0, a = 1): pass' 28 self.fail("duplicate keyword arguments") 29 except SyntaxError: 30 pass 31 try: 32 exec 'def f(a): global a; a = 1' 33 self.fail("variable is global and local") 34 except SyntaxError: 35 pass 36 37 def test_syntax_error(self): 38 self.assertRaises(SyntaxError, compile, "1+*3", "filename", "exec") 39 40 def test_duplicate_global_local(self): 41 try: 42 exec 'def f(a): global a; a = 1' 43 self.fail("variable is global and local") 44 except SyntaxError: 45 pass 46 47 def test_exec_with_general_mapping_for_locals(self): 48 49 class M: 50 "Test mapping interface versus possible calls from eval()." 51 def __getitem__(self, key): 52 if key == 'a': 53 return 12 54 raise KeyError 55 def __setitem__(self, key, value): 56 self.results = (key, value) 57 def keys(self): 58 return list('xyz') 59 60 m = M() 61 g = globals() 62 exec 'z = a' in g, m 63 self.assertEqual(m.results, ('z', 12)) 64 try: 65 exec 'z = b' in g, m 66 except NameError: 67 pass 68 else: 69 self.fail('Did not detect a KeyError') 70 exec 'z = dir()' in g, m 71 self.assertEqual(m.results, ('z', list('xyz'))) 72 exec 'z = globals()' in g, m 73 self.assertEqual(m.results, ('z', g)) 74 exec 'z = locals()' in g, m 75 self.assertEqual(m.results, ('z', m)) 76 try: 77 exec 'z = b' in m 78 except TypeError: 79 pass 80 else: 81 self.fail('Did not validate globals as a real dict') 82 83 class A: 84 "Non-mapping" 85 pass 86 m = A() 87 try: 88 exec 'z = a' in g, m 89 except TypeError: 90 pass 91 else: 92 self.fail('Did not validate locals as a mapping') 93 94 # Verify that dict subclasses work as well 95 class D(dict): 96 def __getitem__(self, key): 97 if key == 'a': 98 return 12 99 return dict.__getitem__(self, key) 100 d = D() 101 exec 'z = a' in g, d 102 self.assertEqual(d['z'], 12) 103 104 def test_extended_arg(self): 105 longexpr = 'x = x or ' + '-x' * 2500 106 code = ''' 107def f(x): 108 %s 109 %s 110 %s 111 %s 112 %s 113 %s 114 %s 115 %s 116 %s 117 %s 118 # the expressions above have no effect, x == argument 119 while x: 120 x -= 1 121 # EXTENDED_ARG/JUMP_ABSOLUTE here 122 return x 123''' % ((longexpr,)*10) 124 exec code 125 self.assertEqual(f(5), 0) 126 127 def test_complex_args(self): 128 129 def comp_args((a, b)): 130 return a,b 131 self.assertEqual(comp_args((1, 2)), (1, 2)) 132 133 def comp_args((a, b)=(3, 4)): 134 return a, b 135 self.assertEqual(comp_args((1, 2)), (1, 2)) 136 self.assertEqual(comp_args(), (3, 4)) 137 138 def comp_args(a, (b, c)): 139 return a, b, c 140 self.assertEqual(comp_args(1, (2, 3)), (1, 2, 3)) 141 142 def comp_args(a=2, (b, c)=(3, 4)): 143 return a, b, c 144 self.assertEqual(comp_args(1, (2, 3)), (1, 2, 3)) 145 self.assertEqual(comp_args(), (2, 3, 4)) 146 147 def test_argument_order(self): 148 try: 149 exec 'def f(a=1, (b, c)): pass' 150 self.fail("non-default args after default") 151 except SyntaxError: 152 pass 153 154 def test_float_literals(self): 155 # testing bad float literals 156 self.assertRaises(SyntaxError, eval, "2e") 157 self.assertRaises(SyntaxError, eval, "2.0e+") 158 self.assertRaises(SyntaxError, eval, "1e-") 159 self.assertRaises(SyntaxError, eval, "3-4e/21") 160 161 def test_indentation(self): 162 # testing compile() of indented block w/o trailing newline" 163 s = """ 164if 1: 165 if 2: 166 pass""" 167 compile(s, "<string>", "exec") 168 169 def test_literals_with_leading_zeroes(self): 170 for arg in ["077787", "0xj", "0x.", "0e", "090000000000000", 171 "080000000000000", "000000000000009", "000000000000008"]: 172 self.assertRaises(SyntaxError, eval, arg) 173 174 self.assertEqual(eval("0777"), 511) 175 self.assertEqual(eval("0777L"), 511) 176 self.assertEqual(eval("000777"), 511) 177 self.assertEqual(eval("0xff"), 255) 178 self.assertEqual(eval("0xffL"), 255) 179 self.assertEqual(eval("0XfF"), 255) 180 self.assertEqual(eval("0777."), 777) 181 self.assertEqual(eval("0777.0"), 777) 182 self.assertEqual(eval("000000000000000000000000000000000000000000000000000777e0"), 777) 183 self.assertEqual(eval("0777e1"), 7770) 184 self.assertEqual(eval("0e0"), 0) 185 self.assertEqual(eval("0000E-012"), 0) 186 self.assertEqual(eval("09.5"), 9.5) 187 self.assertEqual(eval("0777j"), 777j) 188 self.assertEqual(eval("00j"), 0j) 189 self.assertEqual(eval("00.0"), 0) 190 self.assertEqual(eval("0e3"), 0) 191 self.assertEqual(eval("090000000000000."), 90000000000000.) 192 self.assertEqual(eval("090000000000000.0000000000000000000000"), 90000000000000.) 193 self.assertEqual(eval("090000000000000e0"), 90000000000000.) 194 self.assertEqual(eval("090000000000000e-0"), 90000000000000.) 195 self.assertEqual(eval("090000000000000j"), 90000000000000j) 196 self.assertEqual(eval("000000000000007"), 7) 197 self.assertEqual(eval("000000000000008."), 8.) 198 self.assertEqual(eval("000000000000009."), 9.) 199 200 def test_unary_minus(self): 201 # Verify treatment of unary minus on negative numbers SF bug #660455 202 if sys.maxint == 2147483647: 203 # 32-bit machine 204 all_one_bits = '0xffffffff' 205 self.assertEqual(eval(all_one_bits), 4294967295L) 206 self.assertEqual(eval("-" + all_one_bits), -4294967295L) 207 elif sys.maxint == 9223372036854775807: 208 # 64-bit machine 209 all_one_bits = '0xffffffffffffffff' 210 self.assertEqual(eval(all_one_bits), 18446744073709551615L) 211 self.assertEqual(eval("-" + all_one_bits), -18446744073709551615L) 212 else: 213 self.fail("How many bits *does* this machine have???") 214 # Verify treatment of contant folding on -(sys.maxint+1) 215 # i.e. -2147483648 on 32 bit platforms. Should return int, not long. 216 self.assertTrue(isinstance(eval("%s" % (-sys.maxint - 1)), int)) 217 self.assertTrue(isinstance(eval("%s" % (-sys.maxint - 2)), long)) 218 219 if sys.maxint == 9223372036854775807: 220 def test_32_63_bit_values(self): 221 a = +4294967296 # 1 << 32 222 b = -4294967296 # 1 << 32 223 c = +281474976710656 # 1 << 48 224 d = -281474976710656 # 1 << 48 225 e = +4611686018427387904 # 1 << 62 226 f = -4611686018427387904 # 1 << 62 227 g = +9223372036854775807 # 1 << 63 - 1 228 h = -9223372036854775807 # 1 << 63 - 1 229 230 for variable in self.test_32_63_bit_values.func_code.co_consts: 231 if variable is not None: 232 self.assertTrue(isinstance(variable, int)) 233 234 def test_sequence_unpacking_error(self): 235 # Verify sequence packing/unpacking with "or". SF bug #757818 236 i,j = (1, -1) or (-1, 1) 237 self.assertEqual(i, 1) 238 self.assertEqual(j, -1) 239 240 def test_none_assignment(self): 241 stmts = [ 242 'None = 0', 243 'None += 0', 244 '__builtins__.None = 0', 245 'def None(): pass', 246 'class None: pass', 247 '(a, None) = 0, 0', 248 'for None in range(10): pass', 249 'def f(None): pass', 250 ] 251 for stmt in stmts: 252 stmt += "\n" 253 self.assertRaises(SyntaxError, compile, stmt, 'tmp', 'single') 254 self.assertRaises(SyntaxError, compile, stmt, 'tmp', 'exec') 255 256 def test_import(self): 257 succeed = [ 258 'import sys', 259 'import os, sys', 260 'import os as bar', 261 'import os.path as bar', 262 'from __future__ import nested_scopes, generators', 263 'from __future__ import (nested_scopes,\ngenerators)', 264 'from __future__ import (nested_scopes,\ngenerators,)', 265 'from sys import stdin, stderr, stdout', 266 'from sys import (stdin, stderr,\nstdout)', 267 'from sys import (stdin, stderr,\nstdout,)', 268 'from sys import (stdin\n, stderr, stdout)', 269 'from sys import (stdin\n, stderr, stdout,)', 270 'from sys import stdin as si, stdout as so, stderr as se', 271 'from sys import (stdin as si, stdout as so, stderr as se)', 272 'from sys import (stdin as si, stdout as so, stderr as se,)', 273 ] 274 fail = [ 275 'import (os, sys)', 276 'import (os), (sys)', 277 'import ((os), (sys))', 278 'import (sys', 279 'import sys)', 280 'import (os,)', 281 'import os As bar', 282 'import os.path a bar', 283 'from sys import stdin As stdout', 284 'from sys import stdin a stdout', 285 'from (sys) import stdin', 286 'from __future__ import (nested_scopes', 287 'from __future__ import nested_scopes)', 288 'from __future__ import nested_scopes,\ngenerators', 289 'from sys import (stdin', 290 'from sys import stdin)', 291 'from sys import stdin, stdout,\nstderr', 292 'from sys import stdin si', 293 'from sys import stdin,' 294 'from sys import (*)', 295 'from sys import (stdin,, stdout, stderr)', 296 'from sys import (stdin, stdout),', 297 ] 298 for stmt in succeed: 299 compile(stmt, 'tmp', 'exec') 300 for stmt in fail: 301 self.assertRaises(SyntaxError, compile, stmt, 'tmp', 'exec') 302 303 def test_for_distinct_code_objects(self): 304 # SF bug 1048870 305 def f(): 306 f1 = lambda x=1: x 307 f2 = lambda x=2: x 308 return f1, f2 309 f1, f2 = f() 310 self.assertNotEqual(id(f1.func_code), id(f2.func_code)) 311 312 def test_unicode_encoding(self): 313 code = u"# -*- coding: utf-8 -*-\npass\n" 314 self.assertRaises(SyntaxError, compile, code, "tmp", "exec") 315 316 def test_subscripts(self): 317 # SF bug 1448804 318 # Class to make testing subscript results easy 319 class str_map(object): 320 def __init__(self): 321 self.data = {} 322 def __getitem__(self, key): 323 return self.data[str(key)] 324 def __setitem__(self, key, value): 325 self.data[str(key)] = value 326 def __delitem__(self, key): 327 del self.data[str(key)] 328 def __contains__(self, key): 329 return str(key) in self.data 330 d = str_map() 331 # Index 332 d[1] = 1 333 self.assertEqual(d[1], 1) 334 d[1] += 1 335 self.assertEqual(d[1], 2) 336 del d[1] 337 self.assertEqual(1 in d, False) 338 # Tuple of indices 339 d[1, 1] = 1 340 self.assertEqual(d[1, 1], 1) 341 d[1, 1] += 1 342 self.assertEqual(d[1, 1], 2) 343 del d[1, 1] 344 self.assertEqual((1, 1) in d, False) 345 # Simple slice 346 d[1:2] = 1 347 self.assertEqual(d[1:2], 1) 348 d[1:2] += 1 349 self.assertEqual(d[1:2], 2) 350 del d[1:2] 351 self.assertEqual(slice(1, 2) in d, False) 352 # Tuple of simple slices 353 d[1:2, 1:2] = 1 354 self.assertEqual(d[1:2, 1:2], 1) 355 d[1:2, 1:2] += 1 356 self.assertEqual(d[1:2, 1:2], 2) 357 del d[1:2, 1:2] 358 self.assertEqual((slice(1, 2), slice(1, 2)) in d, False) 359 # Extended slice 360 d[1:2:3] = 1 361 self.assertEqual(d[1:2:3], 1) 362 d[1:2:3] += 1 363 self.assertEqual(d[1:2:3], 2) 364 del d[1:2:3] 365 self.assertEqual(slice(1, 2, 3) in d, False) 366 # Tuple of extended slices 367 d[1:2:3, 1:2:3] = 1 368 self.assertEqual(d[1:2:3, 1:2:3], 1) 369 d[1:2:3, 1:2:3] += 1 370 self.assertEqual(d[1:2:3, 1:2:3], 2) 371 del d[1:2:3, 1:2:3] 372 self.assertEqual((slice(1, 2, 3), slice(1, 2, 3)) in d, False) 373 # Ellipsis 374 d[...] = 1 375 self.assertEqual(d[...], 1) 376 d[...] += 1 377 self.assertEqual(d[...], 2) 378 del d[...] 379 self.assertEqual(Ellipsis in d, False) 380 # Tuple of Ellipses 381 d[..., ...] = 1 382 self.assertEqual(d[..., ...], 1) 383 d[..., ...] += 1 384 self.assertEqual(d[..., ...], 2) 385 del d[..., ...] 386 self.assertEqual((Ellipsis, Ellipsis) in d, False) 387 388def test_main(): 389 test_support.run_unittest(TestSpecifics) 390 391if __name__ == "__main__": 392 test_main() 393