PY-24389 Allow trailing comma in all parameter lists starting from Python 3.6

Previously it was prohibited in signatures containing varargs and
single stars (delimiting normal and keyword-only parameters).
This commit is contained in:
Mikhail Golubev
2017-08-04 14:49:01 +03:00
parent d42b4ead6a
commit 8fe04bedbe
4 changed files with 121 additions and 1 deletions
@@ -20,6 +20,7 @@ import com.intellij.lang.WhitespacesBinders;
import com.intellij.psi.tree.IElementType;
import com.jetbrains.python.PyElementTypes;
import com.jetbrains.python.PyTokenTypes;
import com.jetbrains.python.psi.LanguageLevel;
import org.jetbrains.annotations.NotNull;
import static com.jetbrains.python.PyBundle.message;
@@ -163,7 +164,7 @@ public class FunctionParsing extends Parsing {
}
boolean isStarParameter = atAnyOfTokens(PyTokenTypes.MULT, PyTokenTypes.EXP);
if (!parseParameter(endToken, isLambda)) {
if (afterStarParameter) {
if (afterStarParameter && myContext.getLanguageLevel().isOlderThan(LanguageLevel.PYTHON36)) {
myBuilder.error("expression expected");
}
break;
@@ -0,0 +1,15 @@
def f1(*, x,):
pass
def f2(*args,):
pass
def f3(**kwargs,):
pass
lambda *, x,: 42
lambda *args,: 42
lambda *kwargs,: 42
@@ -0,0 +1,99 @@
PyFile:CommaAfterStarArgAllowedInPython36.py
PyFunction('f1')
PsiElement(Py:DEF_KEYWORD)('def')
PsiWhiteSpace(' ')
PsiElement(Py:IDENTIFIER)('f1')
PyParameterList
PsiElement(Py:LPAR)('(')
PySingleStarParameter
PsiElement(Py:MULT)('*')
PsiElement(Py:COMMA)(',')
PsiWhiteSpace(' ')
PyNamedParameter('x')
PsiElement(Py:IDENTIFIER)('x')
PsiElement(Py:COMMA)(',')
PsiElement(Py:RPAR)(')')
PsiElement(Py:COLON)(':')
PsiWhiteSpace('\n ')
PyStatementList
PyPassStatement
PsiElement(Py:PASS_KEYWORD)('pass')
PsiWhiteSpace('\n\n\n')
PyFunction('f2')
PsiElement(Py:DEF_KEYWORD)('def')
PsiWhiteSpace(' ')
PsiElement(Py:IDENTIFIER)('f2')
PyParameterList
PsiElement(Py:LPAR)('(')
PyNamedParameter('args')
PsiElement(Py:MULT)('*')
PsiElement(Py:IDENTIFIER)('args')
PsiElement(Py:COMMA)(',')
PsiElement(Py:RPAR)(')')
PsiElement(Py:COLON)(':')
PsiWhiteSpace('\n ')
PyStatementList
PyPassStatement
PsiElement(Py:PASS_KEYWORD)('pass')
PsiWhiteSpace('\n\n\n')
PyFunction('f3')
PsiElement(Py:DEF_KEYWORD)('def')
PsiWhiteSpace(' ')
PsiElement(Py:IDENTIFIER)('f3')
PyParameterList
PsiElement(Py:LPAR)('(')
PyNamedParameter('kwargs')
PsiElement(Py:EXP)('**')
PsiElement(Py:IDENTIFIER)('kwargs')
PsiElement(Py:COMMA)(',')
PsiElement(Py:RPAR)(')')
PsiElement(Py:COLON)(':')
PsiWhiteSpace('\n ')
PyStatementList
PyPassStatement
PsiElement(Py:PASS_KEYWORD)('pass')
PsiWhiteSpace('\n\n\n')
PyExpressionStatement
PyLambdaExpression
PsiElement(Py:LAMBDA_KEYWORD)('lambda')
PsiWhiteSpace(' ')
PyParameterList
PySingleStarParameter
PsiElement(Py:MULT)('*')
PsiElement(Py:COMMA)(',')
PsiWhiteSpace(' ')
PyNamedParameter('x')
PsiElement(Py:IDENTIFIER)('x')
PsiElement(Py:COMMA)(',')
PsiElement(Py:COLON)(':')
PsiWhiteSpace(' ')
PyNumericLiteralExpression
PsiElement(Py:INTEGER_LITERAL)('42')
PsiWhiteSpace('\n')
PyExpressionStatement
PyLambdaExpression
PsiElement(Py:LAMBDA_KEYWORD)('lambda')
PsiWhiteSpace(' ')
PyParameterList
PyNamedParameter('args')
PsiElement(Py:MULT)('*')
PsiElement(Py:IDENTIFIER)('args')
PsiElement(Py:COMMA)(',')
PsiElement(Py:COLON)(':')
PsiWhiteSpace(' ')
PyNumericLiteralExpression
PsiElement(Py:INTEGER_LITERAL)('42')
PsiWhiteSpace('\n')
PyExpressionStatement
PyLambdaExpression
PsiElement(Py:LAMBDA_KEYWORD)('lambda')
PsiWhiteSpace(' ')
PyParameterList
PyNamedParameter('kwargs')
PsiElement(Py:MULT)('*')
PsiElement(Py:IDENTIFIER)('kwargs')
PsiElement(Py:COMMA)(',')
PsiElement(Py:COLON)(':')
PsiWhiteSpace(' ')
PyNumericLiteralExpression
PsiElement(Py:INTEGER_LITERAL)('42')
@@ -335,6 +335,11 @@ public class PythonParsingTest extends ParsingTestCase {
doTest();
}
// PY-24389
public void testCommaAfterStarArgAllowedInPython36() {
doTest(LanguageLevel.PYTHON36);
}
public void testRangeAsLHS() { // PY-6468
doTest();
}