Avoid duplicate messages in compatibility inspection and unsupported features annotator (PY-33516)

Inspection does not register `CompatibilityVisitor` problems for its opened file language because in such a case
`UnsupportedFeatures` will annotate them.
Also `registerOnFirstMatchingVersion` methods were removed because
they could lead to duplication even if languages to register were different.
This commit is contained in:
Semyon Proshev
2019-01-14 17:27:39 +03:00
parent 4611c74840
commit 1e07ba1cfa
32 changed files with 180 additions and 177 deletions
@@ -204,8 +204,7 @@ public class PyCompatibilityInspection extends PyInspection {
registerForAllMatchingVersions(level -> unsupportedMethods.getOrDefault(level, Collections.emptySet()).contains(functionName),
" not have method " + functionName,
node,
null);
node);
}
}
@@ -215,8 +214,7 @@ public class PyCompatibilityInspection extends PyInspection {
!myUsedImports.contains(functionName)) {
registerForAllMatchingVersions(level -> UnsupportedFeaturesUtil.BUILTINS.get(level).contains(functionName),
" not have method " + functionName,
node,
null);
node);
}
}
else if (resolvedCallee instanceof PyTargetExpression) {
@@ -227,8 +225,7 @@ public class PyCompatibilityInspection extends PyInspection {
PyBuiltinCache.getInstance(resolvedCallee).isBuiltin(resolvedCallee)) {
registerForAllMatchingVersions(level -> UnsupportedFeaturesUtil.BUILTINS.get(level).contains(PyNames.TYPE_LONG),
" not have type long. Use int instead.",
node,
null);
node);
}
}
}
@@ -256,8 +253,7 @@ public class PyCompatibilityInspection extends PyInspection {
registerForAllMatchingVersions(level -> UnsupportedFeaturesUtil.MODULES.get(level).contains(moduleName) && !BACKPORTED_PACKAGES.contains(moduleName),
" not have module " + moduleName,
importElement,
null);
importElement);
}
}
@@ -287,8 +283,7 @@ public class PyCompatibilityInspection extends PyInspection {
registerForAllMatchingVersions(level -> UnsupportedFeaturesUtil.MODULES.get(level).contains(moduleName) && !BACKPORTED_PACKAGES.contains(moduleName),
" not have module " + name,
source,
null);
source);
}
}
@@ -364,14 +359,19 @@ public class PyCompatibilityInspection extends PyInspection {
warnAsyncAndAwaitAreBecomingKeywordsInPy37(node);
}
@Override
protected boolean registerForLanguageLevel(@NotNull LanguageLevel level) {
return level != LanguageLevel.forElement(myHolder.getFile());
}
private void warnAsyncAndAwaitAreBecomingKeywordsInPy37(@NotNull PsiNameIdentifierOwner nameIdentifierOwner) {
final PsiElement nameIdentifier = nameIdentifierOwner.getNameIdentifier();
if (nameIdentifier != null &&
ArrayUtil.contains(nameIdentifierOwner.getName(), PyNames.AWAIT, PyNames.ASYNC) &&
LanguageLevel.forElement(nameIdentifierOwner).isOlderThan(LanguageLevel.PYTHON37)) {
registerOnFirstMatchingVersion(level -> level.isAtLeast(LanguageLevel.PYTHON37),
"'async' and 'await' are keywords in Python 3.7 and newer",
registerForAllMatchingVersions(level -> level.isAtLeast(LanguageLevel.PYTHON37),
" not allow 'async' and 'await' as names",
nameIdentifier,
new PyRenameElementQuickFix(nameIdentifierOwner));
}
@@ -57,10 +57,9 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
public void visitPyAnnotation(PyAnnotation node) {
final PsiElement parent = node.getParent();
if (!(parent instanceof PyFunction || parent instanceof PyNamedParameter)) {
registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON36),
registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON36) && registerForLanguageLevel(level),
" not support variable annotations",
node,
null);
node);
}
}
@@ -68,7 +67,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
public void visitPyDictCompExpression(PyDictCompExpression node) {
super.visitPyDictCompExpression(node);
registerForAllMatchingVersions(level -> !level.supportsSetLiterals(),
registerForAllMatchingVersions(level -> !level.supportsSetLiterals() && registerForLanguageLevel(level),
" not support dictionary comprehensions",
node,
new ConvertDictCompQuickFix(),
@@ -79,7 +78,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
public void visitPySetLiteralExpression(PySetLiteralExpression node) {
super.visitPySetLiteralExpression(node);
registerForAllMatchingVersions(level -> !level.supportsSetLiterals(),
registerForAllMatchingVersions(level -> !level.supportsSetLiterals() && registerForLanguageLevel(level),
" not support set literal expressions",
node,
new ConvertSetLiteralQuickFix(),
@@ -90,7 +89,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
public void visitPySetCompExpression(PySetCompExpression node) {
super.visitPySetCompExpression(node);
registerForAllMatchingVersions(level -> !level.supportsSetLiterals(),
registerForAllMatchingVersions(level -> !level.supportsSetLiterals() && registerForLanguageLevel(level),
" not support set comprehensions",
node,
null,
@@ -109,7 +108,10 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
}
if (element != null && ",".equals(element.getText())) {
registerForAllMatchingVersions(LanguageLevel::isPy3K, " not support this syntax.", node, new ReplaceExceptPartQuickFix());
registerForAllMatchingVersions(level -> level.isPy3K() && registerForLanguageLevel(level),
" not support this syntax.",
node,
new ReplaceExceptPartQuickFix());
}
}
}
@@ -126,10 +128,16 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
if (qName != null) {
if (qName.matches("builtins")) {
registerForAllMatchingVersions(LanguageLevel::isPython2, " not have module builtins", node, new ReplaceBuiltinsQuickFix());
registerForAllMatchingVersions(level -> level.isPython2() && registerForLanguageLevel(level),
" not have module builtins",
node,
new ReplaceBuiltinsQuickFix());
}
else if (qName.matches("__builtin__")) {
registerForAllMatchingVersions(LanguageLevel::isPy3K, " not have module __builtin__", node, new ReplaceBuiltinsQuickFix());
registerForAllMatchingVersions(level -> level.isPy3K() && registerForLanguageLevel(level),
" not have module __builtin__",
node,
new ReplaceBuiltinsQuickFix());
}
}
}
@@ -140,14 +148,14 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
super.visitPyStarExpression(node);
if (node.isAssignmentTarget()) {
registerOnFirstMatchingVersion(LanguageLevel::isPython2,
"Python versions < 3.0 do not support starred expressions as assignment targets",
registerForAllMatchingVersions(level -> level.isPython2() && registerForLanguageLevel(level),
" not support starred expressions as assignment targets",
node);
}
if (node.isUnpacking()) {
registerOnFirstMatchingVersion(level -> level.isOlderThan(LanguageLevel.PYTHON35),
"Python versions < 3.5 do not support starred expressions in tuples, lists, and sets",
registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON35) && registerForLanguageLevel(level),
" not support starred expressions in tuples, lists, and sets",
node);
}
}
@@ -156,8 +164,8 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
public void visitPyDoubleStarExpression(PyDoubleStarExpression node) {
super.visitPyDoubleStarExpression(node);
registerOnFirstMatchingVersion(level -> level.isOlderThan(LanguageLevel.PYTHON35),
"Python versions < 3.5 do not support starred expressions in dicts",
registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON35) && registerForLanguageLevel(level),
" not support starred expressions in dicts",
node);
}
@@ -166,7 +174,10 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
super.visitPyBinaryExpression(node);
if (node.isOperator("<>")) {
registerForAllMatchingVersions(LanguageLevel::isPy3K, " not support <>, use != instead.", node, new ReplaceNotEqOperatorQuickFix());
registerForAllMatchingVersions(level -> level.isPy3K() && registerForLanguageLevel(level),
" not support <>, use != instead.",
node,
new ReplaceNotEqOperatorQuickFix());
}
else if (node.isOperator("@")) {
checkMatrixMultiplicationOperator(node.getPsiOperator());
@@ -174,8 +185,8 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
}
private void checkMatrixMultiplicationOperator(PsiElement node) {
registerOnFirstMatchingVersion(level -> level.isOlderThan(LanguageLevel.PYTHON35),
"Python versions < 3.5 do not support matrix multiplication operators",
registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON35) && registerForLanguageLevel(level),
" not support matrix multiplication operators",
node);
}
@@ -187,7 +198,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
if (node.isIntegerLiteral()) {
if (text.endsWith("l") || text.endsWith("L")) {
registerForAllMatchingVersions(LanguageLevel::isPy3K,
registerForAllMatchingVersions(level -> level.isPy3K() && registerForLanguageLevel(level),
" not support a trailing \'l\' or \'L\'.",
node,
new RemoveTrailingLQuickFix());
@@ -196,7 +207,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
if (text.length() > 1 && text.charAt(0) == '0') {
final char secondChar = Character.toLowerCase(text.charAt(1));
if (secondChar != 'o' && secondChar != 'b' && secondChar != 'x' && text.chars().anyMatch(c -> c != '0')) {
registerForAllMatchingVersions(LanguageLevel::isPy3K,
registerForAllMatchingVersions(level -> level.isPy3K() && registerForLanguageLevel(level),
" not support this syntax. It requires '0o' prefix for octal literals",
node,
new ReplaceOctalNumericLiteralQuickFix());
@@ -205,7 +216,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
}
if (text.contains("_")) {
registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON36),
registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON36) && registerForLanguageLevel(level),
" not support underscores in numeric literals",
node,
new PyRemoveUnderscoresInNumericLiteralsQuickFix());
@@ -227,7 +238,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
seenNonBytes |= !bytes;
final int elementStart = element.getTextOffset();
registerForAllMatchingVersions(level -> !getSupportedStringPrefixes(level).contains(prefix),
registerForAllMatchingVersions(level -> !getSupportedStringPrefixes(level).contains(prefix) && registerForLanguageLevel(level),
" not support a '" + prefix + "' prefix",
node,
TextRange.create(elementStart, elementStart + element.getPrefixLength()),
@@ -236,10 +247,9 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
}
if (seenBytes && seenNonBytes) {
registerForAllMatchingVersions(LanguageLevel::isPy3K,
registerForAllMatchingVersions(level -> level.isPy3K() && registerForLanguageLevel(level),
" not allow to mix bytes and non-bytes literals",
node,
null);
node);
}
}
@@ -260,11 +270,12 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
public void visitPyListCompExpression(final PyListCompExpression node) {
super.visitPyListCompExpression(node);
final List<PyExpression> nodes = node.getForComponents().stream().map(PyComprehensionForComponent::getIteratedList).collect(Collectors.toList());
registerForAllMatchingVersions(level -> UnsupportedFeaturesUtil.visitPyListCompExpression(node, level),
" not support this syntax in list comprehensions.",
nodes,
new ReplaceListComprehensionsQuickFix());
registerForAllMatchingVersions(
level -> registerForLanguageLevel(level) && UnsupportedFeaturesUtil.visitPyListCompExpression(node, level),
" not support this syntax in list comprehensions.",
ContainerUtil.map(node.getForComponents(), PyComprehensionForComponent::getIteratedList),
new ReplaceListComprehensionsQuickFix()
);
}
@Override
@@ -272,19 +283,20 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
super.visitPyRaiseStatement(node);
// empty raise under finally
registerForAllMatchingVersions(level -> UnsupportedFeaturesUtil.raiseHasNoArgsUnderFinally(node, level),
" not support this syntax. Raise with no arguments can only be used in an except block",
node,
null);
registerForAllMatchingVersions(
level -> registerForLanguageLevel(level) && UnsupportedFeaturesUtil.raiseHasNoArgsUnderFinally(node, level),
" not support this syntax. Raise with no arguments can only be used in an except block",
node
);
// raise 1, 2, 3
registerForAllMatchingVersions(level -> UnsupportedFeaturesUtil.raiseHasMoreThenOneArg(node, level),
registerForAllMatchingVersions(level -> registerForLanguageLevel(level) && UnsupportedFeaturesUtil.raiseHasMoreThenOneArg(node, level),
" not support this syntax.",
node,
new ReplaceRaiseStatementQuickFix());
// raise exception from cause
registerForAllMatchingVersions(level -> UnsupportedFeaturesUtil.raiseHasFromKeyword(node, level),
registerForAllMatchingVersions(level -> registerForLanguageLevel(level) && UnsupportedFeaturesUtil.raiseHasFromKeyword(node, level),
" not support this syntax.",
node,
new ReplaceRaiseStatementQuickFix());
@@ -294,7 +306,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
public void visitPyReprExpression(PyReprExpression node) {
super.visitPyReprExpression(node);
registerForAllMatchingVersions(LanguageLevel::isPy3K,
registerForAllMatchingVersions(level -> level.isPy3K() && registerForLanguageLevel(level),
" not support backquotes, use repr() instead",
node,
new ReplaceBackquoteExpressionQuickFix());
@@ -307,7 +319,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
final PyWithItem[] items = node.getWithItems();
if (items.length > 1) {
registerForAllMatchingVersions(level -> !level.supportsSetLiterals(),
registerForAllMatchingVersions(level -> !level.supportsSetLiterals() && registerForLanguageLevel(level),
" not support multiple context managers",
Arrays.asList(items).subList(1, items.length),
null);
@@ -331,8 +343,8 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
element -> !(element instanceof PyParenthesizedExpression || element instanceof PyTupleExpression);
if (arguments.length == 0 || Arrays.stream(arguments).anyMatch(nonParenthesesPredicate)) {
registerOnFirstMatchingVersion(LanguageLevel::isPy3K,
"Python version >= 3.0 do not support this syntax. " +
registerForAllMatchingVersions(level -> level.isPy3K() && registerForLanguageLevel(level),
" not support this syntax. " +
"The print statement has been replaced with a print() function",
node,
new CompatibilityPrintCallQuickFix());
@@ -345,10 +357,9 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
final PsiElement firstChild = node.getFirstChild();
if (firstChild != null && PyNames.SUPER.equals(firstChild.getText()) && ArrayUtil.isEmpty(node.getArguments())) {
registerForAllMatchingVersions(LanguageLevel::isPython2,
registerForAllMatchingVersions(level -> level.isPython2() && registerForLanguageLevel(level),
" not support this syntax. super() should have arguments in Python 2",
node,
null);
node);
}
highlightIncorrectArguments(node);
@@ -365,8 +376,8 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
super.visitPyPrefixExpression(node);
if (node.getOperator() == PyTokenTypes.AWAIT_KEYWORD) {
registerOnFirstMatchingVersion(level -> level.isOlderThan(LanguageLevel.PYTHON35),
"Python versions < 3.5 do not support this syntax",
registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON35) && registerForLanguageLevel(level),
" not support this syntax",
node);
}
}
@@ -381,7 +392,9 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
.filter(function -> function.isAsync() && function.isAsyncAllowed())
.ifPresent(
function -> {
if (!node.isDelegating() && myVersionsToProcess.contains(LanguageLevel.PYTHON35)) {
if (!node.isDelegating() &&
registerForLanguageLevel(LanguageLevel.PYTHON35) &&
myVersionsToProcess.contains(LanguageLevel.PYTHON35)) {
registerProblem(node, "Python version 3.5 does not support 'yield' inside async functions");
}
}
@@ -391,15 +404,15 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
return;
}
registerOnFirstMatchingVersion(LanguageLevel::isPython2,
"Python versions < 3.3 do not support this syntax. Delegating to a subgenerator is available since " +
registerForAllMatchingVersions(level -> level.isPython2() && registerForLanguageLevel(level),
" not support this syntax. Delegating to a subgenerator is available since " +
"Python 3.3; use explicit iteration over subgenerator instead.",
node);
}
@Override
public void visitPyReturnStatement(PyReturnStatement node) {
if (ContainerUtil.exists(myVersionsToProcess, LanguageLevel::isPython2)) {
if (ContainerUtil.exists(myVersionsToProcess, level -> level.isPython2() && registerForLanguageLevel(level))) {
final PyFunction function = PsiTreeUtil.getParentOfType(node, PyFunction.class, false, PyClass.class);
if (function != null && node.getExpression() != null) {
final YieldVisitor visitor = new YieldVisitor();
@@ -422,8 +435,8 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
if (sliceItem != null) {
return;
}
registerOnFirstMatchingVersion(LanguageLevel::isPython2,
"Python versions < 3.0 do not support '...' outside of sequence slicings.",
registerForAllMatchingVersions(level -> level.isPython2() && registerForLanguageLevel(level),
" not support '...' outside of sequence slicings.",
node);
}
}
@@ -443,11 +456,12 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
private void checkAsyncKeyword(@NotNull PsiElement node) {
final ASTNode asyncNode = node.getNode().findChildByType(PyTokenTypes.ASYNC_KEYWORD);
if (asyncNode != null) {
registerOnFirstMatchingVersion(level -> level.isOlderThan(LanguageLevel.PYTHON35),
"Python versions < 3.5 do not support this syntax",
registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON35) && registerForLanguageLevel(level),
" not support this syntax",
node,
asyncNode.getTextRange(),
null);
null,
true);
}
}
@@ -476,6 +490,10 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
}
}
protected boolean registerForLanguageLevel(@NotNull LanguageLevel level) {
return true;
}
protected abstract void registerProblem(@NotNull PsiElement node,
@NotNull TextRange range,
@NotNull String message,
@@ -544,35 +562,20 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
@NotNull String suffix,
@NotNull PsiElement node,
@Nullable LocalQuickFix localQuickFix) {
registerForAllMatchingVersions(levelPredicate, suffix, node, node.getTextRange(), localQuickFix, true);
registerForAllMatchingVersions(levelPredicate, suffix, node, localQuickFix, true);
}
protected void registerOnFirstMatchingVersion(@NotNull Predicate<LanguageLevel> levelPredicate,
@NotNull String message,
@NotNull PsiElement node,
@NotNull TextRange range,
@Nullable LocalQuickFix localQuickFix) {
if (myVersionsToProcess.stream().anyMatch(levelPredicate)) {
registerProblem(node, range, message, localQuickFix, true);
}
}
protected void registerOnFirstMatchingVersion(@NotNull Predicate<LanguageLevel> levelPredicate,
@NotNull String message,
@NotNull PsiElement node,
@Nullable LocalQuickFix localQuickFix) {
registerOnFirstMatchingVersion(levelPredicate, message, node, node.getTextRange(), localQuickFix);
}
protected void registerOnFirstMatchingVersion(@NotNull Predicate<LanguageLevel> levelPredicate,
@NotNull String message,
protected void registerForAllMatchingVersions(@NotNull Predicate<LanguageLevel> levelPredicate,
@NotNull String suffix,
@NotNull PsiElement node) {
registerOnFirstMatchingVersion(levelPredicate, message, node, node.getTextRange(), null);
registerForAllMatchingVersions(levelPredicate, suffix, node, null, true);
}
@Override
public void visitPyNonlocalStatement(final PyNonlocalStatement node) {
registerOnFirstMatchingVersion(LanguageLevel::isPython2, "nonlocal keyword available only since py3", node);
registerForAllMatchingVersions(level -> level.isPython2() && registerForLanguageLevel(level),
" not have nonlocal keyword",
node);
}
private void highlightIncorrectArguments(@NotNull PyCallExpression callExpression) {
@@ -590,8 +593,8 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
registerProblem(argument, "Keyword argument repeated", new PyRemoveArgumentQuickFix());
}
else if (seenKeywordContainer) {
registerOnFirstMatchingVersion(level -> level.isOlderThan(LanguageLevel.PYTHON35),
"Python versions < 3.5 do not allow keyword arguments after **expression",
registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON35) && registerForLanguageLevel(level),
" not allow keyword arguments after **expression",
argument,
new PyRemoveArgumentQuickFix());
}
@@ -603,8 +606,8 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
final PyStarArgument starArgument = (PyStarArgument)argument;
if (starArgument.isKeyword()) {
if (seenKeywordContainer) {
registerOnFirstMatchingVersion(level -> level.isOlderThan(LanguageLevel.PYTHON35),
"Python versions < 3.5 do not allow duplicate **expressions",
registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON35) && registerForLanguageLevel(level),
" not allow duplicate **expressions",
argument,
new PyRemoveArgumentQuickFix());
}
@@ -612,8 +615,8 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
}
else {
if (seenPositionalContainer) {
registerOnFirstMatchingVersion(level -> level.isOlderThan(LanguageLevel.PYTHON35),
"Python versions < 3.5 do not allow duplicate *expressions",
registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON35) && registerForLanguageLevel(level),
" not allow duplicate *expressions",
argument,
new PyRemoveArgumentQuickFix());
}
@@ -625,8 +628,8 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
registerProblem(argument, "Positional argument after keyword argument", new PyRemoveArgumentQuickFix());
}
else if (seenPositionalContainer) {
registerOnFirstMatchingVersion(level -> level.isOlderThan(LanguageLevel.PYTHON35),
"Python versions < 3.5 do not allow positional arguments after *expression",
registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON35) && registerForLanguageLevel(level),
" not allow positional arguments after *expression",
argument,
new PyRemoveArgumentQuickFix());
}
@@ -642,8 +645,8 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
PsiElement sibling = PyPsiUtils.getNextNonWhitespaceSibling(lastArg);
if (sibling != null && sibling.getNode().getElementType() == PyTokenTypes.COMMA) {
boolean isKeyword = ((PyStarArgument)lastArg).isKeyword();
registerOnFirstMatchingVersion(level -> level.isOlderThan(LanguageLevel.PYTHON35),
"Python versions < 3.5 do not allow a trailing comma after "
registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON35) && registerForLanguageLevel(level),
" not allow a trailing comma after "
+ (isKeyword ? "**" : "*") + "expression",
sibling);
}
@@ -654,7 +657,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
public void visitPyComprehensionElement(PyComprehensionElement node) {
super.visitPyComprehensionElement(node);
if (myVersionsToProcess.contains(LanguageLevel.PYTHON35)) {
if (registerForLanguageLevel(LanguageLevel.PYTHON35) && myVersionsToProcess.contains(LanguageLevel.PYTHON35)) {
Arrays
.stream(node.getNode().getChildren(TokenSet.create(PyTokenTypes.ASYNC_KEYWORD)))
.filter(Objects::nonNull)
@@ -2,4 +2,4 @@ def foo(**kwargs): pass
two = 0
kw = {}
foo(**kw, <error descr="Python versions < 3.5 do not allow keyword arguments after **expression">two=1</error>)
foo(**kw, <error descr="Python version 2.7 does not allow keyword arguments after **expression">two=1</error>)
@@ -7,4 +7,4 @@ class Foo(object):
@classmethod
def test(cls):
cls(**kwargs, <error descr="Python versions < 3.5 do not allow keyword arguments after **expression">foo=1</error>)
cls(**kwargs, <error descr="Python version 2.7 does not allow keyword arguments after **expression">foo=1</error>)
@@ -19,7 +19,7 @@ def f2(a, b, c=1, *d):
f2(c=3, *(1,2))
f2(1,2,3, *(1,2))
f2(*(1,2), c=20)
f2(*(1,2), <error descr="Python versions < 3.5 do not allow positional arguments after *expression">20</error>) # fail: positional past *
f2(*(1,2), <error descr="Python version 3.4 does not allow positional arguments after *expression">20</error>) # fail: positional past *
def f3(a=1, b=2, c=3, *d):
return a,b,c,d
@@ -4,14 +4,14 @@ def foo(*args, **kwargs):
foo(0,
*[1],
<warning descr="Python versions < 3.5 do not allow positional arguments after *expression">2</warning>,
<warning descr="Python versions < 3.5 do not allow duplicate *expressions">*[3]</warning>,
<warning descr="Python versions < 3.5 do not allow positional arguments after *expression">4</warning>,
<warning descr="Python version 2.6, 2.7, 3.4 do not allow positional arguments after *expression">2</warning>,
<warning descr="Python version 2.6, 2.7, 3.4 do not allow duplicate *expressions">*[3]</warning>,
<warning descr="Python version 2.6, 2.7, 3.4 do not allow positional arguments after *expression">4</warning>,
a='a',
<warning descr="Python versions < 3.5 do not allow duplicate *expressions">*[6]</warning>,
<warning descr="Python version 2.6, 2.7, 3.4 do not allow duplicate *expressions">*[6]</warning>,
b='b',
<warning descr="Python versions < 3.5 do not allow duplicate *expressions">*[7]</warning>,
<warning descr="Python version 2.6, 2.7, 3.4 do not allow duplicate *expressions">*[7]</warning>,
c='c',
**{'d': 'd'},
<warning descr="Python versions < 3.5 do not allow keyword arguments after **expression">e='e'</warning>,
<warning descr="Python versions < 3.5 do not allow duplicate **expressions">**{'f': 'f'}</warning>)
<warning descr="Python version 2.6, 2.7, 3.4 do not allow keyword arguments after **expression">e='e'</warning>,
<warning descr="Python version 2.6, 2.7, 3.4 do not allow duplicate **expressions">**{'f': 'f'}</warning>)
@@ -1,7 +1,7 @@
<warning descr="Python versions < 3.5 do not support this syntax">async</warning> def foo(x):
<warning descr="Python versions < 3.5 do not support this syntax">async</warning> with x:
y = <warning descr="Python versions < 3.5 do not support this syntax">await x</warning>
if <warning descr="Python versions < 3.5 do not support this syntax">await y</warning>:
return <warning descr="Python versions < 3.5 do not support this syntax">await z</warning>
<warning descr="Python versions < 3.5 do not support this syntax">async</warning> for y in x:
<warning descr="Python version 2.6, 2.7, 3.4 do not support this syntax">async</warning> def foo(x):
<warning descr="Python version 2.6, 2.7, 3.4 do not support this syntax">async</warning> with x:
y = <warning descr="Python version 2.6, 2.7, 3.4 do not support this syntax">await x</warning>
if <warning descr="Python version 2.6, 2.7, 3.4 do not support this syntax">await y</warning>:
return <warning descr="Python version 2.6, 2.7, 3.4 do not support this syntax">await z</warning>
<warning descr="Python version 2.6, 2.7, 3.4 do not support this syntax">async</warning> for y in x:
pass
@@ -1,6 +1,6 @@
<warning descr="Python versions < 3.5 do not support this syntax">async</warning> def asyncgen():
<warning descr="Python version 2.6, 2.7, 3.4 do not support this syntax">async</warning> def asyncgen():
<warning descr="Python version 3.5 does not support 'yield' inside async functions">yield 10</warning>
<warning descr="Python versions < 3.5 do not support this syntax">async</warning> def run():
<warning descr="Python version 2.6, 2.7, 3.4 do not support this syntax">async</warning> def run():
<warning descr="Python version 2.6 does not support set comprehensions">{i <warning descr="Python version 3.5 does not support 'async' inside comprehensions and generator expressions">async</warning> for i in asyncgen()}</warning>
[i <warning descr="Python version 3.5 does not support 'async' inside comprehensions and generator expressions">async</warning> for i in asyncgen()]
<warning descr="Python version 2.6 does not support dictionary comprehensions">{i: i ** 2 <warning descr="Python version 3.5 does not support 'async' inside comprehensions and generator expressions">async</warning> for i in asyncgen()}</warning>
@@ -1,16 +1,16 @@
<warning descr="Python versions < 3.5 do not support this syntax">async</warning> def async2():
[<warning descr="Python versions < 3.5 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> fun()</warning> for fun in funcs]
<warning descr="Python version 2.6 does not support set comprehensions">{<warning descr="Python versions < 3.5 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> fun()</warning> for fun in funcs}</warning>
<warning descr="Python version 2.6 does not support dictionary comprehensions">{fun: <warning descr="Python versions < 3.5 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> fun()</warning> for fun in funcs}</warning>
<warning descr="Python version 2.6, 2.7, 3.4 do not support this syntax">async</warning> def async2():
[<warning descr="Python version 2.6, 2.7, 3.4 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> fun()</warning> for fun in funcs]
<warning descr="Python version 2.6 does not support set comprehensions">{<warning descr="Python version 2.6, 2.7, 3.4 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> fun()</warning> for fun in funcs}</warning>
<warning descr="Python version 2.6 does not support dictionary comprehensions">{fun: <warning descr="Python version 2.6, 2.7, 3.4 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> fun()</warning> for fun in funcs}</warning>
[<warning descr="Python versions < 3.5 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> fun()</warning> for fun in funcs if <warning descr="Python versions < 3.5 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> smth</warning>]
<warning descr="Python version 2.6 does not support set comprehensions">{<warning descr="Python versions < 3.5 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> fun()</warning> for fun in funcs if <warning descr="Python versions < 3.5 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> smth</warning>}</warning>
<warning descr="Python version 2.6 does not support dictionary comprehensions">{fun: <warning descr="Python versions < 3.5 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> fun()</warning> for fun in funcs if <warning descr="Python versions < 3.5 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> smth</warning>}</warning>
[<warning descr="Python version 2.6, 2.7, 3.4 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> fun()</warning> for fun in funcs if <warning descr="Python version 2.6, 2.7, 3.4 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> smth</warning>]
<warning descr="Python version 2.6 does not support set comprehensions">{<warning descr="Python version 2.6, 2.7, 3.4 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> fun()</warning> for fun in funcs if <warning descr="Python version 2.6, 2.7, 3.4 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> smth</warning>}</warning>
<warning descr="Python version 2.6 does not support dictionary comprehensions">{fun: <warning descr="Python version 2.6, 2.7, 3.4 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> fun()</warning> for fun in funcs if <warning descr="Python version 2.6, 2.7, 3.4 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> smth</warning>}</warning>
[<warning descr="Python versions < 3.5 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> fun()</warning> <warning descr="Python version 3.5 does not support 'async' inside comprehensions and generator expressions">async</warning> for fun in funcs]
<warning descr="Python version 2.6 does not support set comprehensions">{<warning descr="Python versions < 3.5 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> fun()</warning> <warning descr="Python version 3.5 does not support 'async' inside comprehensions and generator expressions">async</warning> for fun in funcs}</warning>
<warning descr="Python version 2.6 does not support dictionary comprehensions">{fun: <warning descr="Python versions < 3.5 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> fun()</warning> <warning descr="Python version 3.5 does not support 'async' inside comprehensions and generator expressions">async</warning> for fun in funcs}</warning>
[<warning descr="Python version 2.6, 2.7, 3.4 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> fun()</warning> <warning descr="Python version 3.5 does not support 'async' inside comprehensions and generator expressions">async</warning> for fun in funcs]
<warning descr="Python version 2.6 does not support set comprehensions">{<warning descr="Python version 2.6, 2.7, 3.4 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> fun()</warning> <warning descr="Python version 3.5 does not support 'async' inside comprehensions and generator expressions">async</warning> for fun in funcs}</warning>
<warning descr="Python version 2.6 does not support dictionary comprehensions">{fun: <warning descr="Python version 2.6, 2.7, 3.4 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> fun()</warning> <warning descr="Python version 3.5 does not support 'async' inside comprehensions and generator expressions">async</warning> for fun in funcs}</warning>
[<warning descr="Python versions < 3.5 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> fun()</warning> <warning descr="Python version 3.5 does not support 'async' inside comprehensions and generator expressions">async</warning> for fun in funcs if <warning descr="Python versions < 3.5 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> smth</warning>]
<warning descr="Python version 2.6 does not support set comprehensions">{<warning descr="Python versions < 3.5 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> fun()</warning> <warning descr="Python version 3.5 does not support 'async' inside comprehensions and generator expressions">async</warning> for fun in funcs if <warning descr="Python versions < 3.5 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> smth</warning>}</warning>
<warning descr="Python version 2.6 does not support dictionary comprehensions">{fun: <warning descr="Python versions < 3.5 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> fun()</warning> <warning descr="Python version 3.5 does not support 'async' inside comprehensions and generator expressions">async</warning> for fun in funcs if <warning descr="Python versions < 3.5 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> smth</warning>}</warning>
[<warning descr="Python version 2.6, 2.7, 3.4 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> fun()</warning> <warning descr="Python version 3.5 does not support 'async' inside comprehensions and generator expressions">async</warning> for fun in funcs if <warning descr="Python version 2.6, 2.7, 3.4 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> smth</warning>]
<warning descr="Python version 2.6 does not support set comprehensions">{<warning descr="Python version 2.6, 2.7, 3.4 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> fun()</warning> <warning descr="Python version 3.5 does not support 'async' inside comprehensions and generator expressions">async</warning> for fun in funcs if <warning descr="Python version 2.6, 2.7, 3.4 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> smth</warning>}</warning>
<warning descr="Python version 2.6 does not support dictionary comprehensions">{fun: <warning descr="Python version 2.6, 2.7, 3.4 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> fun()</warning> <warning descr="Python version 3.5 does not support 'async' inside comprehensions and generator expressions">async</warning> for fun in funcs if <warning descr="Python version 2.6, 2.7, 3.4 do not support this syntax"><warning descr="Python version 3.5 does not support 'await' inside comprehensions">await</warning> smth</warning>}</warning>
@@ -1,2 +1,2 @@
xs = {1: 2}
ys = {<warning descr="Python versions < 3.5 do not support starred expressions in dicts">**xs</warning>, 3: 4}
ys = {<warning descr="Python version 2.6, 2.7, 3.4 do not support starred expressions in dicts">**xs</warning>, 3: 4}
@@ -1,2 +1,2 @@
def foo():
<warning descr="Python versions < 3.0 do not support '...' outside of sequence slicings.">...</warning>
<warning descr="Python version 2.6, 2.7 do not support '...' outside of sequence slicings.">...</warning>
@@ -1,3 +1,3 @@
<error descr="Python version 2.7 does not have module builtins"><warning descr="Python version 2.6, 2.7 do not have module builtins">import builtins</warning></error>
<error descr="Python version 2.7 does not have module builtins"><warning descr="Python version 2.6 does not have module builtins">import builtins</warning></error>
<warning descr="Python version 3.4, 3.5, 3.6, 3.7 do not have module __builtin__">import __builtin__</warning>
@@ -1,2 +1,2 @@
x <warning descr="Python versions < 3.5 do not support matrix multiplication operators">@</warning> y
x <warning descr="Python versions < 3.5 do not support matrix multiplication operators">@=</warning> y
x <warning descr="Python version 2.6, 2.7, 3.4 do not support matrix multiplication operators">@</warning> y
x <warning descr="Python version 2.6, 2.7, 3.4 do not support matrix multiplication operators">@=</warning> y
@@ -1 +1 @@
<warning descr="Python version >= 3.0 do not support this syntax. The print statement has been replaced with a print() function">print "One value"</warning>
<warning descr="Python version 3.4, 3.5, 3.6, 3.7 do not support this syntax. The print statement has been replaced with a print() function">print "One value"</warning>
@@ -1,2 +1,2 @@
t = (1, <warning descr="Python versions < 3.5 do not support starred expressions in tuples, lists, and sets">*(2, 3)</warning>)
a, <warning descr="Python versions < 3.0 do not support starred expressions as assignment targets">*b</warning>, c = t
t = (1, <warning descr="Python version 2.6, 2.7, 3.4 do not support starred expressions in tuples, lists, and sets">*(2, 3)</warning>)
a, <warning descr="Python version 2.6, 2.7 do not support starred expressions as assignment targets">*b</warning>, c = t
@@ -2,22 +2,22 @@ a = u"String"
# Python 3.6
a = <error descr="Python version 2.7 does not support a 'F' prefix"><warning descr="Python version 2.6, 2.7, 3.4, 3.5 do not support a 'F' prefix">f</warning></error>""
a = <error descr="Python version 2.7 does not support a 'F' prefix"><warning descr="Python version 2.6, 2.7, 3.4, 3.5 do not support a 'F' prefix">F</warning></error>""
a = <error descr="Python version 2.7 does not support a 'RF' prefix"><warning descr="Python version 2.6, 2.7, 3.4, 3.5 do not support a 'RF' prefix">rf</warning></error>""
a = <error descr="Python version 2.7 does not support a 'FR' prefix"><warning descr="Python version 2.6, 2.7, 3.4, 3.5 do not support a 'FR' prefix">fr</warning></error>""
a = <error descr="Python version 2.7 does not support a 'FU' prefix"><warning descr="Python version 2.6, 2.7, 3.4, 3.5, 3.6, 3.7 do not support a 'FU' prefix">fu</warning></error>""
a = <error descr="Python version 2.7 does not support a 'UF' prefix"><warning descr="Python version 2.6, 2.7, 3.4, 3.5, 3.6, 3.7 do not support a 'UF' prefix">uf</warning></error>""
a = <error descr="Python version 2.7 does not support a 'BF' prefix"><warning descr="Python version 2.6, 2.7, 3.4, 3.5, 3.6, 3.7 do not support a 'BF' prefix">bf</warning></error>""
a = <error descr="Python version 2.7 does not support a 'FB' prefix"><warning descr="Python version 2.6, 2.7, 3.4, 3.5, 3.6, 3.7 do not support a 'FB' prefix">fb</warning></error>""
a = <error descr="Python version 2.7 does not support a 'UFR' prefix"><warning descr="Python version 2.6, 2.7, 3.4, 3.5, 3.6, 3.7 do not support a 'UFR' prefix">ufr</warning></error>""
a = <error descr="Python version 2.7 does not support a 'F' prefix"><warning descr="Python version 2.6, 3.4, 3.5 do not support a 'F' prefix">f</warning></error>""
a = <error descr="Python version 2.7 does not support a 'F' prefix"><warning descr="Python version 2.6, 3.4, 3.5 do not support a 'F' prefix">F</warning></error>""
a = <error descr="Python version 2.7 does not support a 'RF' prefix"><warning descr="Python version 2.6, 3.4, 3.5 do not support a 'RF' prefix">rf</warning></error>""
a = <error descr="Python version 2.7 does not support a 'FR' prefix"><warning descr="Python version 2.6, 3.4, 3.5 do not support a 'FR' prefix">fr</warning></error>""
a = <error descr="Python version 2.7 does not support a 'FU' prefix"><warning descr="Python version 2.6, 3.4, 3.5, 3.6, 3.7 do not support a 'FU' prefix">fu</warning></error>""
a = <error descr="Python version 2.7 does not support a 'UF' prefix"><warning descr="Python version 2.6, 3.4, 3.5, 3.6, 3.7 do not support a 'UF' prefix">uf</warning></error>""
a = <error descr="Python version 2.7 does not support a 'BF' prefix"><warning descr="Python version 2.6, 3.4, 3.5, 3.6, 3.7 do not support a 'BF' prefix">bf</warning></error>""
a = <error descr="Python version 2.7 does not support a 'FB' prefix"><warning descr="Python version 2.6, 3.4, 3.5, 3.6, 3.7 do not support a 'FB' prefix">fb</warning></error>""
a = <error descr="Python version 2.7 does not support a 'UFR' prefix"><warning descr="Python version 2.6, 3.4, 3.5, 3.6, 3.7 do not support a 'UFR' prefix">ufr</warning></error>""
# python 3.3
a = u""
a = r""
a = b""
a = <error descr="Python version 2.7 does not support a 'RB' prefix"><warning descr="Python version 2.6, 2.7 do not support a 'RB' prefix">rb</warning></error>""
a = <error descr="Python version 2.7 does not support a 'RB' prefix"><warning descr="Python version 2.6 does not support a 'RB' prefix">rb</warning></error>""
a = br""
# python 3.2, 3.1
@@ -48,9 +48,9 @@ a = <warning descr="Python version 3.4, 3.5, 3.6, 3.7 do not support a 'UR' pref
# combined, PY-32321
b = <warning descr="Python version 3.4, 3.5, 3.6, 3.7 do not allow to mix bytes and non-bytes literals">u"" b""</warning>
b = <warning descr="Python version 3.4, 3.5, 3.6, 3.7 do not allow to mix bytes and non-bytes literals">r"" b""</warning>
b = <warning descr="Python version 3.4, 3.5, 3.6, 3.7 do not allow to mix bytes and non-bytes literals"><error descr="Python version 2.7 does not support a 'F' prefix"><warning descr="Python version 2.6, 2.7, 3.4, 3.5 do not support a 'F' prefix">f</warning></error>"" b""</warning>
b = <warning descr="Python version 3.4, 3.5, 3.6, 3.7 do not allow to mix bytes and non-bytes literals"><error descr="Python version 2.7 does not support a 'F' prefix"><warning descr="Python version 2.6, 3.4, 3.5 do not support a 'F' prefix">f</warning></error>"" b""</warning>
# never was available
a = <error descr="Python version 2.7 does not support a 'RR' prefix"><warning descr="Python version 2.6, 2.7, 3.4, 3.5, 3.6, 3.7 do not support a 'RR' prefix">rr</warning></error>""
a = <error descr="Python version 2.7 does not support a 'BB' prefix"><warning descr="Python version 2.6, 2.7, 3.4, 3.5, 3.6, 3.7 do not support a 'BB' prefix">bb</warning></error>""
a = <error descr="Python version 2.7 does not support a 'UU' prefix"><warning descr="Python version 2.6, 2.7, 3.4, 3.5, 3.6, 3.7 do not support a 'UU' prefix">uu</warning></error>""
a = <error descr="Python version 2.7 does not support a 'RR' prefix"><warning descr="Python version 2.6, 3.4, 3.5, 3.6, 3.7 do not support a 'RR' prefix">rr</warning></error>""
a = <error descr="Python version 2.7 does not support a 'BB' prefix"><warning descr="Python version 2.6, 3.4, 3.5, 3.6, 3.7 do not support a 'BB' prefix">bb</warning></error>""
a = <error descr="Python version 2.7 does not support a 'UU' prefix"><warning descr="Python version 2.6, 3.4, 3.5, 3.6, 3.7 do not support a 'UU' prefix">uu</warning></error>""
@@ -2,5 +2,5 @@ def foo(*args, **kwargs):
print(args, kwargs)
foo(1, 2, 3, *[3]<error descr="Python versions < 3.5 do not allow a trailing comma after *expression"><warning descr="Python versions < 3.5 do not allow a trailing comma after *expression">,</warning></error>)
foo(1, 2, 3, *[3], **{'d': 'd'}<error descr="Python versions < 3.5 do not allow a trailing comma after **expression"><warning descr="Python versions < 3.5 do not allow a trailing comma after **expression">,</warning></error>)
foo(1, 2, 3, *[3]<error descr="Python version 3.4 does not allow a trailing comma after *expression"><warning descr="Python version 2.6, 2.7 do not allow a trailing comma after *expression">,</warning></error>)
foo(1, 2, 3, *[3], **{'d': 'd'}<error descr="Python version 3.4 does not allow a trailing comma after **expression"><warning descr="Python version 2.6, 2.7 do not allow a trailing comma after **expression">,</warning></error>)
@@ -1,4 +1,4 @@
try:
raise ValueError
finally:
<error descr="Python version 2.7 does not support this syntax. Raise with no arguments can only be used in an except block"><warning descr="Python version 2.6, 2.7 do not support this syntax. Raise with no arguments can only be used in an except block">raise</warning></error>
<error descr="Python version 2.7 does not support this syntax. Raise with no arguments can only be used in an except block"><warning descr="Python version 2.6 does not support this syntax. Raise with no arguments can only be used in an except block">raise</warning></error>
@@ -3,7 +3,7 @@
# oct
<warning descr="Python version 2.6, 2.7, 3.4, 3.5 do not support underscores in numeric literals">0o1_23</warning>
<error descr="Python version 3.6 does not support this syntax. It requires '0o' prefix for octal literals"><warning descr="Python version 2.6, 2.7, 3.4, 3.5 do not support underscores in numeric literals"><warning descr="Python version 3.4, 3.5, 3.6, 3.7 do not support this syntax. It requires '0o' prefix for octal literals">01_23</warning></warning></error>
<error descr="Python version 3.6 does not support this syntax. It requires '0o' prefix for octal literals"><warning descr="Python version 2.6, 2.7, 3.4, 3.5 do not support underscores in numeric literals"><warning descr="Python version 3.4, 3.5, 3.7 do not support this syntax. It requires '0o' prefix for octal literals">01_23</warning></warning></error>
# bin
<warning descr="Python version 2.6, 2.7, 3.4, 3.5 do not support underscores in numeric literals">0b_0011_1111_0100_1110</warning>
@@ -1,14 +1,14 @@
class <warning descr="'async' and 'await' are keywords in Python 3.7 and newer">async</warning>(object):
class <warning descr="Python version 3.7 does not allow 'async' and 'await' as names">async</warning>(object):
pass
class <warning descr="'async' and 'await' are keywords in Python 3.7 and newer">await</warning>(object):
class <warning descr="Python version 3.7 does not allow 'async' and 'await' as names">await</warning>(object):
pass
def <warning descr="'async' and 'await' are keywords in Python 3.7 and newer">async</warning>():
def <warning descr="Python version 3.7 does not allow 'async' and 'await' as names">async</warning>():
pass
def <warning descr="'async' and 'await' are keywords in Python 3.7 and newer">await</warning>():
def <warning descr="Python version 3.7 does not allow 'async' and 'await' as names">await</warning>():
pass
<warning descr="'async' and 'await' are keywords in Python 3.7 and newer">async</warning> = 1
<warning descr="'async' and 'await' are keywords in Python 3.7 and newer">await</warning> = 2
<warning descr="Python version 3.7 does not allow 'async' and 'await' as names">async</warning> = 1
<warning descr="Python version 3.7 does not allow 'async' and 'await' as names">await</warning> = 2
@@ -1,5 +1,5 @@
<warning descr="Python versions < 3.5 do not support this syntax">async</warning> def foo(x):
<warning descr="Python versions < 3.5 do not support this syntax">await x</warning>
<warning descr="Python version 2.6, 2.7, 3.4 do not support this syntax">async</warning> def foo(x):
<warning descr="Python version 2.6, 2.7, 3.4 do not support this syntax">await x</warning>
<warning descr="Python version 3.5 does not support 'yield' inside async functions">yield x</warning>
<error descr="Python does not support 'yield from' inside async functions"><warning descr="Python versions < 3.3 do not support this syntax. Delegating to a subgenerator is available since Python 3.3; use explicit iteration over subgenerator instead.">yield from x</warning></error>
<error descr="Python does not support 'yield from' inside async functions"><warning descr="Python version 2.6, 2.7 do not support this syntax. Delegating to a subgenerator is available since Python 3.3; use explicit iteration over subgenerator instead.">yield from x</warning></error>
<error descr="non-empty 'return' inside asynchronous generator"><warning descr="Python versions < 3.3 do not allow 'return' with argument inside generator.">return x</warning></error>
@@ -3,8 +3,8 @@ def foo():
print x
def test_vlu():
<error descr="Python versions < 3.0 do not support starred expressions as assignment targets">*<weak_warning descr="Local variable 'h' value is not used">h</weak_warning></error>, <weak_warning descr="Local variable 't' value is not used">t</weak_warning> = [1, 2, 3] # fail
<error descr="Python version 2.6 does not support starred expressions as assignment targets">*<weak_warning descr="Local variable 'h' value is not used">h</weak_warning></error>, <weak_warning descr="Local variable 't' value is not used">t</weak_warning> = [1, 2, 3] # fail
def test_vlu():
<error descr="Python versions < 3.0 do not support starred expressions as assignment targets">*h</error>, t = [1, 2, 3] # pass
<error descr="Python version 2.6 does not support starred expressions as assignment targets">*h</error>, t = [1, 2, 3] # pass
print(t)
+1 -1
View File
@@ -1 +1 @@
<warning descr="Python version >= 3.0 do not support this syntax. The print statement has been replaced with a print() function">print <caret>"foo"</warning>
<warning descr="Python version 3.4, 3.5, 3.6, 3.7 do not support this syntax. The print statement has been replaced with a print() function">print "foo"</warning>
@@ -3,6 +3,6 @@ def foo(*args):
a = ()
b = ()
foo(*a, <error descr="Python versions < 3.5 do not allow duplicate *expressions">*<caret>b</error>)
foo(*a, <error descr="Python version 2.7 does not allow duplicate *expressions">*<caret>b</error>)
@@ -4,6 +4,6 @@ def foo(**args):
a = {}
b = {}
foo(**a, <error descr="Python versions < 3.5 do not allow duplicate **expressions">**<caret>b</error>)
foo(**a, <error descr="Python version 2.7 does not allow duplicate **expressions">**<caret>b</error>)
@@ -2,6 +2,6 @@ def foo(a, **args):
pass
b = {}
foo(**b, <error descr="Python versions < 3.5 do not allow keyword arguments after **expression">a<caret>=1</error>)
foo(**b, <error descr="Python version 2.7 does not allow keyword arguments after **expression">a<caret>=1</error>)
@@ -1,2 +1,2 @@
class <warning descr="'async' and 'await' are keywords in Python 3.7 and newer">a<caret>sync</warning>(object):
class <warning descr="Python version 3.7 does not allow 'async' and 'await' as names">a<caret>sync</warning>(object):
pass
@@ -1,2 +1,2 @@
def <warning descr="'async' and 'await' are keywords in Python 3.7 and newer">a<caret>sync</warning>():
def <warning descr="Python version 3.7 does not allow 'async' and 'await' as names">a<caret>sync</warning>():
pass
@@ -1 +1 @@
<warning descr="'async' and 'await' are keywords in Python 3.7 and newer">async</warning> = 1
<warning descr="Python version 3.7 does not allow 'async' and 'await' as names">async</warning> = 1
@@ -1,2 +1,2 @@
class <warning descr="'async' and 'await' are keywords in Python 3.7 and newer">a<caret>wait</warning>(object):
class <warning descr="Python version 3.7 does not allow 'async' and 'await' as names">a<caret>wait</warning>(object):
pass
@@ -1,2 +1,2 @@
def <warning descr="'async' and 'await' are keywords in Python 3.7 and newer">a<caret>wait</warning>():
def <warning descr="Python version 3.7 does not allow 'async' and 'await' as names">a<caret>wait</warning>():
pass
@@ -1 +1 @@
<warning descr="'async' and 'await' are keywords in Python 3.7 and newer">await</warning> = 1
<warning descr="Python version 3.7 does not allow 'async' and 'await' as names">await</warning> = 1