diff options
author | Claudiu Popa <pcmanticore@gmail.com> | 2019-11-26 09:17:10 +0100 |
---|---|---|
committer | Claudiu Popa <pcmanticore@gmail.com> | 2019-11-26 09:17:10 +0100 |
commit | 2cb6818ad5db25fd0f32a193ab90425e7dfcbee0 (patch) | |
tree | 3d8666f65a776dbdd81c61b20b1c6404d09d0582 /astroid | |
parent | 5cdefb0d278dfe80a662156a942472794df5ca67 (diff) | |
download | astroid-git-2cb6818ad5db25fd0f32a193ab90425e7dfcbee0.tar.gz |
Retry parsing a module that has invalid type comments
It is possible for a module to use comments that might be interpreted
as type comments by the `ast` library. We do not want to completely crash on those
invalid type comments.
Close #708
Diffstat (limited to 'astroid')
-rw-r--r-- | astroid/_ast.py | 15 | ||||
-rw-r--r-- | astroid/builder.py | 18 |
2 files changed, 27 insertions, 6 deletions
diff --git a/astroid/_ast.py b/astroid/_ast.py index 2e44c1f1..66c5cf25 100644 --- a/astroid/_ast.py +++ b/astroid/_ast.py @@ -21,7 +21,10 @@ if PY38: FunctionType = namedtuple("FunctionType", ["argtypes", "returns"]) -def _get_parser_module(parse_python_two: bool = False): +def _get_parser_module(parse_python_two=False, type_comments_support=True): + if not type_comments_support: + return ast + if parse_python_two: parser_module = _ast_py2 else: @@ -29,12 +32,14 @@ def _get_parser_module(parse_python_two: bool = False): return parser_module or ast -def _parse(string: str, parse_python_two: bool = False): - parse_module = _get_parser_module(parse_python_two=parse_python_two) +def _parse(string: str, parse_python_two=False, type_comments=True): + parse_module = _get_parser_module( + parse_python_two=parse_python_two, type_comments_support=type_comments + ) parse_func = parse_module.parse - if _ast_py3: + if parse_module is _ast_py3: if PY38: - parse_func = partial(parse_func, type_comments=True) + parse_func = partial(parse_func, type_comments=type_comments) if not parse_python_two: parse_func = partial(parse_func, feature_version=sys.version_info.minor) return parse_func(string) diff --git a/astroid/builder.py b/astroid/builder.py index 34bde0a1..7f30aaeb 100644 --- a/astroid/builder.py +++ b/astroid/builder.py @@ -165,7 +165,7 @@ class AstroidBuilder(raw_building.InspectBuilder): def _data_build(self, data, modname, path): """Build tree node from data and add some informations""" try: - node = _parse(data + "\n") + node = _parse_string(data) except (TypeError, ValueError, SyntaxError) as exc: raise exceptions.AstroidSyntaxError( "Parsing Python code failed:\n{error}", @@ -436,3 +436,19 @@ def extract_node(code, module_name=""): if len(extracted) == 1: return extracted[0] return extracted + + +MISPLACED_TYPE_ANNOTATION_ERROR = "misplaced type annotation" + + +def _parse_string(data, type_comments=True): + try: + node = _parse(data + "\n", type_comments=type_comments) + except SyntaxError as exc: + # If the type annotations are misplaced for some reason, we do not want + # to fail the entire parsing of the file, so we need to retry the parsing without + # type comment support. + if exc.args[0] != MISPLACED_TYPE_ANNOTATION_ERROR or not type_comments: + raise + node = _parse(data + "\n", type_comments=False) + return node |