From 4ff0f452db37e3658b5b974727c88cdb1e1a8282 Mon Sep 17 00:00:00 2001 From: hauntsaninja <> Date: Mon, 20 Apr 2020 22:09:26 -0700 Subject: [PATCH 1/2] fastparse: add line and column information for extended slices --- mypy/fastparse.py | 7 +++++-- test-data/unit/parse.test | 44 +++++++++++++++++++-------------------- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/mypy/fastparse.py b/mypy/fastparse.py index 4b963c74f223..3b4ad8fb66b6 100644 --- a/mypy/fastparse.py +++ b/mypy/fastparse.py @@ -1205,7 +1205,10 @@ def visit_Attribute(self, n: Attribute) -> Union[MemberExpr, SuperExpr]: def visit_Subscript(self, n: ast3.Subscript) -> IndexExpr: e = IndexExpr(self.visit(n.value), self.visit(n.slice)) self.set_line(e, n) - if isinstance(e.index, SliceExpr): + if ( + isinstance(e.index, SliceExpr) or + (sys.version_info <= (3, 9) and isinstance(e.index, TupleExpr)) + ): # Slice has no line/column in the raw ast. e.index.line = e.line e.index.column = e.column @@ -1233,7 +1236,7 @@ def visit_List(self, n: ast3.List) -> Union[ListExpr, TupleExpr]: # Tuple(expr* elts, expr_context ctx) def visit_Tuple(self, n: ast3.Tuple) -> TupleExpr: - e = TupleExpr([self.visit(e) for e in n.elts]) + e = TupleExpr(self.translate_expr_list(n.elts)) return self.set_line(e, n) # --- slice --- diff --git a/test-data/unit/parse.test b/test-data/unit/parse.test index 8940d211e219..3b1d1198c269 100644 --- a/test-data/unit/parse.test +++ b/test-data/unit/parse.test @@ -3151,7 +3151,7 @@ MypyFile:1( ExpressionStmt:1( IndexExpr:1( NameExpr(a) - TupleExpr:-1( + TupleExpr:1( SliceExpr:-1( ) @@ -3166,7 +3166,7 @@ MypyFile:1( ExpressionStmt:1( IndexExpr:1( NameExpr(a) - TupleExpr:-1( + TupleExpr:1( SliceExpr:-1( IntExpr(1) IntExpr(2)) @@ -3181,7 +3181,7 @@ MypyFile:1( ExpressionStmt:1( IndexExpr:1( NameExpr(a) - TupleExpr:-1( + TupleExpr:1( SliceExpr:-1( IntExpr(1) IntExpr(2) @@ -3426,25 +3426,25 @@ y = 30 f'Hello {x!s:<{y+y}}' [out] MypyFile:1( - AssignmentStmt:1( - NameExpr(x) - StrExpr(mypy)) - AssignmentStmt:2( - NameExpr(y) - IntExpr(30)) - ExpressionStmt:3( - CallExpr:3( - MemberExpr:3( - StrExpr() - join) - Args( - ListExpr:3( - StrExpr(Hello ) - CallExpr:3( - MemberExpr:3( - StrExpr({!s:{}}) - format) - Args( + AssignmentStmt:1( + NameExpr(x) + StrExpr(mypy)) + AssignmentStmt:2( + NameExpr(y) + IntExpr(30)) + ExpressionStmt:3( + CallExpr:3( + MemberExpr:3( + StrExpr() + join) + Args( + ListExpr:3( + StrExpr(Hello ) + CallExpr:3( + MemberExpr:3( + StrExpr({!s:{}}) + format) + Args( NameExpr(x) CallExpr:3( MemberExpr:3( From d616fd5e2013d6813efb640b9f4542bf5fd1ff98 Mon Sep 17 00:00:00 2001 From: hauntsaninja <> Date: Thu, 30 Apr 2020 11:11:45 -0700 Subject: [PATCH 2/2] fastparse: fix comparison, clarify Comparison using the ast3 nodes makes things a little clearer, as does commenting the code. --- mypy/fastparse.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/mypy/fastparse.py b/mypy/fastparse.py index 3b4ad8fb66b6..2aac8412f657 100644 --- a/mypy/fastparse.py +++ b/mypy/fastparse.py @@ -1206,10 +1206,13 @@ def visit_Subscript(self, n: ast3.Subscript) -> IndexExpr: e = IndexExpr(self.visit(n.value), self.visit(n.slice)) self.set_line(e, n) if ( - isinstance(e.index, SliceExpr) or - (sys.version_info <= (3, 9) and isinstance(e.index, TupleExpr)) + isinstance(n.slice, ast3.Slice) or + (sys.version_info < (3, 9) and isinstance(n.slice, ast3.ExtSlice)) ): - # Slice has no line/column in the raw ast. + # Before Python 3.9, Slice has no line/column in the raw ast. To avoid incompatibility + # visit_Slice doesn't set_line, even in Python 3.9 on. + # ExtSlice also has no line/column info. In Python 3.9 on, line/column is set for + # e.index when visiting n.slice. e.index.line = e.line e.index.column = e.column return e