17db96d56Sopenharmony_ci"""Tests for the asdl parser in Parser/asdl.py""" 27db96d56Sopenharmony_ci 37db96d56Sopenharmony_ciimport importlib.machinery 47db96d56Sopenharmony_ciimport importlib.util 57db96d56Sopenharmony_ciimport os 67db96d56Sopenharmony_cifrom os.path import dirname 77db96d56Sopenharmony_ciimport sys 87db96d56Sopenharmony_ciimport sysconfig 97db96d56Sopenharmony_ciimport unittest 107db96d56Sopenharmony_ci 117db96d56Sopenharmony_ci 127db96d56Sopenharmony_ci# This test is only relevant for from-source builds of Python. 137db96d56Sopenharmony_ciif not sysconfig.is_python_build(): 147db96d56Sopenharmony_ci raise unittest.SkipTest('test irrelevant for an installed Python') 157db96d56Sopenharmony_ci 167db96d56Sopenharmony_cisrc_base = dirname(dirname(dirname(__file__))) 177db96d56Sopenharmony_ciparser_dir = os.path.join(src_base, 'Parser') 187db96d56Sopenharmony_ci 197db96d56Sopenharmony_ci 207db96d56Sopenharmony_ciclass TestAsdlParser(unittest.TestCase): 217db96d56Sopenharmony_ci @classmethod 227db96d56Sopenharmony_ci def setUpClass(cls): 237db96d56Sopenharmony_ci # Loads the asdl module dynamically, since it's not in a real importable 247db96d56Sopenharmony_ci # package. 257db96d56Sopenharmony_ci # Parses Python.asdl into an ast.Module and run the check on it. 267db96d56Sopenharmony_ci # There's no need to do this for each test method, hence setUpClass. 277db96d56Sopenharmony_ci sys.path.insert(0, parser_dir) 287db96d56Sopenharmony_ci loader = importlib.machinery.SourceFileLoader( 297db96d56Sopenharmony_ci 'asdl', os.path.join(parser_dir, 'asdl.py')) 307db96d56Sopenharmony_ci spec = importlib.util.spec_from_loader('asdl', loader) 317db96d56Sopenharmony_ci module = importlib.util.module_from_spec(spec) 327db96d56Sopenharmony_ci loader.exec_module(module) 337db96d56Sopenharmony_ci cls.asdl = module 347db96d56Sopenharmony_ci cls.mod = cls.asdl.parse(os.path.join(parser_dir, 'Python.asdl')) 357db96d56Sopenharmony_ci cls.assertTrue(cls.asdl.check(cls.mod), 'Module validation failed') 367db96d56Sopenharmony_ci 377db96d56Sopenharmony_ci @classmethod 387db96d56Sopenharmony_ci def tearDownClass(cls): 397db96d56Sopenharmony_ci del sys.path[0] 407db96d56Sopenharmony_ci 417db96d56Sopenharmony_ci def setUp(self): 427db96d56Sopenharmony_ci # alias stuff from the class, for convenience 437db96d56Sopenharmony_ci self.asdl = TestAsdlParser.asdl 447db96d56Sopenharmony_ci self.mod = TestAsdlParser.mod 457db96d56Sopenharmony_ci self.types = self.mod.types 467db96d56Sopenharmony_ci 477db96d56Sopenharmony_ci def test_module(self): 487db96d56Sopenharmony_ci self.assertEqual(self.mod.name, 'Python') 497db96d56Sopenharmony_ci self.assertIn('stmt', self.types) 507db96d56Sopenharmony_ci self.assertIn('expr', self.types) 517db96d56Sopenharmony_ci self.assertIn('mod', self.types) 527db96d56Sopenharmony_ci 537db96d56Sopenharmony_ci def test_definitions(self): 547db96d56Sopenharmony_ci defs = self.mod.dfns 557db96d56Sopenharmony_ci self.assertIsInstance(defs[0], self.asdl.Type) 567db96d56Sopenharmony_ci self.assertIsInstance(defs[0].value, self.asdl.Sum) 577db96d56Sopenharmony_ci 587db96d56Sopenharmony_ci self.assertIsInstance(self.types['withitem'], self.asdl.Product) 597db96d56Sopenharmony_ci self.assertIsInstance(self.types['alias'], self.asdl.Product) 607db96d56Sopenharmony_ci 617db96d56Sopenharmony_ci def test_product(self): 627db96d56Sopenharmony_ci alias = self.types['alias'] 637db96d56Sopenharmony_ci self.assertEqual( 647db96d56Sopenharmony_ci str(alias), 657db96d56Sopenharmony_ci 'Product([Field(identifier, name), Field(identifier, asname, opt=True)], ' 667db96d56Sopenharmony_ci '[Field(int, lineno), Field(int, col_offset), ' 677db96d56Sopenharmony_ci 'Field(int, end_lineno, opt=True), Field(int, end_col_offset, opt=True)])') 687db96d56Sopenharmony_ci 697db96d56Sopenharmony_ci def test_attributes(self): 707db96d56Sopenharmony_ci stmt = self.types['stmt'] 717db96d56Sopenharmony_ci self.assertEqual(len(stmt.attributes), 4) 727db96d56Sopenharmony_ci self.assertEqual(repr(stmt.attributes[0]), 'Field(int, lineno)') 737db96d56Sopenharmony_ci self.assertEqual(repr(stmt.attributes[1]), 'Field(int, col_offset)') 747db96d56Sopenharmony_ci self.assertEqual(repr(stmt.attributes[2]), 'Field(int, end_lineno, opt=True)') 757db96d56Sopenharmony_ci self.assertEqual(repr(stmt.attributes[3]), 'Field(int, end_col_offset, opt=True)') 767db96d56Sopenharmony_ci 777db96d56Sopenharmony_ci def test_constructor_fields(self): 787db96d56Sopenharmony_ci ehandler = self.types['excepthandler'] 797db96d56Sopenharmony_ci self.assertEqual(len(ehandler.types), 1) 807db96d56Sopenharmony_ci self.assertEqual(len(ehandler.attributes), 4) 817db96d56Sopenharmony_ci 827db96d56Sopenharmony_ci cons = ehandler.types[0] 837db96d56Sopenharmony_ci self.assertIsInstance(cons, self.asdl.Constructor) 847db96d56Sopenharmony_ci self.assertEqual(len(cons.fields), 3) 857db96d56Sopenharmony_ci 867db96d56Sopenharmony_ci f0 = cons.fields[0] 877db96d56Sopenharmony_ci self.assertEqual(f0.type, 'expr') 887db96d56Sopenharmony_ci self.assertEqual(f0.name, 'type') 897db96d56Sopenharmony_ci self.assertTrue(f0.opt) 907db96d56Sopenharmony_ci 917db96d56Sopenharmony_ci f1 = cons.fields[1] 927db96d56Sopenharmony_ci self.assertEqual(f1.type, 'identifier') 937db96d56Sopenharmony_ci self.assertEqual(f1.name, 'name') 947db96d56Sopenharmony_ci self.assertTrue(f1.opt) 957db96d56Sopenharmony_ci 967db96d56Sopenharmony_ci f2 = cons.fields[2] 977db96d56Sopenharmony_ci self.assertEqual(f2.type, 'stmt') 987db96d56Sopenharmony_ci self.assertEqual(f2.name, 'body') 997db96d56Sopenharmony_ci self.assertFalse(f2.opt) 1007db96d56Sopenharmony_ci self.assertTrue(f2.seq) 1017db96d56Sopenharmony_ci 1027db96d56Sopenharmony_ci def test_visitor(self): 1037db96d56Sopenharmony_ci class CustomVisitor(self.asdl.VisitorBase): 1047db96d56Sopenharmony_ci def __init__(self): 1057db96d56Sopenharmony_ci super().__init__() 1067db96d56Sopenharmony_ci self.names_with_seq = [] 1077db96d56Sopenharmony_ci 1087db96d56Sopenharmony_ci def visitModule(self, mod): 1097db96d56Sopenharmony_ci for dfn in mod.dfns: 1107db96d56Sopenharmony_ci self.visit(dfn) 1117db96d56Sopenharmony_ci 1127db96d56Sopenharmony_ci def visitType(self, type): 1137db96d56Sopenharmony_ci self.visit(type.value) 1147db96d56Sopenharmony_ci 1157db96d56Sopenharmony_ci def visitSum(self, sum): 1167db96d56Sopenharmony_ci for t in sum.types: 1177db96d56Sopenharmony_ci self.visit(t) 1187db96d56Sopenharmony_ci 1197db96d56Sopenharmony_ci def visitConstructor(self, cons): 1207db96d56Sopenharmony_ci for f in cons.fields: 1217db96d56Sopenharmony_ci if f.seq: 1227db96d56Sopenharmony_ci self.names_with_seq.append(cons.name) 1237db96d56Sopenharmony_ci 1247db96d56Sopenharmony_ci v = CustomVisitor() 1257db96d56Sopenharmony_ci v.visit(self.types['mod']) 1267db96d56Sopenharmony_ci self.assertEqual(v.names_with_seq, 1277db96d56Sopenharmony_ci ['Module', 'Module', 'Interactive', 'FunctionType']) 1287db96d56Sopenharmony_ci 1297db96d56Sopenharmony_ci 1307db96d56Sopenharmony_ciif __name__ == '__main__': 1317db96d56Sopenharmony_ci unittest.main() 132