14710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"""
24710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmTest the API of the symtable module.
34710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"""
44710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport symtable
54710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport unittest
64710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
74710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfrom test import test_support
84710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
94710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmTEST_CODE = """
114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport sys
124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmglob = 42
144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass Mine:
164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    instance_var = 24
174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def a_method(p1, p2):
184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        pass
194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef spam(a, b, *var, **kw):
214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    global bar
224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    bar = 47
234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    x = 23
244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    glob
254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def internal():
264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return x
274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return internal
284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef foo():
304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    exec 'm'
314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    from sys import *
324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef namespace_test(): pass
344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef namespace_test(): pass
354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"""
364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef find_block(block, name):
394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    for ch in block.get_children():
404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if ch.get_name() == name:
414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return ch
424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass SymtableTest(unittest.TestCase):
454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    with test_support.check_warnings(
474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            ("import \* only allowed at module level", SyntaxWarning)):
484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        top = symtable.symtable(TEST_CODE, "?", "exec")
494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    # These correspond to scopes in TEST_CODE
504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Mine = find_block(top, "Mine")
514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    a_method = find_block(Mine, "a_method")
524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    spam = find_block(top, "spam")
534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    internal = find_block(spam, "internal")
544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    foo = find_block(top, "foo")
554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_type(self):
574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(self.top.get_type(), "module")
584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(self.Mine.get_type(), "class")
594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(self.a_method.get_type(), "function")
604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(self.spam.get_type(), "function")
614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(self.internal.get_type(), "function")
624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_optimized(self):
644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertFalse(self.top.is_optimized())
654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertFalse(self.top.has_exec())
664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertFalse(self.top.has_import_star())
674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(self.spam.is_optimized())
694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertFalse(self.foo.is_optimized())
714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(self.foo.has_exec())
724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(self.foo.has_import_star())
734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_nested(self):
754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertFalse(self.top.is_nested())
764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertFalse(self.Mine.is_nested())
774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertFalse(self.spam.is_nested())
784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(self.internal.is_nested())
794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_children(self):
814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(self.top.has_children())
824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(self.Mine.has_children())
834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertFalse(self.foo.has_children())
844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_lineno(self):
864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(self.top.get_lineno(), 0)
874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(self.spam.get_lineno(), 11)
884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_function_info(self):
904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        func = self.spam
914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(func.get_parameters(), ("a", "b", "kw", "var"))
924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(func.get_locals(),
934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         ("a", "b", "internal", "kw", "var", "x"))
944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(func.get_globals(), ("bar", "glob"))
954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(self.internal.get_frees(), ("x",))
964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_globals(self):
984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(self.spam.lookup("glob").is_global())
994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertFalse(self.spam.lookup("glob").is_declared_global())
1004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(self.spam.lookup("bar").is_global())
1014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(self.spam.lookup("bar").is_declared_global())
1024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertFalse(self.internal.lookup("x").is_global())
1034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertFalse(self.Mine.lookup("instance_var").is_global())
1044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_local(self):
1064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(self.spam.lookup("x").is_local())
1074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertFalse(self.internal.lookup("x").is_local())
1084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_referenced(self):
1104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(self.internal.lookup("x").is_referenced())
1114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(self.spam.lookup("internal").is_referenced())
1124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertFalse(self.spam.lookup("x").is_referenced())
1134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_parameters(self):
1154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for sym in ("a", "var", "kw"):
1164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertTrue(self.spam.lookup(sym).is_parameter())
1174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertFalse(self.spam.lookup("x").is_parameter())
1184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_symbol_lookup(self):
1204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(len(self.top.get_identifiers()),
1214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         len(self.top.get_symbols()))
1224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(KeyError, self.top.lookup, "not_here")
1244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_namespaces(self):
1264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(self.top.lookup("Mine").is_namespace())
1274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(self.Mine.lookup("a_method").is_namespace())
1284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(self.top.lookup("spam").is_namespace())
1294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(self.spam.lookup("internal").is_namespace())
1304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(self.top.lookup("namespace_test").is_namespace())
1314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertFalse(self.spam.lookup("x").is_namespace())
1324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(self.top.lookup("spam").get_namespace() is self.spam)
1344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        ns_test = self.top.lookup("namespace_test")
1354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(len(ns_test.get_namespaces()), 2)
1364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(ValueError, ns_test.get_namespace)
1374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_assigned(self):
1394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(self.spam.lookup("x").is_assigned())
1404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(self.spam.lookup("bar").is_assigned())
1414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(self.top.lookup("spam").is_assigned())
1424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(self.Mine.lookup("a_method").is_assigned())
1434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertFalse(self.internal.lookup("x").is_assigned())
1444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_imported(self):
1464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(self.top.lookup("sys").is_imported())
1474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_name(self):
1494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(self.top.get_name(), "top")
1504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(self.spam.get_name(), "spam")
1514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(self.spam.lookup("x").get_name(), "x")
1524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(self.Mine.get_name(), "Mine")
1534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_class_info(self):
1554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(self.Mine.get_methods(), ('a_method',))
1564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_filename_correct(self):
1584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        ### Bug tickler: SyntaxError file name correct whether error raised
1594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        ### while parsing or building symbol table.
1604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def checkfilename(brokencode):
1614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try:
1624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                symtable.symtable(brokencode, "spam", "exec")
1634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            except SyntaxError as e:
1644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.assertEqual(e.filename, "spam")
1654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else:
1664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.fail("no SyntaxError for %r" % (brokencode,))
1674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        checkfilename("def f(x): foo)(")  # parse-time
1684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        checkfilename("def f(x): global x")  # symtable-build-time
1694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_eval(self):
1714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        symbols = symtable.symtable("42", "?", "eval")
1724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_single(self):
1744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        symbols = symtable.symtable("42", "?", "single")
1754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_exec(self):
1774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        symbols = symtable.symtable("def f(x): return x", "?", "exec")
1784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef test_main():
1814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    test_support.run_unittest(SymtableTest)
1824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmif __name__ == '__main__':
1844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    test_main()
185