Skip to content

Commit 4363355

Browse files
SONARPY-788 Fix parsing error on annotated assignment for Python 3.8 (SonarSource#856)
1 parent cb6e0c5 commit 4363355

4 files changed

Lines changed: 30 additions & 2 deletions

File tree

python-frontend/src/main/java/org/sonar/python/api/PythonGrammar.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,8 @@ public static void grammar(LexerfulGrammarBuilder b) {
186186
b.sequence(AUGASSIGN, b.firstOf(YIELD_EXPR, TESTLIST)),
187187
b.zeroOrMore("=", b.firstOf(YIELD_EXPR, TESTLIST_STAR_EXPR))));
188188

189-
// https://github.com/python/cpython/blob/v3.6.4/Grammar/Grammar#L43
190-
b.rule(ANNASSIGN).is(":", TEST, b.optional( "=", TEST));
189+
// https://github.com/python/cpython/blob/v3.8.0/Grammar/Grammar#L87
190+
b.rule(ANNASSIGN).is(":", TEST, b.optional( "=", b.firstOf(YIELD_EXPR, TESTLIST_STAR_EXPR)));
191191

192192
b.rule(TESTLIST_STAR_EXPR).is(b.firstOf(TEST, STAR_EXPR), b.zeroOrMore(",", b.firstOf(TEST, STAR_EXPR)), b.optional(","));
193193
b.rule(AUGASSIGN).is(b.firstOf("+=", "-=", "*=", "/=", "//=", "%=", "**=", ">>=", "<<=", "&=", "^=", "|=", "@="));

python-frontend/src/main/java/org/sonar/python/tree/PythonTreeMaker.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,9 @@ public Expression expression(AstNode astNode) {
878878
if (astNode.is(PythonGrammar.ELLIPSIS)) {
879879
return new EllipsisExpressionImpl(toPyToken(astNode.getTokens()));
880880
}
881+
if (astNode.is(PythonGrammar.TESTLIST_STAR_EXPR)) {
882+
return exprListOrTestList(astNode);
883+
}
881884
throw new IllegalStateException("Expression " + astNode.getType() + " not correctly translated to strongly typed AST");
882885
}
883886

python-frontend/src/test/java/org/sonar/python/tree/PythonTreeMakerTest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,6 +1169,23 @@ public void annotated_assignment() {
11691169
assertThat(((Name) annAssign.annotation().expression()).name()).isEqualTo("string");
11701170
assertThat(annAssign.assignedValue()).isNull();
11711171
assertThat(annAssign.equalToken()).isNull();
1172+
1173+
astNode = p.parse("y: int = yield _bar(x)");
1174+
statementWithSeparator = new StatementWithSeparator(astNode, null);
1175+
annAssign = treeMaker.annotatedAssignment(statementWithSeparator);
1176+
assertThat(annAssign.variable().is(Kind.NAME)).isTrue();
1177+
assertThat(((Name) annAssign.variable()).name()).isEqualTo("y");
1178+
assertThat(annAssign.assignedValue().is(Kind.YIELD_EXPR)).isTrue();
1179+
assertThat(((YieldExpression) annAssign.assignedValue()).expressions().size()).isEqualTo(1);
1180+
assertThat(((YieldExpression) annAssign.assignedValue()).expressions().get(0).is(Kind.CALL_EXPR)).isTrue();
1181+
1182+
astNode = p.parse("y: Tuple = a, b, c");
1183+
statementWithSeparator = new StatementWithSeparator(astNode, null);
1184+
annAssign = treeMaker.annotatedAssignment(statementWithSeparator);
1185+
assertThat(annAssign.variable().is(Kind.NAME)).isTrue();
1186+
assertThat(((Name) annAssign.variable()).name()).isEqualTo("y");
1187+
assertThat(annAssign.assignedValue().is(Kind.TUPLE)).isTrue();
1188+
assertThat(((Tuple) annAssign.assignedValue()).elements().size()).isEqualTo(3);
11721189
}
11731190

11741191
@Test
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
def _bar(current):
2+
return current
3+
4+
def _foo():
5+
x: int = 0
6+
y: int = yield _bar(x)
7+
y: int = yield a, a
8+
yield x + (y if y else 0)

0 commit comments

Comments
 (0)