diff --git a/python/python-psi-impl/resources/messages/PyPsiBundle.properties b/python/python-psi-impl/resources/messages/PyPsiBundle.properties index c760ad7fa77f..c750a04b64b8 100644 --- a/python/python-psi-impl/resources/messages/PyPsiBundle.properties +++ b/python/python-psi-impl/resources/messages/PyPsiBundle.properties @@ -434,8 +434,6 @@ python.docstring.select.type=Select Docstring Type ### Inspections: INSP ### INSP.GROUP.python=Python -INSP.compatibility.this.syntax.available.only.since.py3=This syntax available only since py3 -INSP.compatibility.check.for.compatibility.with.python.versions=Check for compatibility with python versions: INSP.abstract.class.set.as.metaclass=Set ''{0}'' as metaclass INSP.abstract.class.add.to.superclasses=Add ''{0}'' to superclasses INSP.pep8.naming=PEP 8 naming convention violation @@ -663,6 +661,59 @@ INSP.oldstyle.class.super=Old-style class contains call for super method # PyCompatibilityInspection INSP.NAME.compatibility=Code compatibility inspection +INSP.compatibility.this.syntax.available.only.since.py3=This syntax available only since py3 +INSP.compatibility.check.for.compatibility.with.python.versions=Check for compatibility with python versions: +INSP.compatibility.inspection.unsupported.feature.prefix=Python {0,choice,1#version|2#versions} {1} {0,choice,1#does|2#do} not {2} +INSP.compatibility.feature.support.variable.annotations=support variable annotations +INSP.compatibility.feature.support.dictionary.comprehensions=support dictionary comprehensions +INSP.compatibility.feature.support.set.literal.expressions=support set literal expressions +INSP.compatibility.feature.support.set.comprehensions=support set comprehensions +INSP.compatibility.feature.support.this.syntax=support this syntax +INSP.compatibility.feature.have.module.builtins=have module builtins +INSP.compatibility.feature.have.module.builtin=have module __builtin__ +INSP.compatibility.feature.support.starred.expressions.as.assignment.targets=support starred expressions as assignment targets +INSP.compatibility.feature.support.starred.expressions.in.tuples.lists.and.sets=support starred expressions in tuples, lists, and sets +INSP.compatibility.feature.support.unpacking.without.parentheses.in.return.statements=support unpacking without parentheses in return statements +INSP.compatibility.feature.support.unpacking.without.parentheses.in.yield.statements=support unpacking without parentheses in yield statements +INSP.compatibility.feature.support.starred.expressions.in.dicts=support starred expressions in dicts +INSP.compatibility.feature.support.diamond.operator=support <>, use != instead +INSP.compatibility.feature.support.matrix.multiplication.operators=support matrix multiplication operators +INSP.compatibility.feature.support.long.integer.literal.suffix=support a trailing ''{0}'' +INSP.compatibility.feature.support.old.style.octal.literals=support this syntax. It requires '0o' prefix for octal literals +INSP.compatibility.feature.support.underscores.in.numeric.literals=support underscores in numeric literals +INSP.compatibility.feature.support.string.literal.prefix=support a ''{0}'' prefix +INSP.compatibility.feature.allow.to.mix.bytes.and.non.bytes.literals=allow to mix bytes and non-bytes literals +INSP.compatibility.feature.support.this.syntax.in.list.comprehensions=support this syntax in list comprehensions +INSP.compatibility.feature.support.raise.with.no.arguments.outside.except.block=support this syntax. Raise with no arguments can only be used in an except block +INSP.compatibility.feature.support.backquotes=support backquotes, use repr() instead +INSP.compatibility.feature.support.multiple.context.managers=support multiple context managers +INSP.compatibility.feature.support.print.statement=support this syntax. The print statement has been replaced with a print() function +INSP.compatibility.feature.support.super.without.arguments=support this syntax. super() should have arguments in Python 2 +INSP.compatibility.py35.does.not.support.yield.inside.async.functions=Python version 3.5 does not support 'yield' inside async functions +INSP.compatibility.feature.support.yield.from=support this syntax. Delegating to a subgenerator is available since Python 3.3; use explicit iteration over subgenerator instead. +INSP.compatibility.pre35.versions.do.not.allow.return.with.argument.inside.generator=Python versions < 3.3 do not allow 'return' with argument inside generator. +INSP.compatibility.feature.support.ellipsis.outside.slices=support '...' outside of sequence slicings +INSP.compatibility.feature.have.nonlocal.keyword=have nonlocal keyword +INSP.compatibility.keyword.argument.repeated=Keyword argument repeated +INSP.compatibility.feature.allow.keyword.arguments.after.kwargs=allow keyword arguments after **expression +INSP.compatibility.feature.allow.duplicate.kwargs=allow duplicate **expressions +INSP.compatibility.feature.allow.duplicate.positional.varargs=allow duplicate *expressions +INSP.compatibility.feature.allow.positional.arguments.after.expression=allow positional arguments after *expression +INSP.compatibility.positional.argument.after.keyword.argument=Positional argument after keyword argument +INSP.compatibility.positional.argument.after.kwargs=Positional argument after **expression +INSP.compatibility.feature.allow.trailing.comma.after.kwargs=allow a trailing comma after **expression +INSP.compatibility.feature.allow.trailing.comma.after.positional.vararg=allow a trailing comma after *expression +INSP.compatibility.py35.does.not.support.async.inside.comprehensions.and.generator.expressions=Python version 3.5 does not support 'async' inside comprehensions and generator expressions +INSP.compatibility.py35.does.not.support.await.inside.comprehensions=Python version 3.5 does not support 'await' inside comprehensions +INSP.compatibility.feature.support.positional.only.parameters=support positional-only parameters +INSP.compatibility.support.equality.signs.in.fstrings=support equality signs in f-strings +INSP.compatibility.feature.support.assignment.expressions=support assignment expressions +INSP.compatibility.feature.support.continue.inside.finally.clause=support 'continue' inside 'finally' clause +INSP.compatibility.feature.support.arbitrary.expressions.as.decorator=support arbitrary expressions as a decorator +INSP.compatibility.feature.have.type.long=have type long. Use int instead. +INSP.compatibility.feature.have.method=have method {0} +INSP.compatibility.feature.have.module=have module {0} +INSP.compatibility.feature.allow.async.and.await.as.names=allow 'async' and 'await' as names # PyUnnecessaryBackslashInspection INSP.NAME.unnecessary.backslash=Unnecessary backslash diff --git a/python/python-psi-impl/src/com/jetbrains/python/inspections/PyCompatibilityInspection.java b/python/python-psi-impl/src/com/jetbrains/python/inspections/PyCompatibilityInspection.java index d0c9eeac2f52..4c01e652e21f 100644 --- a/python/python-psi-impl/src/com/jetbrains/python/inspections/PyCompatibilityInspection.java +++ b/python/python-psi-impl/src/com/jetbrains/python/inspections/PyCompatibilityInspection.java @@ -20,6 +20,7 @@ import com.intellij.codeInspection.InspectionProfile; import com.intellij.codeInspection.LocalQuickFix; import com.intellij.codeInspection.ProblemHighlightType; import com.intellij.codeInspection.ProblemsHolder; +import com.intellij.codeInspection.util.InspectionMessage; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.JDOMExternalizableStringList; @@ -139,7 +140,7 @@ public class PyCompatibilityInspection extends PyInspection { @Override protected void registerProblem(@NotNull PsiElement element, @NotNull TextRange range, - @NotNull String message, + @NotNull @InspectionMessage String message, @Nullable LocalQuickFix quickFix, boolean asError) { if (element.getTextLength() == 0) { @@ -182,7 +183,7 @@ public class PyCompatibilityInspection extends PyInspection { final Map> unsupportedMethods = UnsupportedFeaturesUtil.CLASS_METHODS.get(className); registerForAllMatchingVersions(level -> unsupportedMethods.getOrDefault(level, Collections.emptySet()).contains(functionName), - " not have method " + functionName, + PyPsiBundle.message("INSP.compatibility.feature.have.method", functionName), node); } } @@ -192,7 +193,7 @@ public class PyCompatibilityInspection extends PyInspection { !"exec".equals(functionName) && !myUsedImports.contains(functionName)) { registerForAllMatchingVersions(level -> UnsupportedFeaturesUtil.BUILTINS.get(level).contains(functionName), - " not have method " + functionName, + PyPsiBundle.message("INSP.compatibility.feature.have.method", functionName), node); } } @@ -203,7 +204,7 @@ public class PyCompatibilityInspection extends PyInspection { PyNames.TYPE_LONG.equals(target.getName()) && PyBuiltinCache.getInstance(resolvedCallee).isBuiltin(resolvedCallee)) { registerForAllMatchingVersions(level -> UnsupportedFeaturesUtil.BUILTINS.get(level).contains(PyNames.TYPE_LONG), - " not have type long. Use int instead.", + PyPsiBundle.message("INSP.compatibility.feature.have.type.long"), node); } } @@ -234,7 +235,7 @@ public class PyCompatibilityInspection extends PyInspection { final String moduleName = qName.toString(); registerForAllMatchingVersions(level -> UnsupportedFeaturesUtil.MODULES.get(level).contains(moduleName) && !BACKPORTED_PACKAGES.contains(moduleName), - " not have module " + moduleName, + PyPsiBundle.message("INSP.compatibility.feature.have.module", moduleName), importElement); } } @@ -264,7 +265,7 @@ public class PyCompatibilityInspection extends PyInspection { final String moduleName = name.toString(); registerForAllMatchingVersions(level -> UnsupportedFeaturesUtil.MODULES.get(level).contains(moduleName) && !BACKPORTED_PACKAGES.contains(moduleName), - " not have module " + name, + PyPsiBundle.message("INSP.compatibility.feature.have.module", name), source); } } @@ -353,7 +354,7 @@ public class PyCompatibilityInspection extends PyInspection { ArrayUtil.contains(nameIdentifierOwner.getName(), PyNames.AWAIT, PyNames.ASYNC) && LanguageLevel.forElement(nameIdentifierOwner).isOlderThan(LanguageLevel.PYTHON37)) { registerForAllMatchingVersions(level -> level.isAtLeast(LanguageLevel.PYTHON37), - " not allow 'async' and 'await' as names", + PyPsiBundle.message("INSP.compatibility.feature.allow.async.and.await.as.names"), nameIdentifier, PythonUiService.getInstance().createPyRenameElementQuickFix(nameIdentifierOwner)); } diff --git a/python/python-psi-impl/src/com/jetbrains/python/validation/CompatibilityVisitor.java b/python/python-psi-impl/src/com/jetbrains/python/validation/CompatibilityVisitor.java index e9f0247a669b..a315a4c3279a 100644 --- a/python/python-psi-impl/src/com/jetbrains/python/validation/CompatibilityVisitor.java +++ b/python/python-psi-impl/src/com/jetbrains/python/validation/CompatibilityVisitor.java @@ -3,7 +3,9 @@ package com.jetbrains.python.validation; import com.google.common.collect.Sets; import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.util.InspectionMessage; import com.intellij.lang.ASTNode; +import com.intellij.openapi.util.NlsSafe; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; @@ -17,11 +19,13 @@ import com.intellij.psi.util.QualifiedName; import com.intellij.util.ArrayUtil; import com.intellij.util.containers.ContainerUtil; import com.jetbrains.python.PyNames; +import com.jetbrains.python.PyPsiBundle; import com.jetbrains.python.PyTokenTypes; import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil; import com.jetbrains.python.inspections.quickfix.*; import com.jetbrains.python.psi.*; import com.jetbrains.python.psi.impl.PyPsiUtils; +import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -44,9 +48,6 @@ public abstract class CompatibilityVisitor extends PyAnnotator { @NotNull private static final Set PYTHON36_PREFIXES = Sets.newHashSet("R", "U", "B", "BR", "RB", "F", "FR", "RF"); - @NotNull - protected static final String COMMON_MESSAGE = "Python version "; - @NotNull protected List myVersionsToProcess; @@ -59,7 +60,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { final PsiElement parent = node.getParent(); if (!(parent instanceof PyFunction || parent instanceof PyNamedParameter)) { registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON36) && registerForLanguageLevel(level), - " not support variable annotations", + PyPsiBundle.message("INSP.compatibility.feature.support.variable.annotations"), node); } } @@ -69,7 +70,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { super.visitPyDictCompExpression(node); registerForAllMatchingVersions(level -> !level.supportsSetLiterals() && registerForLanguageLevel(level), - " not support dictionary comprehensions", + PyPsiBundle.message("INSP.compatibility.feature.support.dictionary.comprehensions"), node, new ConvertDictCompQuickFix(), false); @@ -80,7 +81,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { super.visitPySetLiteralExpression(node); registerForAllMatchingVersions(level -> !level.supportsSetLiterals() && registerForLanguageLevel(level), - " not support set literal expressions", + PyPsiBundle.message("INSP.compatibility.feature.support.set.literal.expressions"), node, new ConvertSetLiteralQuickFix(), false); @@ -91,7 +92,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { super.visitPySetCompExpression(node); registerForAllMatchingVersions(level -> !level.supportsSetLiterals() && registerForLanguageLevel(level), - " not support set comprehensions", + PyPsiBundle.message("INSP.compatibility.feature.support.set.comprehensions"), node, null, false); @@ -110,7 +111,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { if (element != null && ",".equals(element.getText())) { registerForAllMatchingVersions(level -> level.isPy3K() && registerForLanguageLevel(level), - " not support this syntax.", + PyPsiBundle.message("INSP.compatibility.feature.support.this.syntax"), node, new ReplaceExceptPartQuickFix()); } @@ -130,13 +131,13 @@ public abstract class CompatibilityVisitor extends PyAnnotator { if (qName != null) { if (qName.matches("builtins")) { registerForAllMatchingVersions(level -> level.isPython2() && registerForLanguageLevel(level), - " not have module builtins", + PyPsiBundle.message("INSP.compatibility.feature.have.module.builtins"), node, new ReplaceBuiltinsQuickFix()); } else if (qName.matches("__builtin__")) { registerForAllMatchingVersions(level -> level.isPy3K() && registerForLanguageLevel(level), - " not have module __builtin__", + PyPsiBundle.message("INSP.compatibility.feature.have.module.builtin"), node, new ReplaceBuiltinsQuickFix()); } @@ -150,13 +151,13 @@ public abstract class CompatibilityVisitor extends PyAnnotator { if (node.isAssignmentTarget()) { registerForAllMatchingVersions(level -> level.isPython2() && registerForLanguageLevel(level), - " not support starred expressions as assignment targets", + PyPsiBundle.message("INSP.compatibility.feature.support.starred.expressions.as.assignment.targets"), node); } if (node.isUnpacking()) { registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON35) && registerForLanguageLevel(level), - " not support starred expressions in tuples, lists, and sets", + PyPsiBundle.message("INSP.compatibility.feature.support.starred.expressions.in.tuples.lists.and.sets"), node); final PsiElement container = PsiTreeUtil.skipParentsOfType(node, PyParenthesizedExpression.class); if (container instanceof PyTupleExpression) { @@ -165,7 +166,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { registerForAllMatchingVersions(level -> level.isAtLeast(LanguageLevel.PYTHON35) && level.isOlderThan(LanguageLevel.PYTHON38) && registerForLanguageLevel(level), - " not support unpacking without parentheses in return statements", + PyPsiBundle.message("INSP.compatibility.feature.support.unpacking.without.parentheses.in.return.statements"), node); } @@ -173,7 +174,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { registerForAllMatchingVersions(level -> level.isAtLeast(LanguageLevel.PYTHON35) && level.isOlderThan(LanguageLevel.PYTHON38) && registerForLanguageLevel(level), - " not support unpacking without parentheses in yield statements", + PyPsiBundle.message("INSP.compatibility.feature.support.unpacking.without.parentheses.in.yield.statements"), node); } } @@ -185,7 +186,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { super.visitPyDoubleStarExpression(node); registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON35) && registerForLanguageLevel(level), - " not support starred expressions in dicts", + PyPsiBundle.message("INSP.compatibility.feature.support.starred.expressions.in.dicts"), node); } @@ -195,7 +196,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { if (node.isOperator("<>")) { registerForAllMatchingVersions(level -> level.isPy3K() && registerForLanguageLevel(level), - " not support <>, use != instead.", + PyPsiBundle.message("INSP.compatibility.feature.support.diamond.operator"), node, new ReplaceNotEqOperatorQuickFix()); } @@ -206,7 +207,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { private void checkMatrixMultiplicationOperator(PsiElement node) { registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON35) && registerForLanguageLevel(level), - " not support matrix multiplication operators", + PyPsiBundle.message("INSP.compatibility.feature.support.matrix.multiplication.operators"), node); } @@ -220,7 +221,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { String suffix = node.getIntegerLiteralSuffix(); if ("l".equalsIgnoreCase(suffix)) { registerForAllMatchingVersions(level -> level.isPy3K() && registerForLanguageLevel(level), - " not support a trailing '" + suffix + "'.", + PyPsiBundle.message("INSP.compatibility.feature.support.long.integer.literal.suffix", suffix), node, new RemoveTrailingSuffixQuickFix()); } @@ -229,7 +230,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { final char secondChar = Character.toLowerCase(text.charAt(1)); if (secondChar != 'o' && secondChar != 'b' && secondChar != 'x' && text.chars().anyMatch(c -> c != '0')) { registerForAllMatchingVersions(level -> level.isPy3K() && registerForLanguageLevel(level), - " not support this syntax. It requires '0o' prefix for octal literals", + PyPsiBundle.message("INSP.compatibility.feature.support.old.style.octal.literals"), node, new ReplaceOctalNumericLiteralQuickFix()); } @@ -238,7 +239,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { if (text.contains("_")) { registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON36) && registerForLanguageLevel(level), - " not support underscores in numeric literals", + PyPsiBundle.message("INSP.compatibility.feature.support.underscores.in.numeric.literals"), node, new PyRemoveUnderscoresInNumericLiteralsQuickFix()); } @@ -260,7 +261,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { final int elementStart = element.getTextOffset(); registerForAllMatchingVersions(level -> !getSupportedStringPrefixes(level).contains(prefix) && registerForLanguageLevel(level), - " not support a '" + prefix + "' prefix", + PyPsiBundle.message("INSP.compatibility.feature.support.string.literal.prefix", prefix), node, TextRange.create(elementStart, elementStart + element.getPrefixLength()), new RemovePrefixQuickFix(prefix), @@ -269,7 +270,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { if (seenBytes && seenNonBytes) { registerForAllMatchingVersions(level -> level.isPy3K() && registerForLanguageLevel(level), - " not allow to mix bytes and non-bytes literals", + PyPsiBundle.message("INSP.compatibility.feature.allow.to.mix.bytes.and.non.bytes.literals"), node); } } @@ -293,7 +294,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { registerForAllMatchingVersions( level -> registerForLanguageLevel(level) && UnsupportedFeaturesUtil.visitPyListCompExpression(node, level), - " not support this syntax in list comprehensions.", + PyPsiBundle.message("INSP.compatibility.feature.support.this.syntax.in.list.comprehensions"), ContainerUtil.map(node.getForComponents(), PyComprehensionForComponent::getIteratedList), new ReplaceListComprehensionsQuickFix() ); @@ -306,19 +307,19 @@ public abstract class CompatibilityVisitor extends PyAnnotator { // empty raise under finally registerForAllMatchingVersions( level -> registerForLanguageLevel(level) && UnsupportedFeaturesUtil.raiseHasNoArgsUnderFinally(node, level), - " not support this syntax. Raise with no arguments can only be used in an except block", + PyPsiBundle.message("INSP.compatibility.feature.support.raise.with.no.arguments.outside.except.block"), node ); // raise 1, 2, 3 registerForAllMatchingVersions(level -> registerForLanguageLevel(level) && UnsupportedFeaturesUtil.raiseHasMoreThenOneArg(node, level), - " not support this syntax.", + PyPsiBundle.message("INSP.compatibility.feature.support.this.syntax"), node, new ReplaceRaiseStatementQuickFix()); // raise exception from cause registerForAllMatchingVersions(level -> registerForLanguageLevel(level) && UnsupportedFeaturesUtil.raiseHasFromKeyword(node, level), - " not support this syntax.", + PyPsiBundle.message("INSP.compatibility.feature.support.this.syntax"), node, new ReplaceRaiseStatementQuickFix()); } @@ -328,7 +329,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { super.visitPyReprExpression(node); registerForAllMatchingVersions(level -> level.isPy3K() && registerForLanguageLevel(level), - " not support backquotes, use repr() instead", + PyPsiBundle.message("INSP.compatibility.feature.support.backquotes"), node, new ReplaceBackquoteExpressionQuickFix()); } @@ -341,7 +342,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { final PyWithItem[] items = node.getWithItems(); if (items.length > 1) { registerForAllMatchingVersions(level -> !level.supportsSetLiterals() && registerForLanguageLevel(level), - " not support multiple context managers", + PyPsiBundle.message("INSP.compatibility.feature.support.multiple.context.managers"), Arrays.asList(items).subList(1, items.length), null); } @@ -365,8 +366,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { if (arguments.length == 0 || Arrays.stream(arguments).anyMatch(nonParenthesesPredicate)) { registerForAllMatchingVersions(level -> level.isPy3K() && registerForLanguageLevel(level), - " not support this syntax. " + - "The print statement has been replaced with a print() function", + PyPsiBundle.message("INSP.compatibility.feature.support.print.statement"), node, new CompatibilityPrintCallQuickFix()); } @@ -379,7 +379,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { final PsiElement firstChild = node.getFirstChild(); if (firstChild != null && PyNames.SUPER.equals(firstChild.getText()) && ArrayUtil.isEmpty(node.getArguments())) { registerForAllMatchingVersions(level -> level.isPython2() && registerForLanguageLevel(level), - " not support this syntax. super() should have arguments in Python 2", + PyPsiBundle.message("INSP.compatibility.feature.support.super.without.arguments"), node); } @@ -398,7 +398,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { if (node.getOperator() == PyTokenTypes.AWAIT_KEYWORD) { registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON35) && registerForLanguageLevel(level), - " not support this syntax", + PyPsiBundle.message("INSP.compatibility.feature.support.this.syntax"), node); } } @@ -416,7 +416,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { if (!node.isDelegating() && registerForLanguageLevel(LanguageLevel.PYTHON35) && myVersionsToProcess.contains(LanguageLevel.PYTHON35)) { - registerProblem(node, "Python version 3.5 does not support 'yield' inside async functions"); + registerProblem(node, PyPsiBundle.message("INSP.compatibility.py35.does.not.support.yield.inside.async.functions")); } } ); @@ -426,8 +426,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { } 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.", + PyPsiBundle.message("INSP.compatibility.feature.support.yield.from"), node); } @@ -439,7 +438,8 @@ public abstract class CompatibilityVisitor extends PyAnnotator { final YieldVisitor visitor = new YieldVisitor(); function.acceptChildren(visitor); if (visitor.haveYield()) { - registerProblem(node, "Python versions < 3.3 do not allow 'return' with argument inside generator."); + registerProblem(node, + PyPsiBundle.message("INSP.compatibility.pre35.versions.do.not.allow.return.with.argument.inside.generator")); } } } @@ -457,7 +457,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { return; } registerForAllMatchingVersions(level -> level.isPython2() && registerForLanguageLevel(level), - " not support '...' outside of sequence slicings.", + PyPsiBundle.message("INSP.compatibility.feature.support.ellipsis.outside.slices"), node); } } @@ -478,7 +478,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { final ASTNode asyncNode = node.getNode().findChildByType(PyTokenTypes.ASYNC_KEYWORD); if (asyncNode != null) { registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON35) && registerForLanguageLevel(level), - " not support this syntax", + PyPsiBundle.message("INSP.compatibility.feature.support.this.syntax"), node, asyncNode.getTextRange(), null, @@ -517,15 +517,17 @@ public abstract class CompatibilityVisitor extends PyAnnotator { protected abstract void registerProblem(@NotNull PsiElement node, @NotNull TextRange range, - @NotNull String message, + @NotNull @InspectionMessage String message, @Nullable LocalQuickFix localQuickFix, boolean asError); - protected void registerProblem(@NotNull PsiElement node, @NotNull String message, @Nullable LocalQuickFix localQuickFix) { + protected void registerProblem(@NotNull PsiElement node, + @NotNull @InspectionMessage String message, + @Nullable LocalQuickFix localQuickFix) { registerProblem(node, node.getTextRange(), message, localQuickFix, true); } - protected void registerProblem(@NotNull PsiElement node, @NotNull String message) { + protected void registerProblem(@NotNull PsiElement node, @NotNull @InspectionMessage String message) { registerProblem(node, message, null); } @@ -534,7 +536,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { } protected void registerForAllMatchingVersions(@NotNull Predicate levelPredicate, - @NotNull String suffix, + @NotNull @Nls String suffix, @NotNull Iterable> nodesWithRanges, @Nullable LocalQuickFix localQuickFix, boolean asError) { @@ -545,15 +547,17 @@ public abstract class CompatibilityVisitor extends PyAnnotator { .collect(Collectors.toList()); if (!levels.isEmpty()) { - final String result = COMMON_MESSAGE + StringUtil.join(levels, ", ") + (levels.size() == 1 ? " does" : " do") + suffix; + @NlsSafe String versions = StringUtil.join(levels, ", "); + @InspectionMessage String message = PyPsiBundle.message("INSP.compatibility.inspection.unsupported.feature.prefix", + levels.size(), versions, suffix); for (Pair nodeWithRange : nodesWithRanges) { - registerProblem(nodeWithRange.first, nodeWithRange.second, result, localQuickFix, asError); + registerProblem(nodeWithRange.first, nodeWithRange.second, message, localQuickFix, asError); } } } protected void registerForAllMatchingVersions(@NotNull Predicate levelPredicate, - @NotNull String suffix, + @NotNull @Nls String suffix, @NotNull Iterable nodes, @Nullable LocalQuickFix localQuickFix) { final List> nodesWithRanges = @@ -562,7 +566,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { } protected void registerForAllMatchingVersions(@NotNull Predicate levelPredicate, - @NotNull String suffix, + @NotNull @Nls String suffix, @NotNull PsiElement node, @NotNull TextRange range, @Nullable LocalQuickFix localQuickFix, @@ -572,7 +576,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { } protected void registerForAllMatchingVersions(@NotNull Predicate levelPredicate, - @NotNull String suffix, + @NotNull @Nls String suffix, @NotNull PsiElement node, @Nullable LocalQuickFix localQuickFix, boolean asError) { @@ -580,14 +584,14 @@ public abstract class CompatibilityVisitor extends PyAnnotator { } protected void registerForAllMatchingVersions(@NotNull Predicate levelPredicate, - @NotNull String suffix, + @NotNull @Nls String suffix, @NotNull PsiElement node, @Nullable LocalQuickFix localQuickFix) { registerForAllMatchingVersions(levelPredicate, suffix, node, localQuickFix, true); } protected void registerForAllMatchingVersions(@NotNull Predicate levelPredicate, - @NotNull String suffix, + @NotNull @Nls String suffix, @NotNull PsiElement node) { registerForAllMatchingVersions(levelPredicate, suffix, node, null, true); } @@ -595,7 +599,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { @Override public void visitPyNonlocalStatement(final PyNonlocalStatement node) { registerForAllMatchingVersions(level -> level.isPython2() && registerForLanguageLevel(level), - " not have nonlocal keyword", + PyPsiBundle.message("INSP.compatibility.feature.have.nonlocal.keyword"), node); } @@ -611,11 +615,11 @@ public abstract class CompatibilityVisitor extends PyAnnotator { final String keyword = ((PyKeywordArgument)argument).getKeyword(); if (keywordArgumentNames.contains(keyword)) { - registerProblem(argument, "Keyword argument repeated", new PyRemoveArgumentQuickFix()); + registerProblem(argument, PyPsiBundle.message("INSP.compatibility.keyword.argument.repeated"), new PyRemoveArgumentQuickFix()); } else if (seenKeywordContainer) { registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON35) && registerForLanguageLevel(level), - " not allow keyword arguments after **expression", + PyPsiBundle.message("INSP.compatibility.feature.allow.keyword.arguments.after.kwargs"), argument, new PyRemoveArgumentQuickFix()); } @@ -628,7 +632,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { if (starArgument.isKeyword()) { if (seenKeywordContainer) { registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON35) && registerForLanguageLevel(level), - " not allow duplicate **expressions", + PyPsiBundle.message("INSP.compatibility.feature.allow.duplicate.kwargs"), argument, new PyRemoveArgumentQuickFix()); } @@ -637,7 +641,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { else { if (seenPositionalContainer) { registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON35) && registerForLanguageLevel(level), - " not allow duplicate *expressions", + PyPsiBundle.message("INSP.compatibility.feature.allow.duplicate.positional.varargs"), argument, new PyRemoveArgumentQuickFix()); } @@ -646,16 +650,16 @@ public abstract class CompatibilityVisitor extends PyAnnotator { } else { if (seenKeywordArgument) { - registerProblem(argument, "Positional argument after keyword argument", new PyRemoveArgumentQuickFix()); + registerProblem(argument, PyPsiBundle.message("INSP.compatibility.positional.argument.after.keyword.argument"), new PyRemoveArgumentQuickFix()); } else if (seenPositionalContainer) { registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON35) && registerForLanguageLevel(level), - " not allow positional arguments after *expression", + PyPsiBundle.message("INSP.compatibility.feature.allow.positional.arguments.after.expression"), argument, new PyRemoveArgumentQuickFix()); } else if (seenKeywordContainer) { - registerProblem(argument, "Positional argument after **expression", new PyRemoveArgumentQuickFix()); + registerProblem(argument, PyPsiBundle.message("INSP.compatibility.positional.argument.after.kwargs"), new PyRemoveArgumentQuickFix()); } } } @@ -666,9 +670,15 @@ public abstract class CompatibilityVisitor extends PyAnnotator { PsiElement sibling = PyPsiUtils.getNextNonWhitespaceSibling(lastArg); if (sibling != null && sibling.getNode().getElementType() == PyTokenTypes.COMMA) { boolean isKeyword = ((PyStarArgument)lastArg).isKeyword(); + String message; + if (isKeyword) { + message = PyPsiBundle.message("INSP.compatibility.feature.allow.trailing.comma.after.kwargs"); + } + else { + message = PyPsiBundle.message("INSP.compatibility.feature.allow.trailing.comma.after.positional.vararg"); + } registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON35) && registerForLanguageLevel(level), - " not allow a trailing comma after " - + (isKeyword ? "**" : "*") + "expression", + message, sibling); } } @@ -684,7 +694,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { .filter(Objects::nonNull) .map(ASTNode::getPsi) .forEach(element -> registerProblem(element, - "Python version 3.5 does not support 'async' inside comprehensions and generator expressions")); + PyPsiBundle.message("INSP.compatibility.py35.does.not.support.async.inside.comprehensions.and.generator.expressions"))); final Stream resultPrefixExpressions = PsiTreeUtil .collectElementsOfType(node.getResultExpression(), PyPrefixExpression.class) @@ -700,7 +710,8 @@ public abstract class CompatibilityVisitor extends PyAnnotator { .map(expression -> expression.getNode().findChildByType(PyTokenTypes.AWAIT_KEYWORD)) .filter(Objects::nonNull) .map(ASTNode::getPsi) - .forEach(element -> registerProblem(element, "Python version 3.5 does not support 'await' inside comprehensions")); + .forEach(element -> registerProblem(element, + PyPsiBundle.message("INSP.compatibility.py35.does.not.support.await.inside.comprehensions"))); } } @@ -709,7 +720,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { super.visitPySlashParameter(node); registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON38) && registerForLanguageLevel(level), - " not support positional-only parameters", + PyPsiBundle.message("INSP.compatibility.feature.support.positional.only.parameters"), node); } @@ -720,7 +731,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { final ASTNode equalitySignInFStringFragment = node.getNode().findChildByType(PyTokenTypes.EQ); if (equalitySignInFStringFragment != null) { registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON38) && registerForLanguageLevel(level), - " not support equality signs in f-strings", equalitySignInFStringFragment.getPsi()); + PyPsiBundle.message("INSP.compatibility.support.equality.signs.in.fstrings"), equalitySignInFStringFragment.getPsi()); } } @@ -728,7 +739,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { public void visitPyAssignmentExpression(PyAssignmentExpression node) { super.visitPyAssignmentExpression(node); registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON38) && registerForLanguageLevel(level), - " not support assignment expressions", node); + PyPsiBundle.message("INSP.compatibility.feature.support.assignment.expressions"), node); } @Override @@ -737,7 +748,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { if (PsiTreeUtil.getParentOfType(node, PyFinallyPart.class, false, PyLoopStatement.class) != null) { registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON38) && registerForLanguageLevel(level), - " not support 'continue' inside 'finally' clause", + PyPsiBundle.message("INSP.compatibility.feature.support.continue.inside.finally.clause"), node); } } @@ -747,7 +758,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { super.visitPyDecorator(decorator); if (PsiTreeUtil.getChildOfType(decorator, PsiErrorElement.class) == null && decorator.getQualifiedName() == null) { registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON39) && registerForLanguageLevel(level), - " not support arbitrary expressions as a decorator", decorator); + PyPsiBundle.message("INSP.compatibility.feature.support.arbitrary.expressions.as.decorator"), decorator); } } } diff --git a/python/testData/highlighting/implicitOctLongInteger.py b/python/testData/highlighting/implicitOctLongInteger.py index 5466dfd85add..d6377f9589f4 100644 --- a/python/testData/highlighting/implicitOctLongInteger.py +++ b/python/testData/highlighting/implicitOctLongInteger.py @@ -1 +1 @@ -01234L \ No newline at end of file +01234L \ No newline at end of file diff --git a/python/testData/highlighting/unsupportedFeaturesInPython3.py b/python/testData/highlighting/unsupportedFeaturesInPython3.py index b04973039ef7..05cb6f5e5951 100644 --- a/python/testData/highlighting/unsupportedFeaturesInPython3.py +++ b/python/testData/highlighting/unsupportedFeaturesInPython3.py @@ -1,6 +1,6 @@ -print(a <> 3) +print(a <> 3) `foo()` -a = 123l +a = 123l a = 043 a = 0X43 a = 0X43 @@ -11,15 +11,15 @@ a = 0B1 a = 0b1 a = 0.0 s = u"text" -raise a, b, c -raise a, b +raise a, b, c +raise a, b try: pass -except a, name: +except a, name: pass -[x * 2 for x in vec1, vec2] +[x * 2 for x in vec1, vec2] import __builtin__ diff --git a/python/testData/inspections/BatchReplacePrintInsertsFutureImportOnlyOnce.py b/python/testData/inspections/BatchReplacePrintInsertsFutureImportOnlyOnce.py index ad746b0c98e8..2da1fec6882c 100644 --- a/python/testData/inspections/BatchReplacePrintInsertsFutureImportOnlyOnce.py +++ b/python/testData/inspections/BatchReplacePrintInsertsFutureImportOnlyOnce.py @@ -1,2 +1,2 @@ -print 'foo' -print 'bar' \ No newline at end of file +print 'foo' +print 'bar' \ No newline at end of file diff --git a/python/testData/inspections/PyCompatibilityInspection/argumentsUnpackingGeneralizations.py b/python/testData/inspections/PyCompatibilityInspection/argumentsUnpackingGeneralizations.py index 3558259797e7..b81b02bc7154 100644 --- a/python/testData/inspections/PyCompatibilityInspection/argumentsUnpackingGeneralizations.py +++ b/python/testData/inspections/PyCompatibilityInspection/argumentsUnpackingGeneralizations.py @@ -4,14 +4,14 @@ def foo(*args, **kwargs): foo(0, *[1], - 2, - *[3], - 4, + 2, + *[3], + 4, a='a', - *[6], + *[6], b='b', - *[7], + *[7], c='c', **{'d': 'd'}, - e='e', - **{'f': 'f'}) + e='e', + **{'f': 'f'}) diff --git a/python/testData/inspections/PyCompatibilityInspection/assignmentExpressions.py b/python/testData/inspections/PyCompatibilityInspection/assignmentExpressions.py index a81156554f14..f8fe9a0831df 100644 --- a/python/testData/inspections/PyCompatibilityInspection/assignmentExpressions.py +++ b/python/testData/inspections/PyCompatibilityInspection/assignmentExpressions.py @@ -1,13 +1,13 @@ # Handle a matched regex -if (match := pattern.search(data)) is not None: +if (match := pattern.search(data)) is not None: pass # A loop that can't be trivially rewritten using 2-arg iter() -while chunk := file.read(8192): +while chunk := file.read(8192): pass # Reuse a value that's expensive to compute -[y := f(x), y**2, y**3] +[y := f(x), y**2, y**3] # Share a subexpression between a comprehension filter clause and its output -filtered_data = [y for x in data if (y := f(x)) is not None] \ No newline at end of file +filtered_data = [y for x in data if (y := f(x)) is not None] \ No newline at end of file diff --git a/python/testData/inspections/PyCompatibilityInspection/asyncAwait.py b/python/testData/inspections/PyCompatibilityInspection/asyncAwait.py index eada4910789f..d1cf6e7cd100 100644 --- a/python/testData/inspections/PyCompatibilityInspection/asyncAwait.py +++ b/python/testData/inspections/PyCompatibilityInspection/asyncAwait.py @@ -1,7 +1,7 @@ -async def foo(x): - async with x: - y = await x - if await y: - return await z - async for y in x: +async def foo(x): + async with x: + y = await x + if await y: + return await z + async for y in x: pass diff --git a/python/testData/inspections/PyCompatibilityInspection/asyncComprehensions.py b/python/testData/inspections/PyCompatibilityInspection/asyncComprehensions.py index bd2da0d56019..b543e029ec9a 100644 --- a/python/testData/inspections/PyCompatibilityInspection/asyncComprehensions.py +++ b/python/testData/inspections/PyCompatibilityInspection/asyncComprehensions.py @@ -1,6 +1,6 @@ -async def asyncgen(): +async def asyncgen(): yield 10 -async def run(): +async def run(): {i async for i in asyncgen()} [i async for i in asyncgen()] {i: i ** 2 async for i in asyncgen()} diff --git a/python/testData/inspections/PyCompatibilityInspection/awaitInComprehensions.py b/python/testData/inspections/PyCompatibilityInspection/awaitInComprehensions.py index 3c22098d1981..c7d9762a9047 100644 --- a/python/testData/inspections/PyCompatibilityInspection/awaitInComprehensions.py +++ b/python/testData/inspections/PyCompatibilityInspection/awaitInComprehensions.py @@ -1,16 +1,16 @@ -async def async2(): - [await fun() for fun in funcs] - {await fun() for fun in funcs} - {fun: await fun() for fun in funcs} +async def async2(): + [await fun() for fun in funcs] + {await fun() for fun in funcs} + {fun: await fun() for fun in funcs} - [await fun() for fun in funcs if await smth] - {await fun() for fun in funcs if await smth} - {fun: await fun() for fun in funcs if await smth} + [await fun() for fun in funcs if await smth] + {await fun() for fun in funcs if await smth} + {fun: await fun() for fun in funcs if await smth} - [await fun() async for fun in funcs] - {await fun() async for fun in funcs} - {fun: await fun() async for fun in funcs} + [await fun() async for fun in funcs] + {await fun() async for fun in funcs} + {fun: await fun() async for fun in funcs} - [await fun() async for fun in funcs if await smth] - {await fun() async for fun in funcs if await smth} - {fun: await fun() async for fun in funcs if await smth} \ No newline at end of file + [await fun() async for fun in funcs if await smth] + {await fun() async for fun in funcs if await smth} + {fun: await fun() async for fun in funcs if await smth} \ No newline at end of file diff --git a/python/testData/inspections/PyCompatibilityInspection/binaryExpression.py b/python/testData/inspections/PyCompatibilityInspection/binaryExpression.py index 18a27e89010c..6aa8b77ec220 100644 --- a/python/testData/inspections/PyCompatibilityInspection/binaryExpression.py +++ b/python/testData/inspections/PyCompatibilityInspection/binaryExpression.py @@ -1,4 +1,4 @@ -print(a <> b) +print(a <> b) -if a <> 2: +if a <> 2: var = a \ No newline at end of file diff --git a/python/testData/inspections/PyCompatibilityInspection/builtinLong.py b/python/testData/inspections/PyCompatibilityInspection/builtinLong.py index a31692081e9e..9980b3c97561 100644 --- a/python/testData/inspections/PyCompatibilityInspection/builtinLong.py +++ b/python/testData/inspections/PyCompatibilityInspection/builtinLong.py @@ -1 +1 @@ -long("abc") \ No newline at end of file +long("abc") \ No newline at end of file diff --git a/python/testData/inspections/PyCompatibilityInspection/callExpression.py b/python/testData/inspections/PyCompatibilityInspection/callExpression.py index 3c98ce3091e3..395dbdce8b7d 100644 --- a/python/testData/inspections/PyCompatibilityInspection/callExpression.py +++ b/python/testData/inspections/PyCompatibilityInspection/callExpression.py @@ -1,8 +1,8 @@ class A(B): def __init__(self): - super() + super() -cmp() -reduce() +cmp() +reduce() -buffer() \ No newline at end of file +buffer() \ No newline at end of file diff --git a/python/testData/inspections/PyCompatibilityInspection/doubleStarUnpacking.py b/python/testData/inspections/PyCompatibilityInspection/doubleStarUnpacking.py index 0ee45319ece6..31f817553fb2 100644 --- a/python/testData/inspections/PyCompatibilityInspection/doubleStarUnpacking.py +++ b/python/testData/inspections/PyCompatibilityInspection/doubleStarUnpacking.py @@ -1,2 +1,2 @@ xs = {1: 2} -ys = {**xs, 3: 4} +ys = {**xs, 3: 4} diff --git a/python/testData/inspections/PyCompatibilityInspection/ellipsisAsStatementPy2.py b/python/testData/inspections/PyCompatibilityInspection/ellipsisAsStatementPy2.py index b996e0088cab..df4ebc0fe8d0 100644 --- a/python/testData/inspections/PyCompatibilityInspection/ellipsisAsStatementPy2.py +++ b/python/testData/inspections/PyCompatibilityInspection/ellipsisAsStatementPy2.py @@ -1,2 +1,2 @@ def foo(): - ... + ... diff --git a/python/testData/inspections/PyCompatibilityInspection/equalitySignInFStrings.py b/python/testData/inspections/PyCompatibilityInspection/equalitySignInFStrings.py index d5212da63f0a..c8a74eb77eb7 100644 --- a/python/testData/inspections/PyCompatibilityInspection/equalitySignInFStrings.py +++ b/python/testData/inspections/PyCompatibilityInspection/equalitySignInFStrings.py @@ -1,3 +1,3 @@ import math -print(f'{math.pi =:.2f}') -print(f'{f"{3.1415=:.1f}":*^20}') \ No newline at end of file +print(f'{math.pi =:.2f}') +print(f'{f"{3.1415=:.1f}":*^20}') \ No newline at end of file diff --git a/python/testData/inspections/PyCompatibilityInspection/exceptBlock.py b/python/testData/inspections/PyCompatibilityInspection/exceptBlock.py index b206d5774887..4396d55f103b 100644 --- a/python/testData/inspections/PyCompatibilityInspection/exceptBlock.py +++ b/python/testData/inspections/PyCompatibilityInspection/exceptBlock.py @@ -1,4 +1,4 @@ try: do_smth() -except ImportError, ImportWarning: +except ImportError, ImportWarning: do() \ No newline at end of file diff --git a/python/testData/inspections/PyCompatibilityInspection/expressionInDecorators.py b/python/testData/inspections/PyCompatibilityInspection/expressionInDecorators.py index f4622082a300..9f289c90407f 100644 --- a/python/testData/inspections/PyCompatibilityInspection/expressionInDecorators.py +++ b/python/testData/inspections/PyCompatibilityInspection/expressionInDecorators.py @@ -1,9 +1,9 @@ -@x[0][1] +@x[0][1] @my_decorator def say_whee(): print("Whee!") -@foo[0].wrapper +@foo[0].wrapper @foo.bar() def say_whee(): print("Whee!") \ No newline at end of file diff --git a/python/testData/inspections/PyCompatibilityInspection/fromImportStatement.py b/python/testData/inspections/PyCompatibilityInspection/fromImportStatement.py index 45768163cdce..464316ca18c3 100644 --- a/python/testData/inspections/PyCompatibilityInspection/fromImportStatement.py +++ b/python/testData/inspections/PyCompatibilityInspection/fromImportStatement.py @@ -1 +1 @@ -from Bastion import BastionClass \ No newline at end of file +from Bastion import BastionClass \ No newline at end of file diff --git a/python/testData/inspections/PyCompatibilityInspection/importElement.py b/python/testData/inspections/PyCompatibilityInspection/importElement.py index 083e7f36828b..6b9a0db4de1e 100644 --- a/python/testData/inspections/PyCompatibilityInspection/importElement.py +++ b/python/testData/inspections/PyCompatibilityInspection/importElement.py @@ -1,4 +1,4 @@ -import Bastion +import Bastion -from asyncio import Queue +from asyncio import Queue from io import StringIO \ No newline at end of file diff --git a/python/testData/inspections/PyCompatibilityInspection/importStatement.py b/python/testData/inspections/PyCompatibilityInspection/importStatement.py index c3c3fce97cb3..f26b880a1ff6 100644 --- a/python/testData/inspections/PyCompatibilityInspection/importStatement.py +++ b/python/testData/inspections/PyCompatibilityInspection/importStatement.py @@ -1,3 +1,3 @@ import builtins -import __builtin__ \ No newline at end of file +import __builtin__ \ No newline at end of file diff --git a/python/testData/inspections/PyCompatibilityInspection/listCompExpression.py b/python/testData/inspections/PyCompatibilityInspection/listCompExpression.py index e231912e5e1d..1b88b0ab9fce 100644 --- a/python/testData/inspections/PyCompatibilityInspection/listCompExpression.py +++ b/python/testData/inspections/PyCompatibilityInspection/listCompExpression.py @@ -1 +1 @@ -var = [x for x in 1, 2, 3] \ No newline at end of file +var = [x for x in 1, 2, 3] \ No newline at end of file diff --git a/python/testData/inspections/PyCompatibilityInspection/matMul.py b/python/testData/inspections/PyCompatibilityInspection/matMul.py index a6c05ef126a6..e4749ef8975e 100644 --- a/python/testData/inspections/PyCompatibilityInspection/matMul.py +++ b/python/testData/inspections/PyCompatibilityInspection/matMul.py @@ -1,2 +1,2 @@ -x @ y -x @= y +x @ y +x @= y diff --git a/python/testData/inspections/PyCompatibilityInspection/numericLiteralExpression.py b/python/testData/inspections/PyCompatibilityInspection/numericLiteralExpression.py index 042efc14cd63..26900b07a824 100644 --- a/python/testData/inspections/PyCompatibilityInspection/numericLiteralExpression.py +++ b/python/testData/inspections/PyCompatibilityInspection/numericLiteralExpression.py @@ -1,8 +1,8 @@ a = 12u -b = 12l +b = 12l c = 12ll d = 12U -e = 12L +e = 12L f = 12LL g = 0x12ful h = 0X12fuL @@ -20,4 +20,4 @@ s = 12llu t = 12llU u = 12LLu v = 12LLU -w = 048 \ No newline at end of file +w = 048 \ No newline at end of file diff --git a/python/testData/inspections/PyCompatibilityInspection/printStatement.py b/python/testData/inspections/PyCompatibilityInspection/printStatement.py index 2e1aebee1924..816a3ac1286b 100644 --- a/python/testData/inspections/PyCompatibilityInspection/printStatement.py +++ b/python/testData/inspections/PyCompatibilityInspection/printStatement.py @@ -1 +1 @@ -print "One value" \ No newline at end of file +print "One value" \ No newline at end of file diff --git a/python/testData/inspections/PyCompatibilityInspection/raiseFrom.py b/python/testData/inspections/PyCompatibilityInspection/raiseFrom.py index f7033897e3d2..d09bdf87c7fb 100644 --- a/python/testData/inspections/PyCompatibilityInspection/raiseFrom.py +++ b/python/testData/inspections/PyCompatibilityInspection/raiseFrom.py @@ -1,2 +1,2 @@ -raise exception from cause +raise exception from cause a = 1 \ No newline at end of file diff --git a/python/testData/inspections/PyCompatibilityInspection/raiseMultipleArgs.py b/python/testData/inspections/PyCompatibilityInspection/raiseMultipleArgs.py index 062066bd2164..4489cb6f9978 100644 --- a/python/testData/inspections/PyCompatibilityInspection/raiseMultipleArgs.py +++ b/python/testData/inspections/PyCompatibilityInspection/raiseMultipleArgs.py @@ -1,4 +1,4 @@ try: a except : - raise ImportError, ImportWarning + raise ImportError, ImportWarning diff --git a/python/testData/inspections/PyCompatibilityInspection/reprExpression.py b/python/testData/inspections/PyCompatibilityInspection/reprExpression.py index cf4eab4c1fc1..5385cbe725b8 100644 --- a/python/testData/inspections/PyCompatibilityInspection/reprExpression.py +++ b/python/testData/inspections/PyCompatibilityInspection/reprExpression.py @@ -1 +1 @@ -a = `imp.acquire_lock()` +a = `imp.acquire_lock()` diff --git a/python/testData/inspections/PyCompatibilityInspection/starExpression.py b/python/testData/inspections/PyCompatibilityInspection/starExpression.py index a42ade5e4ee5..211af8dfa54c 100644 --- a/python/testData/inspections/PyCompatibilityInspection/starExpression.py +++ b/python/testData/inspections/PyCompatibilityInspection/starExpression.py @@ -1,2 +1,2 @@ -t = (1, *(2, 3)) -a, *b, c = t +t = (1, *(2, 3)) +a, *b, c = t diff --git a/python/testData/inspections/PyCompatibilityInspection/stringLiteralExpression.py b/python/testData/inspections/PyCompatibilityInspection/stringLiteralExpression.py index 32827aee12b8..a7e1f3ee5b88 100644 --- a/python/testData/inspections/PyCompatibilityInspection/stringLiteralExpression.py +++ b/python/testData/inspections/PyCompatibilityInspection/stringLiteralExpression.py @@ -2,15 +2,15 @@ a = u"String" # Python 3.6 -a = f"" -a = F"" -a = rf"" -a = fr"" -a = fu"" -a = uf"" -a = bf"" -a = fb"" -a = ufr"" +a = f"" +a = F"" +a = rf"" +a = fr"" +a = fu"" +a = uf"" +a = bf"" +a = fb"" +a = ufr"" # python 3.3 @@ -35,7 +35,7 @@ a = b"" a = u"" a = r"" -a = ur"" +a = ur"" a = b"" a = br"" @@ -43,14 +43,14 @@ a = br"" a = u"" a = r"" -a = ur"" +a = ur"" # combined, PY-32321 -b = u"" b"" -b = r"" b"" -b = f"" b"" +b = u"" b"" +b = r"" b"" +b = f"" b"" # never was available -a = rr"" -a = bb"" -a = uu"" \ No newline at end of file +a = rr"" +a = bb"" +a = uu"" \ No newline at end of file diff --git a/python/testData/inspections/PyCompatibilityInspection/trailingCommaAfterStarArgs.py b/python/testData/inspections/PyCompatibilityInspection/trailingCommaAfterStarArgs.py index 3c225470b709..0dfe512412f0 100644 --- a/python/testData/inspections/PyCompatibilityInspection/trailingCommaAfterStarArgs.py +++ b/python/testData/inspections/PyCompatibilityInspection/trailingCommaAfterStarArgs.py @@ -2,5 +2,5 @@ def foo(*args, **kwargs): print(args, kwargs) -foo(1, 2, 3, *[3],) -foo(1, 2, 3, *[3], **{'d': 'd'},) +foo(1, 2, 3, *[3],) +foo(1, 2, 3, *[3], **{'d': 'd'},) diff --git a/python/testData/inspections/PyCompatibilityInspection/tryFinallyEmptyRaisePy3.py b/python/testData/inspections/PyCompatibilityInspection/tryFinallyEmptyRaisePy3.py index f2bf13030630..e68eccf7d1f3 100644 --- a/python/testData/inspections/PyCompatibilityInspection/tryFinallyEmptyRaisePy3.py +++ b/python/testData/inspections/PyCompatibilityInspection/tryFinallyEmptyRaisePy3.py @@ -1,4 +1,4 @@ try: raise ValueError finally: - raise \ No newline at end of file + raise \ No newline at end of file diff --git a/python/testData/inspections/PyCompatibilityInspection/underscoreBz2Module.py b/python/testData/inspections/PyCompatibilityInspection/underscoreBz2Module.py index 870868fb0053..3514027b3be8 100644 --- a/python/testData/inspections/PyCompatibilityInspection/underscoreBz2Module.py +++ b/python/testData/inspections/PyCompatibilityInspection/underscoreBz2Module.py @@ -1 +1 @@ -import _bz2 \ No newline at end of file +import _bz2 \ No newline at end of file diff --git a/python/testData/inspections/PyCompatibilityInspection/underscoresInNumericLiterals.py b/python/testData/inspections/PyCompatibilityInspection/underscoresInNumericLiterals.py index e5d364dcba8e..1729ddc90f54 100644 --- a/python/testData/inspections/PyCompatibilityInspection/underscoresInNumericLiterals.py +++ b/python/testData/inspections/PyCompatibilityInspection/underscoresInNumericLiterals.py @@ -1,58 +1,58 @@ # hex -0xCAFE_F00D +0xCAFE_F00D # oct -0o1_23 -01_23 +0o1_23 +01_23 # bin -0b_0011_1111_0100_1110 +0b_0011_1111_0100_1110 # dec -10_000_000 +10_000_000 # pointfloat -10_00.00_23 -10_00. +10_00.00_23 +10_00. # exponentfloat -10_00.00_23e1_2 -10_00.00_23E1_2 -10_00.e1_2 -10_00.E1_2 +10_00.00_23e1_2 +10_00.00_23E1_2 +10_00.e1_2 +10_00.E1_2 -10_00.00_23e+1_2 -10_00.00_23E+1_2 -10_00.e+1_2 -10_00.E+1_2 +10_00.00_23e+1_2 +10_00.00_23E+1_2 +10_00.e+1_2 +10_00.E+1_2 -10_00.00_23e-1_2 -10_00.00_23E-1_2 -10_00.e-1_2 -10_00.E-1_2 +10_00.00_23e-1_2 +10_00.00_23E-1_2 +10_00.e-1_2 +10_00.E-1_2 -10_0000_23e1_2 -10_0000_23E1_2 -10_00e1_2 -10_00E1_2 +10_0000_23e1_2 +10_0000_23E1_2 +10_00e1_2 +10_00E1_2 -10_0000_23e+1_2 -10_0000_23E+1_2 -10_00e+1_2 -10_00E+1_2 +10_0000_23e+1_2 +10_0000_23E+1_2 +10_00e+1_2 +10_00E+1_2 -10_0000_23e-1_2 -10_0000_23E-1_2 -10_00e-1_2 -10_00E-1_2 +10_0000_23e-1_2 +10_0000_23E-1_2 +10_00e-1_2 +10_00E-1_2 # imag -10_00.00_23j -10_00.00_23J +10_00.00_23j +10_00.00_23J -10_00.00_23e1_2j -10_00.00_23e1_2J +10_00.00_23e1_2j +10_00.00_23e1_2J -10_000_000j -10_000_000J \ No newline at end of file +10_000_000j +10_000_000J \ No newline at end of file diff --git a/python/testData/inspections/PyCompatibilityInspection/unpackingInNonParenthesizedTuplesInReturnAndYield.py b/python/testData/inspections/PyCompatibilityInspection/unpackingInNonParenthesizedTuplesInReturnAndYield.py index e41b329752da..82d3d8cafcb4 100644 --- a/python/testData/inspections/PyCompatibilityInspection/unpackingInNonParenthesizedTuplesInReturnAndYield.py +++ b/python/testData/inspections/PyCompatibilityInspection/unpackingInNonParenthesizedTuplesInReturnAndYield.py @@ -1,7 +1,7 @@ def gen(xs): - yield 42, *xs - yield from 42, *xs + yield 42, *xs + yield from 42, *xs def func(xs): - return 42, *xs + return 42, *xs diff --git a/python/testData/inspections/PyCompatibilityInspection/variableAnnotations.py b/python/testData/inspections/PyCompatibilityInspection/variableAnnotations.py index f5cbb701ec6c..0876a4555bc8 100644 --- a/python/testData/inspections/PyCompatibilityInspection/variableAnnotations.py +++ b/python/testData/inspections/PyCompatibilityInspection/variableAnnotations.py @@ -1,8 +1,8 @@ class C: - x: int - y: None = 42 + x: int + y: None = 42 def m(self, d): - x: List[bool] - d['foo']: str - (d['bar']): float + x: List[bool] + d['foo']: str + (d['bar']): float diff --git a/python/testData/inspections/PyCompatibilityInspection/warningAboutAsyncAndAwaitInPy36.py b/python/testData/inspections/PyCompatibilityInspection/warningAboutAsyncAndAwaitInPy36.py index ab26323feacb..cd8c0e615196 100644 --- a/python/testData/inspections/PyCompatibilityInspection/warningAboutAsyncAndAwaitInPy36.py +++ b/python/testData/inspections/PyCompatibilityInspection/warningAboutAsyncAndAwaitInPy36.py @@ -1,14 +1,14 @@ -class async(object): +class async(object): pass -class await(object): +class await(object): pass -def async(): +def async(): pass -def await(): +def await(): pass -async = 1 -await = 2 \ No newline at end of file +async = 1 +await = 2 \ No newline at end of file diff --git a/python/testData/inspections/PyCompatibilityInspection/yieldInsideAsyncDef.py b/python/testData/inspections/PyCompatibilityInspection/yieldInsideAsyncDef.py index 3573a332b110..91a730eca616 100644 --- a/python/testData/inspections/PyCompatibilityInspection/yieldInsideAsyncDef.py +++ b/python/testData/inspections/PyCompatibilityInspection/yieldInsideAsyncDef.py @@ -1,5 +1,5 @@ -async def foo(x): - await x +async def foo(x): + await x yield x - yield from x + yield from x return x diff --git a/python/testData/inspections/ReplaceNotEqOperator.py b/python/testData/inspections/ReplaceNotEqOperator.py index 31af3639a987..ebf152813f46 100644 --- a/python/testData/inspections/ReplaceNotEqOperator.py +++ b/python/testData/inspections/ReplaceNotEqOperator.py @@ -1 +1 @@ -print(a <> b) \ No newline at end of file +print(a <> b) \ No newline at end of file diff --git a/python/testData/inspections/ReplacePrint.py b/python/testData/inspections/ReplacePrint.py index 66d520df4eeb..4aab7a5a8191 100644 --- a/python/testData/inspections/ReplacePrint.py +++ b/python/testData/inspections/ReplacePrint.py @@ -1 +1 @@ -print "foo" \ No newline at end of file +print "foo" \ No newline at end of file diff --git a/python/testData/quickFixes/PyRemoveTrailingSuffixQuickFixTest/fixl.py b/python/testData/quickFixes/PyRemoveTrailingSuffixQuickFixTest/fixl.py index f61ec245ccb7..13ac094a923d 100644 --- a/python/testData/quickFixes/PyRemoveTrailingSuffixQuickFixTest/fixl.py +++ b/python/testData/quickFixes/PyRemoveTrailingSuffixQuickFixTest/fixl.py @@ -1 +1 @@ -1000l \ No newline at end of file +1000l \ No newline at end of file diff --git a/python/testData/quickFixes/PyRenameElementQuickFixTest/renameAsyncClassInPy36.py b/python/testData/quickFixes/PyRenameElementQuickFixTest/renameAsyncClassInPy36.py index 8281f1dba11f..8b6cadcddea8 100644 --- a/python/testData/quickFixes/PyRenameElementQuickFixTest/renameAsyncClassInPy36.py +++ b/python/testData/quickFixes/PyRenameElementQuickFixTest/renameAsyncClassInPy36.py @@ -1,2 +1,2 @@ -class async(object): +class async(object): pass \ No newline at end of file diff --git a/python/testData/quickFixes/PyRenameElementQuickFixTest/renameAsyncFunctionInPy36.py b/python/testData/quickFixes/PyRenameElementQuickFixTest/renameAsyncFunctionInPy36.py index e1ca9c6a2993..add7f982609e 100644 --- a/python/testData/quickFixes/PyRenameElementQuickFixTest/renameAsyncFunctionInPy36.py +++ b/python/testData/quickFixes/PyRenameElementQuickFixTest/renameAsyncFunctionInPy36.py @@ -1,2 +1,2 @@ -def async(): +def async(): pass \ No newline at end of file diff --git a/python/testData/quickFixes/PyRenameElementQuickFixTest/renameAsyncVariableInPy36.py b/python/testData/quickFixes/PyRenameElementQuickFixTest/renameAsyncVariableInPy36.py index 0b02b513a89b..4a7efc4225f8 100644 --- a/python/testData/quickFixes/PyRenameElementQuickFixTest/renameAsyncVariableInPy36.py +++ b/python/testData/quickFixes/PyRenameElementQuickFixTest/renameAsyncVariableInPy36.py @@ -1 +1 @@ -async = 1 \ No newline at end of file +async = 1 \ No newline at end of file diff --git a/python/testData/quickFixes/PyRenameElementQuickFixTest/renameAwaitClassInPy36.py b/python/testData/quickFixes/PyRenameElementQuickFixTest/renameAwaitClassInPy36.py index f398068f0efe..d1ef03bdc59d 100644 --- a/python/testData/quickFixes/PyRenameElementQuickFixTest/renameAwaitClassInPy36.py +++ b/python/testData/quickFixes/PyRenameElementQuickFixTest/renameAwaitClassInPy36.py @@ -1,2 +1,2 @@ -class await(object): +class await(object): pass \ No newline at end of file diff --git a/python/testData/quickFixes/PyRenameElementQuickFixTest/renameAwaitFunctionInPy36.py b/python/testData/quickFixes/PyRenameElementQuickFixTest/renameAwaitFunctionInPy36.py index 412641b13c24..fdcab4a11057 100644 --- a/python/testData/quickFixes/PyRenameElementQuickFixTest/renameAwaitFunctionInPy36.py +++ b/python/testData/quickFixes/PyRenameElementQuickFixTest/renameAwaitFunctionInPy36.py @@ -1,2 +1,2 @@ -def await(): +def await(): pass \ No newline at end of file diff --git a/python/testData/quickFixes/PyRenameElementQuickFixTest/renameAwaitVariableInPy36.py b/python/testData/quickFixes/PyRenameElementQuickFixTest/renameAwaitVariableInPy36.py index d62315e04309..ce8563c92eef 100644 --- a/python/testData/quickFixes/PyRenameElementQuickFixTest/renameAwaitVariableInPy36.py +++ b/python/testData/quickFixes/PyRenameElementQuickFixTest/renameAwaitVariableInPy36.py @@ -1 +1 @@ -await = 1 \ No newline at end of file +await = 1 \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/inspections/PyCompatibilityInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyCompatibilityInspectionTest.java index a93892b34a8e..7abe153c5b1f 100644 --- a/python/testSrc/com/jetbrains/python/inspections/PyCompatibilityInspectionTest.java +++ b/python/testSrc/com/jetbrains/python/inspections/PyCompatibilityInspectionTest.java @@ -229,7 +229,7 @@ public class PyCompatibilityInspectionTest extends PyInspectionTestCase { runWithLanguageLevel( LanguageLevel.PYTHON38, () -> doTestByText( - "def f(pos1, /, pos_or_kwd, *, kwd1):\n" + + "def f(pos1, /, pos_or_kwd, *, kwd1):\n" + " pass" ) ); @@ -248,7 +248,7 @@ public class PyCompatibilityInspectionTest extends PyInspectionTestCase { " try:\n" + " print(\"a\")\n" + " finally:\n" + - " continue") + " continue") ); }