def AssertSourceEquals(self, src_or_tree_1, src_or_tree_2): # Strip leading "\n"s for convenience ast1 = self.ToAST(src_or_tree_1) ast2 = self.ToAST(src_or_tree_2) src1 = pytd.Print(ast1).strip() + "\n" src2 = pytd.Print(ast2).strip() + "\n" # Verify printed versions are the same and ASTs are the same. # TODO(pludemann): Find out why some tests leave confuse NamedType and # ClassType and fix the tests so that this conversion isn't # needed. ast1 = ast1.Visit(visitors.ClassTypeToNamedType()) ast2 = ast2.Visit(visitors.ClassTypeToNamedType()) if src1 != src2 or not ast1.ASTeq(ast2): # Due to differing opinions on the form of debug output, allow an # environment variable to control what output you want. Set # PY_UNITTEST_DIFF to get diff output. if os.getenv("PY_UNITTEST_DIFF"): self.maxDiff = None # for better diff output (assertMultiLineEqual) self.assertMultiLineEqual(src1, src2) else: sys.stdout.flush() sys.stderr.flush() print >> sys.stderr, "Source files or ASTs differ:" print >> sys.stderr, "-" * 36, " Actual ", "-" * 36 print >> sys.stderr, textwrap.dedent(src1).strip() print >> sys.stderr, "-" * 36, "Expected", "-" * 36 print >> sys.stderr, textwrap.dedent(src2).strip() print >> sys.stderr, "-" * 80 if not ast1.ASTeq(ast2): print >> sys.stderr, "Actual AST:", ast1 print >> sys.stderr, "Expect AST:", ast2 self.fail("source files differ")
def assertTypesMatchPytd(self, ty, pytd_src, version=None): """Parses pytd_src and compares with ty.""" # TODO(pludemann): This is a copy of pytd.parse.parser_test_base.Parse() # TODO(pludemann): Consider using the pytd_tree to call # assertHasOnlySignatures (or similar) to guard against the # inferencer adding additional but harmless calls. pytd_tree = parser.TypeDeclParser(version=version).Parse( textwrap.dedent(pytd_src)) pytd_tree = pytd_tree.Visit( visitors.LookupBuiltins(builtins.GetBuiltinsAndTyping()[0])) pytd_tree = pytd_tree.Visit( visitors.ClassTypeToNamedType()) pytd_tree = pytd_tree.Visit( visitors.CanonicalOrderingVisitor(sort_signatures=True)) pytd_tree.Visit(visitors.VerifyVisitor()) ty = ty.Visit(visitors.ClassTypeToNamedType()) ty = ty.Visit(visitors.AdjustSelf(force=True)) ty = ty.Visit(visitors.CanonicalOrderingVisitor(sort_signatures=True)) ty.Visit(visitors.VerifyVisitor()) ty_src = pytd.Print(ty) + "\n" pytd_tree_src = pytd.Print(pytd_tree) + "\n" log.info("========== result ==========") _LogLines(log.info, ty_src) log.info("========== expected ==========") _LogLines(log.info, pytd_tree_src) log.info("==============================") # In the diff output, mark expected with "-" and actual with "+". # (In other words, display a change from "working" to "broken") self.assertMultiLineEqual(pytd_tree_src, ty_src)
def assertTypesMatchPytd(self, ty, pytd_src, version=None): """Parses pytd_src and compares with ty.""" pytd_tree = parser.parse_string(textwrap.dedent(pytd_src), python_version=version) pytd_tree = pytd_tree.Visit( visitors.LookupBuiltins(builtins.GetBuiltinsAndTyping()[0], full_names=False)) pytd_tree = pytd_tree.Visit(visitors.LookupLocalTypes()) pytd_tree = pytd_tree.Visit(visitors.ClassTypeToNamedType()) pytd_tree = pytd_tree.Visit( visitors.CanonicalOrderingVisitor(sort_signatures=True)) pytd_tree.Visit(visitors.VerifyVisitor()) ty = ty.Visit(visitors.ClassTypeToNamedType()) ty = ty.Visit(visitors.AdjustSelf(force=True)) ty = ty.Visit(visitors.CanonicalOrderingVisitor(sort_signatures=True)) ty.Visit(visitors.VerifyVisitor()) ty_src = pytd.Print(ty) + "\n" pytd_tree_src = pytd.Print(pytd_tree) + "\n" log.info("========== result ==========") _LogLines(log.info, ty_src) log.info("========== expected ==========") _LogLines(log.info, pytd_tree_src) log.info("==============================") # In the diff output, mark expected with "-" and actual with "+". # (In other words, display a change from "working" to "broken") self.assertMultiLineEqual(pytd_tree_src, ty_src)
def Parse(self, src, version=None, platform=None): # TODO(kramm): Using self.parser here breaks tests. Why? tree = parser.TypeDeclParser(version=version, platform=platform).Parse( textwrap.dedent(src)) tree = tree.Visit(visitors.NamedTypeToClassType()) tree = visitors.AdjustTypeParameters(tree) # Convert back to named types for easier testing tree = tree.Visit(visitors.ClassTypeToNamedType()) tree.Visit(visitors.VerifyVisitor()) return tree
def convert_pytd(ast, builtins_pytd, protocols_pytd): """Convert pytd with unknowns (structural types) to one with nominal types.""" builtins_pytd = builtins_pytd.Visit(visitors.ClassTypeToNamedType()) mapping, result = solve(ast, builtins_pytd, protocols_pytd) log_info_mapping(mapping) lookup = pytd_utils.Concat(builtins_pytd, result) result = insert_solution(result, mapping, lookup) if log.isEnabledFor(logging.INFO): log.info("=========== solve result =============\n%s", pytd.Print(result)) log.info("=========== solve result (end) =============") return result
def Parse(self, src, name=None, version=None, platform=None): version = version or self.PYTHON_VERSION # TODO(kramm): Using self.parser here breaks tests. Why? tree = parser.parse_string(textwrap.dedent(src), name=name, python_version=version, platform=platform) tree = tree.Visit(visitors.NamedTypeToClassType()) tree = tree.Visit(visitors.AdjustTypeParameters()) # Convert back to named types for easier testing tree = tree.Visit(visitors.ClassTypeToNamedType()) tree.Visit(visitors.VerifyVisitor()) return tree
def canonical_pyi(pyi, python_version): ast = parser.parse_string(pyi, python_version=python_version) ast = ast.Visit(visitors.ClassTypeToNamedType()) ast = ast.Visit(visitors.CanonicalOrderingVisitor(sort_signatures=True)) ast.Visit(visitors.VerifyVisitor()) return pytd.Print(ast)
def canonical_pyi(pyi): ast = parser.TypeDeclParser().Parse(pyi) ast = ast.Visit(visitors.ClassTypeToNamedType()) ast = ast.Visit(visitors.CanonicalOrderingVisitor(sort_signatures=True)) ast.Visit(visitors.VerifyVisitor()) return pytd.Print(ast)