diff --git a/python/python-psi-impl/resources/META-INF/PythonPsiImpl.xml b/python/python-psi-impl/resources/META-INF/PythonPsiImpl.xml
index 8bb1c12111b7..0393b6068c8a 100644
--- a/python/python-psi-impl/resources/META-INF/PythonPsiImpl.xml
+++ b/python/python-psi-impl/resources/META-INF/PythonPsiImpl.xml
@@ -131,7 +131,7 @@
-
+
@@ -171,7 +171,7 @@
-
+
diff --git a/python/python-psi-impl/resources/messages/PyPsiBundle.properties b/python/python-psi-impl/resources/messages/PyPsiBundle.properties
index fa4f31eb719a..5339603bf24c 100644
--- a/python/python-psi-impl/resources/messages/PyPsiBundle.properties
+++ b/python/python-psi-impl/resources/messages/PyPsiBundle.properties
@@ -442,7 +442,6 @@ INSP.pep8.naming=PEP 8 naming convention violation
INSP.pep8.naming.excluded.base.classes=Excluded base classes
INSP.pep8.naming.ignored.errors=Ignored errors
INSP.shadowing.builtins=Shadowing built-ins
-INSP.dunder.slots=Definition of __slots__ in a class
INSP.final.classes.methods.and.variables=Final classes, methods and variables
INSP.global.undefined=Global variable is undefined at the module level
INSP.inconsistent.indentation=Inconsistent indentation
@@ -487,7 +486,6 @@ INSP.stub.packages.compatibility.incompatible.packages.message=''{0}{1}{2}'' is
INSP.arguments.not.declared.but.provided.by.decorator=Following arguments are not declared but provided by decorator: {0}
INSP.abstract.class=Class must implement all abstract methods
INSP.assigning.function.call.that.doesnt.return.anything=Assigning function call that doesn't return anything
-INSP.deprecated.function.class.or.module=Deprecated function, class or module
INSP.mandatory.encoding=No encoding specified for file
INSP.missing.type.hints=Missing type hinting for function definition
INSP.overloads.in.regular.python.files=Overloads in regular Python files
@@ -603,12 +601,15 @@ INSP.classic.class.usage.old.style.class.ancestors=Old-style class, because all
# PyExceptionInheritance
INSP.NAME.exception.not.inherit=Exception doesn't inherit from standard ''Exception'' class
+INSP.exception.inheritance.exception.does.not.inherit.from.base.exception.class=Exception doesn't inherit from base 'Exception' class
# PyDefaultArgumentInspection
INSP.NAME.default.argument=Default argument is mutable
+INSP.default.arguments.default.argument.value.mutable=Default argument value is mutable
# PyDocstringTypesInspection
INSP.NAME.docstring.types=Type in docstring doesn't match inferred type
+INSP.docstring.types.dynamically.inferred.type.does.not.match.specified.type=Dynamically inferred type ''{0}'' doesn''t match specified type ''{1}''
# PyStatementEffectInspection
INSP.NAME.statement.effect=Statement has no effect
@@ -734,6 +735,7 @@ INSP.NAME.set.function.to.literal=Function call can be replaced with set literal
# PyDecoratorInspection
INSP.NAME.decorator.outside.class=Class specific decorator on method outside class
+INSP.decorators.method.only.decorator.on.method.outside.class=Decorator {0} on method outside class
# PyPackageRequirementsInspection
INSP.NAME.requirements=Package requirements
@@ -786,9 +788,11 @@ INSP.comparison.with.none.performed.with.equality.operators=Comparison with None
# PyDictCreationInspection
INSP.NAME.dict.creation=Dictionary creation could be rewritten by dictionary literal
+INSP.dict.creation.this.dictionary.creation.could.be.rewritten.as.dictionary.literal=This dictionary creation could be rewritten as a dictionary literal
# PyDictDuplicateKeysInspection
INSP.NAME.duplicate.keys=Dictionary contains duplicate keys
+INSP.duplicate.keys.dictionary.contains.duplicate.keys=Dictionary contains duplicate keys ''{0}''
# PyFromFutureImportInspection
INSP.NAME.from.future.import=from __future__ import must be the first executable statement
@@ -906,6 +910,14 @@ INSP.python.trailing.suffix.not.support=Python does not support a trailing ''{0}
# PyInterpreterInspection
python.sdk.no.interpreter.configured.owner=No Python interpreter configured for the {0}
+# PyDeprecationInspection
+INSP.NAME.deprecated.function.class.or.module=Deprecated function, class or module
+INSP.deprecation.abc.decorator.deprecated.use.alternative=''{0}'' is deprecated since Python 3.3. Use ''{1}'' with ''{2}'' instead
+
+INSP.NAME.dunder.slots=Definition of __slots__ in a class
+INSP.dunder.slots.name.in.slots.conflicts.with.class.variable=''{0}'' in __slots__ conflicts with class variable
+INSP.dunder.slots.class.object.attribute.read.only=''{0}'' object attribute ''{1}'' is read-only
+
# PyInspectionsSuppressor
INSP.python.suppressor.suppress.for.function=Suppress for function
INSP.python.suppressor.suppress.for.class=Suppress for class
diff --git a/python/python-psi-impl/src/com/jetbrains/python/inspections/PyDecoratorInspection.java b/python/python-psi-impl/src/com/jetbrains/python/inspections/PyDecoratorInspection.java
index 184970aaeb92..9eaa0b051f78 100644
--- a/python/python-psi-impl/src/com/jetbrains/python/inspections/PyDecoratorInspection.java
+++ b/python/python-psi-impl/src/com/jetbrains/python/inspections/PyDecoratorInspection.java
@@ -18,6 +18,7 @@ package com.jetbrains.python.inspections;
import com.intellij.codeInspection.LocalInspectionToolSession;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.psi.PsiElementVisitor;
+import com.jetbrains.python.PyPsiBundle;
import com.jetbrains.python.inspections.quickfix.RemoveDecoratorQuickFix;
import com.jetbrains.python.psi.PyClass;
import com.jetbrains.python.psi.PyDecorator;
@@ -59,7 +60,8 @@ public class PyDecoratorInspection extends PyInspection {
for (PyDecorator decorator : decorators.getDecorators()) {
String name = decorator.getText();
if (name.equals("@classmethod") || name.equals("@staticmethod"))
- registerProblem(decorator, "Decorator " + name + " on method outside class", new RemoveDecoratorQuickFix());
+ registerProblem(decorator, PyPsiBundle.message("INSP.decorators.method.only.decorator.on.method.outside.class", name),
+ new RemoveDecoratorQuickFix());
}
}
}
diff --git a/python/python-psi-impl/src/com/jetbrains/python/inspections/PyDefaultArgumentInspection.java b/python/python-psi-impl/src/com/jetbrains/python/inspections/PyDefaultArgumentInspection.java
index cca918bdb403..792432d8a6ab 100644
--- a/python/python-psi-impl/src/com/jetbrains/python/inspections/PyDefaultArgumentInspection.java
+++ b/python/python-psi-impl/src/com/jetbrains/python/inspections/PyDefaultArgumentInspection.java
@@ -18,6 +18,7 @@ package com.jetbrains.python.inspections;
import com.intellij.codeInspection.LocalInspectionToolSession;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.psi.PsiElementVisitor;
+import com.jetbrains.python.PyPsiBundle;
import com.jetbrains.python.inspections.quickfix.PyDefaultArgumentQuickFix;
import com.jetbrains.python.psi.PyExpression;
import com.jetbrains.python.psi.PyNamedParameter;
@@ -47,7 +48,8 @@ public class PyDefaultArgumentInspection extends PyInspection {
public void visitPyNamedParameter(PyNamedParameter node) {
final PyExpression defaultValue = node.getDefaultValue();
if (PyUtil.isForbiddenMutableDefault(defaultValue, myTypeEvalContext)) {
- registerProblem(defaultValue, "Default argument value is mutable", new PyDefaultArgumentQuickFix());
+ registerProblem(defaultValue, PyPsiBundle.message("INSP.default.arguments.default.argument.value.mutable"),
+ new PyDefaultArgumentQuickFix());
}
}
}
diff --git a/python/python-psi-impl/src/com/jetbrains/python/inspections/PyDeprecationInspection.java b/python/python-psi-impl/src/com/jetbrains/python/inspections/PyDeprecationInspection.java
index e0e58d05a66d..050f1339c313 100644
--- a/python/python-psi-impl/src/com/jetbrains/python/inspections/PyDeprecationInspection.java
+++ b/python/python-psi-impl/src/com/jetbrains/python/inspections/PyDeprecationInspection.java
@@ -19,9 +19,11 @@ import com.intellij.codeInspection.LocalInspectionToolSession;
import com.intellij.codeInspection.ProblemHighlightType;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.lang.ASTNode;
+import com.intellij.openapi.util.NlsSafe;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.util.PsiTreeUtil;
+import com.jetbrains.python.PyPsiBundle;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.PyKnownDecoratorUtil.KnownDecorator;
import com.jetbrains.python.pyi.PyiUtil;
@@ -59,7 +61,7 @@ public class PyDeprecationInspection extends PyInspection {
final PsiElement element = importStatement.resolveImportSource();
if (resolveResult != null && element != resolveResult.getContainingFile()) return;
}
- String deprecationMessage = null;
+ @NlsSafe String deprecationMessage = null;
if (resolveResult instanceof PyFunction) {
deprecationMessage = ((PyFunction)resolveResult).getDeprecationMessage();
}
@@ -100,8 +102,10 @@ public class PyDeprecationInspection extends PyInspection {
}
final KnownDecorator abcAbsMethod = KnownDecorator.ABC_ABSTRACTMETHOD;
- final String message = "'" + deprecated.getQualifiedName() + "' is deprecated since Python 3.3. " +
- "Use '" + builtin.getQualifiedName() + "' with '" + abcAbsMethod.getQualifiedName() + "' instead.";
+ final String message = PyPsiBundle.message("INSP.deprecation.abc.decorator.deprecated.use.alternative",
+ deprecated.getQualifiedName(),
+ builtin.getQualifiedName(),
+ abcAbsMethod.getQualifiedName());
registerProblem(decorator, message, ProblemHighlightType.LIKE_DEPRECATED);
}
diff --git a/python/python-psi-impl/src/com/jetbrains/python/inspections/PyDictCreationInspection.java b/python/python-psi-impl/src/com/jetbrains/python/inspections/PyDictCreationInspection.java
index 73492e2fe85c..ffd31972499c 100644
--- a/python/python-psi-impl/src/com/jetbrains/python/inspections/PyDictCreationInspection.java
+++ b/python/python-psi-impl/src/com/jetbrains/python/inspections/PyDictCreationInspection.java
@@ -22,6 +22,7 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiPolyVariantReference;
import com.intellij.psi.util.PsiTreeUtil;
+import com.jetbrains.python.PyPsiBundle;
import com.jetbrains.python.inspections.quickfix.DictCreationQuickFix;
import com.jetbrains.python.psi.*;
import org.jetbrains.annotations.NotNull;
@@ -68,7 +69,9 @@ public class PyDictCreationInspection extends PyInspection {
if (targets == null)
return;
if (!targets.isEmpty()) {
- registerProblem(node, "This dictionary creation could be rewritten as a dictionary literal", new DictCreationQuickFix(node));
+ registerProblem(node,
+ PyPsiBundle.message("INSP.dict.creation.this.dictionary.creation.could.be.rewritten.as.dictionary.literal"),
+ new DictCreationQuickFix(node));
break;
}
statement = PsiTreeUtil.getNextSiblingOfType(assignmentStatement, PyStatement.class);
diff --git a/python/python-psi-impl/src/com/jetbrains/python/inspections/PyDictDuplicateKeysInspection.java b/python/python-psi-impl/src/com/jetbrains/python/inspections/PyDictDuplicateKeysInspection.java
index 88bc48e9ec4b..8bf066fda82f 100644
--- a/python/python-psi-impl/src/com/jetbrains/python/inspections/PyDictDuplicateKeysInspection.java
+++ b/python/python-psi-impl/src/com/jetbrains/python/inspections/PyDictDuplicateKeysInspection.java
@@ -19,11 +19,13 @@ import com.intellij.codeInspection.LocalInspectionToolSession;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.lang.ASTNode;
+import com.intellij.openapi.util.NlsSafe;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.util.containers.MultiMap;
+import com.jetbrains.python.PyPsiBundle;
import com.jetbrains.python.inspections.quickfix.PyRemoveDictKeyQuickFix;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.PyBuiltinCache;
@@ -127,12 +129,13 @@ public class PyDictDuplicateKeysInspection extends PyInspection {
private void registerProblems(@NotNull MultiMap keyValueAndKeys, LocalQuickFix @NotNull ... quickFixes) {
for (Map.Entry> entry : keyValueAndKeys.entrySet()) {
- final String keyValue = entry.getKey();
+ final @NlsSafe String keyValue = entry.getKey();
final Collection keys = entry.getValue();
if (keys.size() > 1) {
for (PsiElement key : keys) {
- registerProblem(key, "Dictionary contains duplicate keys '" + unwrapStringKey(keyValue) + "'", quickFixes);
+ String unquotedKey = unwrapStringKey(keyValue);
+ registerProblem(key, PyPsiBundle.message("INSP.duplicate.keys.dictionary.contains.duplicate.keys", unquotedKey), quickFixes);
}
}
}
diff --git a/python/python-psi-impl/src/com/jetbrains/python/inspections/PyDocstringTypesInspection.java b/python/python-psi-impl/src/com/jetbrains/python/inspections/PyDocstringTypesInspection.java
index f392f57118d9..2866148642b9 100644
--- a/python/python-psi-impl/src/com/jetbrains/python/inspections/PyDocstringTypesInspection.java
+++ b/python/python-psi-impl/src/com/jetbrains/python/inspections/PyDocstringTypesInspection.java
@@ -3,6 +3,7 @@ package com.jetbrains.python.inspections;
import com.intellij.codeInspection.*;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.NlsSafe;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.SmartPointerManager;
@@ -69,16 +70,14 @@ public class PyDocstringTypesInspection extends PyInspection {
}
for (String param : docString.getParameters()) {
- Substring type = docString.getParamTypeSubstring(param);
+ @NlsSafe Substring type = docString.getParamTypeSubstring(param);
if (type != null) {
String dynamicType = signature.getArgTypeQualifiedName(param);
if (dynamicType != null) {
- String dynamicTypeShortName = getShortestImportableName(function, dynamicType);
+ @NlsSafe String dynamicTypeShortName = getShortestImportableName(function, dynamicType);
if (!match(function, dynamicType, type.getValue())) {
- registerProblem(node, "Dynamically inferred type '" +
- dynamicTypeShortName +
- "' doesn't match specified type '" +
- type + "'",
+ registerProblem(node, PyPsiBundle.message("INSP.docstring.types.dynamically.inferred.type.does.not.match.specified.type",
+ dynamicTypeShortName, type),
ProblemHighlightType.WEAK_WARNING, null, type.getTextRange(),
new ChangeTypeQuickFix(param, type, dynamicTypeShortName, node)
);
diff --git a/python/python-psi-impl/src/com/jetbrains/python/inspections/PyDunderSlotsInspection.kt b/python/python-psi-impl/src/com/jetbrains/python/inspections/PyDunderSlotsInspection.kt
index 4edaa0aa9e3b..3d7b672858bb 100644
--- a/python/python-psi-impl/src/com/jetbrains/python/inspections/PyDunderSlotsInspection.kt
+++ b/python/python-psi-impl/src/com/jetbrains/python/inspections/PyDunderSlotsInspection.kt
@@ -5,6 +5,7 @@ import com.intellij.codeInspection.LocalInspectionToolSession
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.PsiElementVisitor
import com.jetbrains.python.PyNames
+import com.jetbrains.python.PyPsiBundle
import com.jetbrains.python.psi.*
import com.jetbrains.python.psi.impl.PyPsiUtils
import com.jetbrains.python.psi.types.PyClassType
@@ -57,7 +58,7 @@ class PyDunderSlotsInspection : PyInspection() {
val classAttribute = pyClass.findClassAttribute(name, false, myTypeEvalContext)
if (classAttribute != null && classAttribute.hasAssignedValue()) {
- registerProblem(slot, "'$name' in __slots__ conflicts with class variable")
+ registerProblem(slot, PyPsiBundle.message("INSP.dunder.slots.name.in.slots.conflicts.with.class.variable", name))
}
}
@@ -71,7 +72,7 @@ class PyDunderSlotsInspection : PyInspection() {
val qualifierType = myTypeEvalContext.getType(qualifier)
if (qualifierType is PyClassType && !qualifierType.isAttributeWritable(targetName, myTypeEvalContext)) {
- registerProblem(target, "'${qualifierType.name}' object attribute '$targetName' is read-only")
+ registerProblem(target, PyPsiBundle.message("INSP.dunder.slots.class.object.attribute.read.only", qualifierType.name, targetName))
}
}
}
diff --git a/python/python-psi-impl/src/com/jetbrains/python/inspections/PyExceptionInheritInspection.java b/python/python-psi-impl/src/com/jetbrains/python/inspections/PyExceptionInheritInspection.java
index 91003f6920b2..caa92e04909c 100644
--- a/python/python-psi-impl/src/com/jetbrains/python/inspections/PyExceptionInheritInspection.java
+++ b/python/python-psi-impl/src/com/jetbrains/python/inspections/PyExceptionInheritInspection.java
@@ -20,6 +20,7 @@ import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiPolyVariantReference;
+import com.jetbrains.python.PyPsiBundle;
import com.jetbrains.python.inspections.quickfix.PyAddExceptionSuperClassQuickFix;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.types.PyClassLikeType;
@@ -67,7 +68,9 @@ public class PyExceptionInheritInspection extends PyInspection {
return;
}
}
- registerProblem(expression, "Exception doesn't inherit from base 'Exception' class", new PyAddExceptionSuperClassQuickFix());
+ registerProblem(expression,
+ PyPsiBundle.message("INSP.exception.inheritance.exception.does.not.inherit.from.base.exception.class"),
+ new PyAddExceptionSuperClassQuickFix());
}
}
}
diff --git a/python/testData/deprecation/abcDeprecatedAbstracts.py b/python/testData/deprecation/abcDeprecatedAbstracts.py
index 2c4ea6ce8023..81b5af0d51f6 100644
--- a/python/testData/deprecation/abcDeprecatedAbstracts.py
+++ b/python/testData/deprecation/abcDeprecatedAbstracts.py
@@ -2,7 +2,7 @@ import abc
class A(metaclass=abc.ABCMeta):
- @abc.abstractproperty
+ @abc.abstractproperty
def prop(self):
pass
@@ -11,7 +11,7 @@ from abc import abstractproperty
class B(metaclass=abc.ABCMeta):
- @abstractproperty
+ @abstractproperty
def prop(self):
pass
@@ -20,7 +20,7 @@ from abc import abstractproperty as ap
class C(metaclass=abc.ABCMeta):
- @ap
+ @ap
def prop(self):
pass
@@ -29,16 +29,16 @@ import abc as foo
class D(metaclass=abc.ABCMeta):
- @foo.abstractproperty
+ @foo.abstractproperty
def prop(self):
pass
class A:
- @abc.abstractclassmethod
+ @abc.abstractclassmethod
def foo(cls):
pass
- @abc.abstractstaticmethod
+ @abc.abstractstaticmethod
def bar():
pass
\ No newline at end of file