def lib2to3_parse( src_txt: str, target_versions: Iterable[TargetVersion] = ()) -> Node: """Given a string with source, return the lib2to3 Node.""" if not src_txt.endswith("\n"): src_txt += "\n" for grammar in get_grammars(set(target_versions)): drv = driver.Driver(grammar, pytree.convert) try: result = drv.parse_string(src_txt, True) break except ParseError as pe: lineno, column = pe.context[1] lines = src_txt.splitlines() try: faulty_line = lines[lineno - 1] except IndexError: faulty_line = "<line number missing in source>" exc = InvalidInput( f"Cannot parse: {lineno}:{column}: {faulty_line}") else: raise exc from None if isinstance(result, Leaf): result = Node(syms.file_input, [result]) return result
def matches_grammar(src_txt: str, grammar: Grammar) -> bool: drv = driver.Driver(grammar) try: drv.parse_string(src_txt, True) except (ParseError, TokenError, IndentationError): return False else: return True
def lib2to3_parse( src_txt: str, target_versions: Iterable[TargetVersion] = ()) -> Node: """Given a string with source, return the lib2to3 Node.""" if not src_txt.endswith("\n"): src_txt += "\n" grammars = get_grammars(set(target_versions)) errors = {} for grammar in grammars: drv = driver.Driver(grammar) try: result = drv.parse_string(src_txt, True) break except ParseError as pe: lineno, column = pe.context[1] lines = src_txt.splitlines() try: faulty_line = lines[lineno - 1] except IndexError: faulty_line = "<line number missing in source>" errors[grammar.version] = InvalidInput( f"Cannot parse: {lineno}:{column}: {faulty_line}") except TokenError as te: # In edge cases these are raised; and typically don't have a "faulty_line". lineno, column = te.args[1] errors[grammar.version] = InvalidInput( f"Cannot parse: {lineno}:{column}: {te.args[0]}") else: # Choose the latest version when raising the actual parsing error. assert len(errors) >= 1 exc = errors[max(errors)] if matches_grammar(src_txt, pygram.python_grammar) or matches_grammar( src_txt, pygram.python_grammar_no_print_statement): original_msg = exc.args[0] msg = f"{original_msg}\n{PY2_HINT}" raise InvalidInput(msg) from None raise exc from None if isinstance(result, Leaf): result = Node(syms.file_input, [result]) return result
def lib2to3_parse(src_txt: str) -> Node: """Given a string with source, return the lib2to3 Node.""" grammar = pygram.python_grammar_no_print_statement drv = driver.Driver(grammar, pytree.convert) if src_txt[-1] != '\n': nl = '\r\n' if '\r\n' in src_txt[:1024] else '\n' src_txt += nl try: result = drv.parse_string(src_txt, True) except ParseError as pe: lineno, column = pe.context[1] lines = src_txt.splitlines() try: faulty_line = lines[lineno - 1] except IndexError: faulty_line = "<line number missing in source>" raise ValueError(f"Cannot parse: {lineno}:{column}: {faulty_line}") from None if isinstance(result, Leaf): result = Node(syms.file_input, [result]) return result