mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
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:
@@ -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)
|
||||
|
||||
+1
-1
@@ -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>)
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+7
-7
@@ -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>
|
||||
+1
-1
@@ -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>
|
||||
|
||||
+6
-6
@@ -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 @@
|
||||
<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
|
||||
Reference in New Issue
Block a user