def post_process_ast(ast, src, name=None): """Post-process the parsed AST.""" ast = definitions.finalize_ast(ast) ast = ast.Visit(pep484.ConvertTypingToNative(name)) if name: ast = ast.Replace(name=name) ast = ast.Visit(visitors.AddNamePrefix()) else: # If there's no unique name, hash the sourcecode. ast = ast.Replace(name=hashlib.md5(src.encode("utf-8")).hexdigest()) ast = ast.Visit(visitors.StripExternalNamePrefix()) # Now that we have resolved external names, process any class decorators that # do code generation. try: ast = ast.Visit(decorate.DecorateClassVisitor()) except TypeError as e: # Convert errors into ParseError. Unfortunately we no longer have location # information if an error is raised during transformation of a class node. raise ParseError.from_exc(e) # Typeshed files that explicitly import and refer to "__builtin__" need to # have that rewritten to builtins ast = ast.Visit(visitors.RenameBuiltinsPrefix()) return ast
def parse(self, src, name, filename): """Parse a PYI file and return the corresponding AST. Note that parse() should be called exactly once per _Parser instance. It holds aggregated state during parsing and is not designed to be reused. Args: src: The source text to parse. name: The name of the module to be created. filename: The name of the source file. Returns: A pytd.TypeDeclUnit() representing the parsed pyi. Raises: ParseError: If the PYI source could not be parsed. """ # Ensure instances do not get reused. assert not self._used self._used = True self._filename = filename self._ast_name = name self._type_map = {} try: defs = parser_ext.parse(self, src) ast = self._build_type_decl_unit(defs) except ParseError as e: if self._error_location: line = e.line or self._error_location[0] try: text = src.splitlines()[line-1] except IndexError: text = None raise ParseError(utils.message(e), line=line, filename=self._filename, column=self._error_location[1], text=text) else: raise e ast = ast.Visit(_PropertyToConstant()) ast = ast.Visit(_InsertTypeParameters()) # TODO(kramm): This is in the wrong place- it should happen after resolving # local names, in load_pytd. ast = ast.Visit(pep484.ConvertTypingToNative(name)) if name: ast = ast.Replace(name=name) ast = ast.Visit(visitors.AddNamePrefix()) else: # If there's no unique name, hash the sourcecode. ast = ast.Replace(name=hashlib.md5(src.encode("utf-8")).hexdigest()) ast = ast.Visit(visitors.StripExternalNamePrefix()) # Typeshed files that explicitly import and refer to "builtins" need to have # that rewritten to __builtin__ ast = ast.Visit(visitors.RenameBuiltinsPrefix()) return ast.Replace(is_package=utils.is_pyi_directory_init(filename))
def post_process_ast(ast, src, name=None): """Post-process the parsed AST.""" ast = definitions.finalize_ast(ast) ast = ast.Visit(pep484.ConvertTypingToNative(name)) if name: ast = ast.Replace(name=name) ast = ast.Visit(visitors.AddNamePrefix()) else: # If there's no unique name, hash the sourcecode. ast = ast.Replace(name=hashlib.md5(src.encode("utf-8")).hexdigest()) ast = ast.Visit(visitors.StripExternalNamePrefix()) # Typeshed files that explicitly import and refer to "__builtin__" need to # have that rewritten to builtins return ast.Visit(visitors.RenameBuiltinsPrefix())
def post_process_ast(ast, src, name=None): """Post-process the parsed AST.""" ast = definitions.finalize_ast(ast) ast = ast.Visit(pep484.ConvertTypingToNative(name)) if name: ast = ast.Replace(name=name) ast = ast.Visit(visitors.AddNamePrefix()) else: # If there's no unique name, hash the sourcecode. ast = ast.Replace(name=hashlib.md5(src.encode("utf-8")).hexdigest()) ast = ast.Visit(visitors.StripExternalNamePrefix()) # Now that we have resolved external names, validate any class decorators that # do code generation. (We will generate the class lazily, but we should check # for errors at parse time so they can be reported early.) try: ast = ast.Visit(decorate.ValidateDecoratedClassVisitor()) except TypeError as e: # Convert errors into ParseError. Unfortunately we no longer have location # information if an error is raised during transformation of a class node. raise ParseError.from_exc(e) return ast