1""" 2Test the API of the symtable module. 3""" 4import symtable 5import unittest 6 7from test import test_support 8 9 10TEST_CODE = """ 11import sys 12 13glob = 42 14 15class Mine: 16 instance_var = 24 17 def a_method(p1, p2): 18 pass 19 20def spam(a, b, *var, **kw): 21 global bar 22 bar = 47 23 x = 23 24 glob 25 def internal(): 26 return x 27 return internal 28 29def foo(): 30 exec 'm' 31 from sys import * 32 33def namespace_test(): pass 34def namespace_test(): pass 35""" 36 37 38def find_block(block, name): 39 for ch in block.get_children(): 40 if ch.get_name() == name: 41 return ch 42 43 44class SymtableTest(unittest.TestCase): 45 46 with test_support.check_warnings( 47 ("import \* only allowed at module level", SyntaxWarning)): 48 top = symtable.symtable(TEST_CODE, "?", "exec") 49 # These correspond to scopes in TEST_CODE 50 Mine = find_block(top, "Mine") 51 a_method = find_block(Mine, "a_method") 52 spam = find_block(top, "spam") 53 internal = find_block(spam, "internal") 54 foo = find_block(top, "foo") 55 56 def test_type(self): 57 self.assertEqual(self.top.get_type(), "module") 58 self.assertEqual(self.Mine.get_type(), "class") 59 self.assertEqual(self.a_method.get_type(), "function") 60 self.assertEqual(self.spam.get_type(), "function") 61 self.assertEqual(self.internal.get_type(), "function") 62 63 def test_optimized(self): 64 self.assertFalse(self.top.is_optimized()) 65 self.assertFalse(self.top.has_exec()) 66 self.assertFalse(self.top.has_import_star()) 67 68 self.assertTrue(self.spam.is_optimized()) 69 70 self.assertFalse(self.foo.is_optimized()) 71 self.assertTrue(self.foo.has_exec()) 72 self.assertTrue(self.foo.has_import_star()) 73 74 def test_nested(self): 75 self.assertFalse(self.top.is_nested()) 76 self.assertFalse(self.Mine.is_nested()) 77 self.assertFalse(self.spam.is_nested()) 78 self.assertTrue(self.internal.is_nested()) 79 80 def test_children(self): 81 self.assertTrue(self.top.has_children()) 82 self.assertTrue(self.Mine.has_children()) 83 self.assertFalse(self.foo.has_children()) 84 85 def test_lineno(self): 86 self.assertEqual(self.top.get_lineno(), 0) 87 self.assertEqual(self.spam.get_lineno(), 11) 88 89 def test_function_info(self): 90 func = self.spam 91 self.assertEqual(sorted(func.get_parameters()), ["a", "b", "kw", "var"]) 92 expected = ["a", "b", "internal", "kw", "var", "x"] 93 self.assertEqual(sorted(func.get_locals()), expected) 94 self.assertEqual(sorted(func.get_globals()), ["bar", "glob"]) 95 self.assertEqual(self.internal.get_frees(), ("x",)) 96 97 def test_globals(self): 98 self.assertTrue(self.spam.lookup("glob").is_global()) 99 self.assertFalse(self.spam.lookup("glob").is_declared_global()) 100 self.assertTrue(self.spam.lookup("bar").is_global()) 101 self.assertTrue(self.spam.lookup("bar").is_declared_global()) 102 self.assertFalse(self.internal.lookup("x").is_global()) 103 self.assertFalse(self.Mine.lookup("instance_var").is_global()) 104 105 def test_local(self): 106 self.assertTrue(self.spam.lookup("x").is_local()) 107 self.assertFalse(self.internal.lookup("x").is_local()) 108 109 def test_referenced(self): 110 self.assertTrue(self.internal.lookup("x").is_referenced()) 111 self.assertTrue(self.spam.lookup("internal").is_referenced()) 112 self.assertFalse(self.spam.lookup("x").is_referenced()) 113 114 def test_parameters(self): 115 for sym in ("a", "var", "kw"): 116 self.assertTrue(self.spam.lookup(sym).is_parameter()) 117 self.assertFalse(self.spam.lookup("x").is_parameter()) 118 119 def test_symbol_lookup(self): 120 self.assertEqual(len(self.top.get_identifiers()), 121 len(self.top.get_symbols())) 122 123 self.assertRaises(KeyError, self.top.lookup, "not_here") 124 125 def test_namespaces(self): 126 self.assertTrue(self.top.lookup("Mine").is_namespace()) 127 self.assertTrue(self.Mine.lookup("a_method").is_namespace()) 128 self.assertTrue(self.top.lookup("spam").is_namespace()) 129 self.assertTrue(self.spam.lookup("internal").is_namespace()) 130 self.assertTrue(self.top.lookup("namespace_test").is_namespace()) 131 self.assertFalse(self.spam.lookup("x").is_namespace()) 132 133 self.assertTrue(self.top.lookup("spam").get_namespace() is self.spam) 134 ns_test = self.top.lookup("namespace_test") 135 self.assertEqual(len(ns_test.get_namespaces()), 2) 136 self.assertRaises(ValueError, ns_test.get_namespace) 137 138 def test_assigned(self): 139 self.assertTrue(self.spam.lookup("x").is_assigned()) 140 self.assertTrue(self.spam.lookup("bar").is_assigned()) 141 self.assertTrue(self.top.lookup("spam").is_assigned()) 142 self.assertTrue(self.Mine.lookup("a_method").is_assigned()) 143 self.assertFalse(self.internal.lookup("x").is_assigned()) 144 145 def test_imported(self): 146 self.assertTrue(self.top.lookup("sys").is_imported()) 147 148 def test_name(self): 149 self.assertEqual(self.top.get_name(), "top") 150 self.assertEqual(self.spam.get_name(), "spam") 151 self.assertEqual(self.spam.lookup("x").get_name(), "x") 152 self.assertEqual(self.Mine.get_name(), "Mine") 153 154 def test_class_info(self): 155 self.assertEqual(self.Mine.get_methods(), ('a_method',)) 156 157 def test_filename_correct(self): 158 ### Bug tickler: SyntaxError file name correct whether error raised 159 ### while parsing or building symbol table. 160 def checkfilename(brokencode): 161 try: 162 symtable.symtable(brokencode, "spam", "exec") 163 except SyntaxError as e: 164 self.assertEqual(e.filename, "spam") 165 else: 166 self.fail("no SyntaxError for %r" % (brokencode,)) 167 checkfilename("def f(x): foo)(") # parse-time 168 checkfilename("def f(x): global x") # symtable-build-time 169 170 def test_eval(self): 171 symbols = symtable.symtable("42", "?", "eval") 172 173 def test_single(self): 174 symbols = symtable.symtable("42", "?", "single") 175 176 def test_exec(self): 177 symbols = symtable.symtable("def f(x): return x", "?", "exec") 178 179 180def test_main(): 181 test_support.run_unittest(SymtableTest) 182 183if __name__ == '__main__': 184 test_main() 185