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_utils.Print(ast1).strip() + "\n" src2 = pytd_utils.Print(ast2).strip() + "\n" # Verify printed versions are the same and ASTs are the same. ast1 = ast1.Visit(visitors.ClassTypeToNamedType()) ast2 = ast2.Visit(visitors.ClassTypeToNamedType()) if src1 != src2 or not pytd_utils.ASTeq(ast1, 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) # pylint: disable=invalid-name self.assertMultiLineEqual(src1, src2) else: sys.stdout.flush() sys.stderr.flush() print("Source files or ASTs differ:", file=sys.stderr) print("-" * 36, " Actual ", "-" * 36, file=sys.stderr) print(textwrap.dedent(src1).strip(), file=sys.stderr) print("-" * 36, "Expected", "-" * 36, file=sys.stderr) print(textwrap.dedent(src2).strip(), file=sys.stderr) print("-" * 80, file=sys.stderr) if not pytd_utils.ASTeq(ast1, ast2): print("Actual AST:", ast1, file=sys.stderr) print("Expect AST:", ast2, file=sys.stderr) self.fail("source files differ")
def assertTypesMatchPytd(self, ty, pytd_src): """Parses pytd_src and compares with ty.""" pytd_tree = parser.parse_string( textwrap.dedent(pytd_src), options=parser.PyiOptions(python_version=self.python_version)) pytd_tree = pytd_tree.Visit( visitors.LookupBuiltins(self.loader.builtins, 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()) ty = ty.Visit(visitors.CanonicalOrderingVisitor(sort_signatures=True)) ty.Visit(visitors.VerifyVisitor()) ty_src = pytd_utils.Print(ty) + "\n" pytd_tree_src = pytd_utils.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 canonical_pyi(pyi, multiline_args=False, options=None): """Rewrite a pyi in canonical form.""" ast = parse_string(pyi, options=options) ast = ast.Visit(visitors.ClassTypeToNamedType()) ast = ast.Visit(visitors.CanonicalOrderingVisitor(sort_signatures=True)) ast.Visit(visitors.VerifyVisitor()) return pytd_utils.Print(ast, multiline_args)
def Parse(self, src, name=None, version=None, platform=None): version = version or self.PYTHON_VERSION 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 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_utils.Print(result)) log.info("=========== solve result (end) =============") return result
def Parse(self, src, name=None, version=None, platform=None): if version: self.options.python_version = version if platform: self.options.platform = platform tree = parser.parse_string( textwrap.dedent(src), name=name, options=self.options) 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, multiline_args=False): 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 Print(ast, multiline_args)