Given a string with source, return the lib2to3 Node.
(
src_txt: str, target_versions: Collection[TargetVersion] = ()
)
| 53 | |
| 54 | |
| 55 | def lib2to3_parse( |
| 56 | src_txt: str, target_versions: Collection[TargetVersion] = () |
| 57 | ) -> Node: |
| 58 | """Given a string with source, return the lib2to3 Node.""" |
| 59 | if not src_txt.endswith("\n"): |
| 60 | src_txt += "\n" |
| 61 | |
| 62 | grammars = get_grammars(set(target_versions)) |
| 63 | if target_versions: |
| 64 | max_tv = max(target_versions, key=lambda tv: tv.value) |
| 65 | tv_str = f" for target version {max_tv.pretty()}" |
| 66 | else: |
| 67 | tv_str = "" |
| 68 | |
| 69 | errors = {} |
| 70 | for grammar in grammars: |
| 71 | drv = driver.Driver(grammar) |
| 72 | try: |
| 73 | result = drv.parse_string(src_txt, False) |
| 74 | break |
| 75 | |
| 76 | except ParseError as pe: |
| 77 | lineno, column = pe.context[1] |
| 78 | lines = src_txt.splitlines() |
| 79 | try: |
| 80 | faulty_line = lines[lineno - 1] |
| 81 | except IndexError: |
| 82 | faulty_line = "<line number missing in source>" |
| 83 | error_msg = ( |
| 84 | f"Cannot parse{tv_str}: {lineno}:{column}\n" |
| 85 | f" {faulty_line}\n" |
| 86 | f" {' ' * (column - 1)}^\n" |
| 87 | f"ParseError: {pe.msg}" |
| 88 | ) |
| 89 | |
| 90 | errors[grammar.version] = InvalidInput(error_msg) |
| 91 | |
| 92 | except TokenError as te: |
| 93 | lineno, column = te.args[1] |
| 94 | lines = src_txt.splitlines() |
| 95 | try: |
| 96 | faulty_line = lines[lineno - 1] |
| 97 | except IndexError: |
| 98 | faulty_line = "<line number missing in source>" |
| 99 | error_msg = ( |
| 100 | f"Cannot parse{tv_str}: {lineno}:{column}\n" |
| 101 | f" {faulty_line}\n" |
| 102 | f" {' ' * (column - 1)}^\n" |
| 103 | f"TokenError: {te.args[0]}" |
| 104 | ) |
| 105 | errors[grammar.version] = InvalidInput(error_msg) |
| 106 | |
| 107 | else: |
| 108 | # Choose the latest version when raising the actual parsing error. |
| 109 | assert len(errors) >= 1 |
| 110 | exc = errors[max(errors)] |
| 111 | raise exc from None |
| 112 |
no test coverage detected