mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
i18n: Extract messages from and annotate several Python inspections
* PyFinalInspection * PyFromFutureImportInspection * PyInconsistentIndentationInspection * PyInterpreterInspection * PyListCreationInspection * PyMandatoryEncodingInspection * PyMissingTypeHintsInspection * PyNonAsciiCharInspection * PyOverloadsInspection * PyPackageRequirementsInspection * PyPep8NamingInspection * PyPropertyDefinitionInspection * PyProtectedMemberInspection * PyProtocolInspection * PyShadowingBuiltinsInspection * PyStatementEffectInspection * PyStringFormatInspection * PyTupleAssignmentBalanceInspection I also replaced some existing message keys that used poorly recognized "$1" notation or otherwise diverged from the convention in use, and updated annotations in PythonUiService where needed. GitOrigin-RevId: 75d73d38104c806ad5065e87f76e274b502e889d
This commit is contained in:
committed by
intellij-monorepo-bot
parent
1b58c59529
commit
0e3afcf3ef
@@ -133,10 +133,10 @@
|
||||
<localInspection language="Python" shortName="PyDictDuplicateKeysInspection" suppressId="PyDictDuplicateKeys" bundle="messages.PyPsiBundle" key="INSP.NAME.duplicate.keys" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyDictDuplicateKeysInspection"/>
|
||||
<localInspection language="Python" shortName="PyDunderSlotsInspection" suppressId="PyDunderSlots" bundle="messages.PyPsiBundle" key="INSP.NAME.dunder.slots" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyDunderSlotsInspection"/>
|
||||
<localInspection language="Python" shortName="PyExceptClausesOrderInspection" suppressId="PyExceptClausesOrder" bundle="messages.PyPsiBundle" key="INSP.NAME.bad.except.clauses.order" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyExceptClausesOrderInspection"/>
|
||||
<localInspection language="Python" shortName="PyFinalInspection" suppressId="PyFinal" bundle="messages.PyPsiBundle" key="INSP.final.classes.methods.and.variables" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyFinalInspection"/>
|
||||
<localInspection language="Python" shortName="PyFinalInspection" suppressId="PyFinal" bundle="messages.PyPsiBundle" key="INSP.NAME.final.classes.methods.and.variables" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyFinalInspection"/>
|
||||
<localInspection language="Python" shortName="PyFromFutureImportInspection" suppressId="PyFromFutureImport" bundle="messages.PyPsiBundle" key="INSP.NAME.from.future.import" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyFromFutureImportInspection"/>
|
||||
<localInspection language="Python" shortName="PyGlobalUndefinedInspection" suppressId="PyGlobalUndefined" bundle="messages.PyPsiBundle" key="INSP.global.undefined" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WEAK WARNING" implementationClass="com.jetbrains.python.inspections.PyGlobalUndefinedInspection"/>
|
||||
<localInspection language="Python" shortName="PyInconsistentIndentationInspection" suppressId="PyInconsistentIndentation" bundle="messages.PyPsiBundle" key="INSP.inconsistent.indentation" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyInconsistentIndentationInspection"/>
|
||||
<localInspection language="Python" shortName="PyInconsistentIndentationInspection" suppressId="PyInconsistentIndentation" bundle="messages.PyPsiBundle" key="INSP.NAME.inconsistent.indentation" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyInconsistentIndentationInspection"/>
|
||||
<localInspection language="Python" shortName="PyIncorrectDocstringInspection" suppressId="PyIncorrectDocstring" bundle="messages.PyPsiBundle" key="INSP.NAME.incorrect.docstring" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WEAK WARNING" implementationClass="com.jetbrains.python.inspections.PyIncorrectDocstringInspection"/>
|
||||
<localInspection language="Python" shortName="PyMissingOrEmptyDocstringInspection" suppressId="PyMissingOrEmptyDocstring" bundle="messages.PyPsiBundle" key="INSP.NAME.missing.or.empty.docstring" groupKey="INSP.GROUP.python" enabledByDefault="false" level="WEAK WARNING" implementationClass="com.jetbrains.python.inspections.PyMissingOrEmptyDocstringInspection"/>
|
||||
<localInspection language="Python" shortName="PyNamedTupleInspection" suppressId="PyNamedTuple" bundle="messages.PyPsiBundle" key="INSP.named.tuple" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyNamedTupleInspection"/>
|
||||
@@ -150,7 +150,7 @@
|
||||
<localInspection language="Python" shortName="PyInitNewSignatureInspection" suppressId="PyInitNewSignature" bundle="messages.PyPsiBundle" key="INSP.NAME.new.init.signature" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyInitNewSignatureInspection"/>
|
||||
<localInspection language="Python" shortName="PyTrailingSemicolonInspection" suppressId="PyTrailingSemicolon" bundle="messages.PyPsiBundle" key="INSP.NAME.trailing.semicolon" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyTrailingSemicolonInspection"/>
|
||||
<localInspection language="Python" shortName="PyReturnFromInitInspection" suppressId="PyReturnFromInit" bundle="messages.PyPsiBundle" key="INSP.NAME.init.return" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyReturnFromInitInspection"/>
|
||||
<localInspection language="Python" shortName="PyTupleAssignmentBalanceInspection" suppressId="PyTupleAssignmentBalance" bundle="messages.PyPsiBundle" key="INSP.NAME.incorrect.assignment" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyTupleAssignmentBalanceInspection"/>
|
||||
<localInspection language="Python" shortName="PyTupleAssignmentBalanceInspection" suppressId="PyTupleAssignmentBalance" bundle="messages.PyPsiBundle" key="INSP.NAME.tuple.assignment.balance" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyTupleAssignmentBalanceInspection"/>
|
||||
<localInspection language="Python" shortName="PyClassicStyleClassInspection" suppressId="PyClassicStyleClass" bundle="messages.PyPsiBundle" key="INSP.NAME.classic.class.usage" groupKey="INSP.GROUP.python" enabledByDefault="false" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyClassicStyleClassInspection"/>
|
||||
<localInspection language="Python" shortName="PyExceptionInheritInspection" suppressId="PyExceptionInherit" bundle="messages.PyPsiBundle" key="INSP.NAME.exception.not.inherit" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyExceptionInheritInspection"/>
|
||||
<localInspection language="Python" shortName="PyUnboundLocalVariableInspection" suppressId="PyUnboundLocalVariable" bundle="messages.PyPsiBundle" key="INSP.NAME.unbound" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyUnboundLocalVariableInspection"/>
|
||||
@@ -172,22 +172,22 @@
|
||||
<localInspection language="Python" shortName="PyDecoratorInspection" suppressId="PyDecorator" bundle="messages.PyPsiBundle" key="INSP.NAME.decorator.outside.class" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyDecoratorInspection"/>
|
||||
<localInspection language="Python" shortName="PyTypeCheckerInspection" suppressId="PyTypeChecker" bundle="messages.PyPsiBundle" key="INSP.type.checker" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyTypeCheckerInspection"/>
|
||||
<localInspection language="Python" shortName="PyDeprecationInspection" suppressId="PyDeprecation" bundle="messages.PyPsiBundle" key="INSP.NAME.deprecated.function.class.or.module" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyDeprecationInspection"/>
|
||||
<localInspection language="Python" shortName="PyMandatoryEncodingInspection" suppressId="PyMandatoryEncoding" bundle="messages.PyPsiBundle" key="INSP.mandatory.encoding" groupKey="INSP.GROUP.python" enabledByDefault="false" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyMandatoryEncodingInspection"/>
|
||||
<localInspection language="Python" shortName="PyMandatoryEncodingInspection" suppressId="PyMandatoryEncoding" bundle="messages.PyPsiBundle" key="INSP.NAME.mandatory.encoding" groupKey="INSP.GROUP.python" enabledByDefault="false" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyMandatoryEncodingInspection"/>
|
||||
<localInspection language="Python" shortName="PyClassHasNoInitInspection" suppressId="PyClassHasNoInit" bundle="messages.PyPsiBundle" key="INSP.class.has.no.init" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WEAK WARNING" implementationClass="com.jetbrains.python.inspections.PyClassHasNoInitInspection"/>
|
||||
<localInspection language="Python" shortName="PyNoneFunctionAssignmentInspection" suppressId="PyNoneFunctionAssignment" bundle="messages.PyPsiBundle" key="INSP.assigning.function.call.that.doesnt.return.anything" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WEAK WARNING" implementationClass="com.jetbrains.python.inspections.PyNoneFunctionAssignmentInspection"/>
|
||||
<localInspection language="Python" shortName="PyProtectedMemberInspection" suppressId="PyProtectedMember" bundle="messages.PyPsiBundle" key="INSP.protected.member" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WEAK WARNING" implementationClass="com.jetbrains.python.inspections.PyProtectedMemberInspection"/>
|
||||
<localInspection language="Python" shortName="PyProtectedMemberInspection" suppressId="PyProtectedMember" bundle="messages.PyPsiBundle" key="INSP.NAME.protected.member" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WEAK WARNING" implementationClass="com.jetbrains.python.inspections.PyProtectedMemberInspection"/>
|
||||
<localInspection language="Python" shortName="PyMethodMayBeStaticInspection" suppressId="PyMethodMayBeStatic" bundle="messages.PyPsiBundle" key="INSP.method.may.be.static" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WEAK WARNING" implementationClass="com.jetbrains.python.inspections.PyMethodMayBeStaticInspection"/>
|
||||
<localInspection language="Python" shortName="PyDocstringTypesInspection" suppressId="PyDocstringTypes" bundle="messages.PyPsiBundle" key="INSP.NAME.docstring.types" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WEAK WARNING" implementationClass="com.jetbrains.python.inspections.PyDocstringTypesInspection"/>
|
||||
<localInspection language="Python" shortName="PyShadowingNamesInspection" suppressId="PyShadowingNames" bundle="messages.PyPsiBundle" key="INSP.shadowing.names" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WEAK WARNING" implementationClass="com.jetbrains.python.inspections.PyShadowingNamesInspection"/>
|
||||
<localInspection language="Python" shortName="PyAbstractClassInspection" suppressId="PyAbstractClass" bundle="messages.PyPsiBundle" key="INSP.abstract.class" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WEAK WARNING" implementationClass="com.jetbrains.python.inspections.PyAbstractClassInspection"/>
|
||||
<localInspection language="Python" shortName="PyMissingTypeHintsInspection" suppressId="PyMissingTypeHints" bundle="messages.PyPsiBundle" key="INSP.missing.type.hints" groupKey="INSP.GROUP.python" enabledByDefault="false" level="WEAK WARNING" implementationClass="com.jetbrains.python.inspections.PyMissingTypeHintsInspection"/>
|
||||
<localInspection language="Python" shortName="PyOverloadsInspection" suppressId="PyOverloads" bundle="messages.PyPsiBundle" key="INSP.overloads.in.regular.python.files" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyOverloadsInspection"/>
|
||||
<localInspection language="Python" shortName="PyProtocolInspection" suppressId="PyProtocol" bundle="messages.PyPsiBundle" key="INSP.protocol.definition.and.usages" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyProtocolInspection"/>
|
||||
<localInspection language="Python" shortName="PyMissingTypeHintsInspection" suppressId="PyMissingTypeHints" bundle="messages.PyPsiBundle" key="INSP.NAME.missing.type.hints" groupKey="INSP.GROUP.python" enabledByDefault="false" level="WEAK WARNING" implementationClass="com.jetbrains.python.inspections.PyMissingTypeHintsInspection"/>
|
||||
<localInspection language="Python" shortName="PyOverloadsInspection" suppressId="PyOverloads" bundle="messages.PyPsiBundle" key="INSP.NAME.overloads.in.regular.python.files" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyOverloadsInspection"/>
|
||||
<localInspection language="Python" shortName="PyProtocolInspection" suppressId="PyProtocol" bundle="messages.PyPsiBundle" key="INSP.NAME.protocol.definition.and.usages" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyProtocolInspection"/>
|
||||
<localInspection language="Python" shortName="PyTypeHintsInspection" suppressId="PyTypeHints" bundle="messages.PyPsiBundle" key="INSP.type.hints" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyTypeHintsInspection"/>
|
||||
<localInspection language="Python" shortName="PyTypedDictInspection" suppressId="PyTypedDict" bundle="messages.PyPsiBundle" key="INSP.typed.dict" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyTypedDictInspection"/>
|
||||
<localInspection language="Python" shortName="PyChainedComparisonsInspection" suppressId="PyChainedComparisons" bundle="messages.PyPsiBundle" key="INSP.NAME.chained.comparisons" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WEAK WARNING" implementationClass="com.jetbrains.python.inspections.PyChainedComparisonsInspection"/>
|
||||
<localInspection language="Python" shortName="PyPep8NamingInspection" suppressId="PyPep8Naming" bundle="messages.PyPsiBundle" key="INSP.pep8.naming" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WEAK WARNING" implementationClass="com.jetbrains.python.inspections.PyPep8NamingInspection"/>
|
||||
<localInspection language="Python" shortName="PyShadowingBuiltinsInspection" suppressId="PyShadowingBuiltins" bundle="messages.PyPsiBundle" key="INSP.shadowing.builtins" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WEAK WARNING" implementationClass="com.jetbrains.python.inspections.PyShadowingBuiltinsInspection"/>
|
||||
<localInspection language="Python" shortName="PyPep8NamingInspection" suppressId="PyPep8Naming" bundle="messages.PyPsiBundle" key="INSP.NAME.pep8.naming" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WEAK WARNING" implementationClass="com.jetbrains.python.inspections.PyPep8NamingInspection"/>
|
||||
<localInspection language="Python" shortName="PyShadowingBuiltinsInspection" suppressId="PyShadowingBuiltins" bundle="messages.PyPsiBundle" key="INSP.NAME.shadowing.builtins" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WEAK WARNING" implementationClass="com.jetbrains.python.inspections.PyShadowingBuiltinsInspection"/>
|
||||
|
||||
<intentionAction>
|
||||
<className>com.jetbrains.python.codeInsight.intentions.PyConvertMethodToPropertyIntention</className>
|
||||
|
||||
@@ -119,7 +119,6 @@ can.t.assign.to.await.expression=Can't assign to await expression
|
||||
for.expected='for' expected
|
||||
rarrow.expected='->' expected
|
||||
unexpected.tokens=Unexpected tokens
|
||||
enable.in.python.3=Enable in Python 3+
|
||||
|
||||
PARSE.function.type.annotations.py2=Type annotations are unsupported in Python 2
|
||||
PARSE.function.return.type.annotations.py2=Return type annotations are unsupported in Python 2
|
||||
@@ -438,13 +437,7 @@ INSP.GROUP.python=Python
|
||||
|
||||
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
|
||||
INSP.pep8.naming.excluded.base.classes=Excluded base classes
|
||||
INSP.pep8.naming.ignored.errors=Ignored errors
|
||||
INSP.shadowing.builtins=Shadowing built-ins
|
||||
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
|
||||
INSP.named.tuple=Namedtuple definition
|
||||
INSP.shadows.name.from.outer.scope=Shadows name ''{0}'' from outer scope
|
||||
INSP.trailing.semicolon=Trailing semicolon in the statement
|
||||
@@ -457,13 +450,7 @@ INSP.interpreter.configure.python.interpreter=Configure Python interpreter
|
||||
INSP.interpreter.interpreter.settings=Interpreter settings
|
||||
INSP.interpreter.use.interpreter=Use {0}
|
||||
INSP.interpreter.use.suggested.interpreter=Use suggested interpreter
|
||||
INSP.mandatory.encoding.encoding.comment.format=Encoding comment format:
|
||||
INSP.mandatory.encoding.select.default.encoding=Select default encoding:
|
||||
INSP.mandatory.encoding.no.encoding.specified.for.file=No encoding specified for file
|
||||
INSP.method.parameters.metaclass.method.first.argument.name=Metaclass method first argument name
|
||||
INSP.missing.type.hints.add.type.hints=Add type hints
|
||||
INSP.missing.type.hints.add.type.hints.for=Add type hints for ''{0}''
|
||||
INSP.missing.type.hints.only.when.types.are.known.collected.from.run.time.or.inferred=Only when types are known(collected from run-time or inferred)
|
||||
|
||||
INSP.package.requirements.requirements.have.been.ignored=Requirements have been ignored
|
||||
INSP.package.requirements.requirement.has.been.ignored=''{0}'' has been ignored
|
||||
@@ -477,21 +464,15 @@ INSP.package.requirements.administrator.privileges.required.button.configure=Con
|
||||
INSP.package.requirements.administrator.privileges.required.button.install.anyway=Install Anyway
|
||||
INSP.package.requirements.requirements.file.empty=Requirements file is empty
|
||||
INSP.package.requirements.quickfix.family.name=Add imported packages to requirements...
|
||||
INSP.pep8.ignore.base.class=Ignore base class
|
||||
INSP.pep8.ignore.base.class=Ignore Base Class
|
||||
INSP.pep8.ignore.method.names.for.descendants.of.class=Ignore method names for descendants of class
|
||||
INSP.shadowing.builtins.ignore.shadowed.built.in.name=Ignore shadowed built-in name
|
||||
INSP.stub.packages.compatibility.ignore=Ignore ''{0}'' compatibility
|
||||
INSP.stub.packages.compatibility.ignored.packages=Ignored stub packages
|
||||
INSP.stub.packages.compatibility.incompatible.packages.message=''{0}{1}{2}'' is incompatible with ''{3}{4}{5}''. Expected ''{6}'' version: [{7}]
|
||||
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.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
|
||||
INSP.pep8.coding.style.violation=PEP 8 coding style violation
|
||||
INSP.protected.member=Access to a protected member of a class or a module
|
||||
INSP.protocol.definition.and.usages=Protocol definition and usages
|
||||
INSP.shadowing.names=Shadowing names from outer scopes
|
||||
INSP.stub.packages.compatibility=Stub packages compatibility inspection
|
||||
INSP.stub.packages=Stub packages advertiser
|
||||
@@ -542,6 +523,16 @@ INSP.unused.import.statement=Unused import statement <code>#ref</code>
|
||||
|
||||
# PyInterpreterInspection
|
||||
INSP.NAME.invalid.interpreter=Invalid interpreter configured
|
||||
INSP.interpreter.pipenv.interpreter.associated.with.another.project=Pipenv interpreter is associated with another project: ''{0}''
|
||||
INSP.interpreter.pipenv.interpreter.associated.with.another.module=Pipenv interpreter is associated with another module: ''{0}''
|
||||
INSP.interpreter.pipenv.interpreter.not.associated.with.any.project=Pipenv interpreter is not associated with any project
|
||||
INSP.interpreter.pipenv.interpreter.not.associated.with.any.module=Pipenv interpreter is not associated with any module
|
||||
INSP.interpreter.invalid.python.interpreter.selected.for.project=Invalid Python interpreter selected for the project
|
||||
INSP.interpreter.invalid.python.interpreter.selected.for.module=Invalid Python interpreter selected for the module
|
||||
INSP.interpreter.python.has.reached.its.end.of.life.and.is.no.longer.supported.in.pycharm=Python {0} has reached its end-of-life date and it is no longer supported in PyCharm
|
||||
INSP.interpreter.python.has.reached.its.end.life.and.is.no.longer.supported.in.python.plugin=Python {0} has reached its end-of-life date and it is no longer supported in Python plugin
|
||||
INSP.interpreter.no.python.interpreter.configured.for.project=No Python interpreter configured for the project
|
||||
INSP.interpreter.no.python.interpreter.configured.for.module=No Python interpreter configured for the module
|
||||
|
||||
# ReturnValueFromInitInspection
|
||||
INSP.NAME.init.return=__init__ method that returns a value
|
||||
@@ -554,8 +545,8 @@ INSP.unreachable.code=This code is unreachable
|
||||
# PyStringFormatInspection
|
||||
INSP.NAME.str.format=Errors in string formatting operations
|
||||
INSP.format.requires.no.mapping=Format doesn't require a mapping
|
||||
INSP.key.$0.has.no.arg=Key ''{0}'' has no corresponding argument
|
||||
INSP.unexpected.type.$0=Unexpected type {0}
|
||||
INSP.str.format.key.has.no.argument=Key ''{0}'' has no corresponding argument
|
||||
INSP.str.format.unexpected.argument.type=Unexpected type {0}
|
||||
INSP.too.few.keys=Too few mapping keys
|
||||
INSP.no.format.specifier.char=Format specifier character missing
|
||||
INSP.format.requires.mapping=Format requires a mapping
|
||||
@@ -566,6 +557,8 @@ INSP.unused.mapping = Mapping key "{0}" is unused
|
||||
INSP.unsupported.format.character=Unsupported format character ''{0}''
|
||||
INSP.manual.to.auto.field.numbering=Cannot switch from manual field specification to automatic field numbering
|
||||
INSP.auto.to.manual.field.numbering=Cannot switch from automatic field numbering to manual field specification
|
||||
INSP.str.format.unsupported.format.character.b=Unsupported format character 'b'
|
||||
INSP.str.format.can.not.use.star.in.formats.when.using.mapping=Can't use '*' in formats when using a mapping
|
||||
|
||||
# PyMethodOverridingInspection
|
||||
INSP.NAME.method.over=Method signature does not match signature of overridden method
|
||||
@@ -589,9 +582,13 @@ INSP.unbound.function.too.large=Function ''{0}'' is too large to analyse
|
||||
|
||||
# PyListCreationInspection
|
||||
INSP.NAME.list.creation=List creation could be rewritten by list literal
|
||||
INSP.list.creation.this.list.creation.could.be.rewritten.as.list.literal=This list creation could be rewritten as a list literal
|
||||
|
||||
# PyTupleAssignmentBalanceInspection
|
||||
INSP.NAME.incorrect.assignment=Tuple assignment balance is incorrect
|
||||
INSP.NAME.tuple.assignment.balance=Tuple assignment balance is incorrect
|
||||
INSP.tuple.assignment.balance.only.one.starred.expression.allowed.in.assignment=Only one starred expression allowed in assignment
|
||||
INSP.tuple.assignment.balance.need.more.values.to.unpack=Need more values to unpack
|
||||
INSP.tuple.assignment.balance.too.many.values.to.unpack=Too many values to unpack
|
||||
|
||||
# PyClassicStyleClassInspection
|
||||
INSP.NAME.classic.class.usage=Classic style class usage
|
||||
@@ -613,7 +610,8 @@ INSP.docstring.types.dynamically.inferred.type.does.not.match.specified.type=Dyn
|
||||
|
||||
# PyStatementEffectInspection
|
||||
INSP.NAME.statement.effect=Statement has no effect
|
||||
INSP.NAME.statement.message=Statement seems to have no effect
|
||||
INSP.statement.effect.statement.seems.to.have.no.effect=Statement seems to have no effect
|
||||
INSP.statement.effect.statement.having.no.effect.can.be.replaced.with.function.call=Statement seems to have no effect and can be replaced with function call to have effect
|
||||
|
||||
# PyStringExceptionInspection
|
||||
INSP.NAME.raising.string.exception=Raising a string exception
|
||||
@@ -622,11 +620,16 @@ INSP.NAME.raising.string.exception=Raising a string exception
|
||||
INSP.NAME.wrong.super.arguments=Wrong arguments to call super
|
||||
INSP.$0.is.not.superclass.of.$1=''{0}'' is not an instance or a subclass of ''{1}''
|
||||
|
||||
# PynonAsciiCharInspection
|
||||
# PyNonAsciiCharInspection
|
||||
INSP.NAME.non.ascii=File contains non-ASCII character
|
||||
INSP.non.ascii.char.non.ascii.character.in.file.but.no.encoding.declared=Non-ASCII character ''{0}'' in file, but no encoding declared
|
||||
|
||||
# PyMandatoryEncodingInspection
|
||||
INSP.NAME.mandatory.encoding=No encoding specified for file
|
||||
INSP.mandatory.encoding.label.encoding.comment.format=Encoding comment format:
|
||||
INSP.mandatory.encoding.label.select.default.encoding=Select default encoding:
|
||||
INSP.mandatory.encoding.checkbox.enable.in.python.3=Enable in Python 3+
|
||||
INSP.mandatory.encoding.no.encoding.specified.for.file=No encoding specified for file
|
||||
|
||||
# PyTupleItemAssignmentInspection
|
||||
INSP.NAME.tuple.item.assignment=Tuple item assignment
|
||||
@@ -652,8 +655,10 @@ INSP.deleter.signature.advice=Deleter signature should be (self)
|
||||
INSP.accessor.first.param.is.$0=First parameter of an accessor is usually called ''{0}''
|
||||
|
||||
# PyProtectedMemberInspection
|
||||
INSP.protected.member.$0.access=Access to a protected member {0} of a class
|
||||
INSP.protected.member.$0.access.module=Access to a protected member {0} of a module
|
||||
INSP.NAME.protected.member=Access to a protected member of a class or a module
|
||||
INSP.protected.member.access.to.protected.member.of.class=Access to a protected member {0} of a class
|
||||
INSP.protected.member.access.to.protected.member.of.module=Access to a protected member {0} of a module
|
||||
INSP.protected.member.name.not.declared.in.all=''{0}'' is not declared in __all__
|
||||
|
||||
# PyOldStyleClassesInspection
|
||||
INSP.NAME.oldstyle.class=Old-style class contains new-style class features
|
||||
@@ -739,6 +744,11 @@ INSP.decorators.method.only.decorator.on.method.outside.class=Decorator {0} on m
|
||||
|
||||
# PyPackageRequirementsInspection
|
||||
INSP.NAME.requirements=Package requirements
|
||||
INSP.requirements.column.name.ignore.packages=Ignore Packages
|
||||
INSP.requirements.package.requirements.not.satisfied=Package {1,choice,1#requirement|2#requirements} {0} {1,choice,1#is|2#are} not satisfied
|
||||
INSP.requirements.package.containing.module.not.listed.in.project.requirements=Package containing module ''{0}'' is not listed in project requirements
|
||||
QFIX.NAME.install.requirements=Install {0,choice,1#requirement|2#requirements}
|
||||
QFIX.NAME.ignore.requirements=Ignore {0,choice,1#requirement|2#requirements}
|
||||
|
||||
# PyClassHasNoInitInspection
|
||||
INSP.NAME.class.has.no.init=Class has no __init__ method
|
||||
@@ -796,6 +806,7 @@ INSP.duplicate.keys.dictionary.contains.duplicate.keys=Dictionary contains dupli
|
||||
|
||||
# PyFromFutureImportInspection
|
||||
INSP.NAME.from.future.import=from __future__ import must be the first executable statement
|
||||
INSP.from.future.import.from.future.imports.must.occur.at.beginning.file=from __future__ imports must occur at the beginning of the file
|
||||
|
||||
# PyMethodFirstArgAssignmentInspection
|
||||
INSP.NAME.first.arg.assign=Reassignment of method's first argument
|
||||
@@ -907,17 +918,85 @@ INSP.dataclasses.method.should.be.called.on.attrs.types=''{0}'' method should be
|
||||
# PyHighlightingAnnotator
|
||||
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
|
||||
|
||||
# PyDunderSlotsInspection
|
||||
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
|
||||
|
||||
# PyFinalInspection
|
||||
INSP.NAME.final.classes.methods.and.variables=Final classes, methods and variables
|
||||
INSP.final.super.classes.are.marked.as.final.and.should.not.be.subclassed={0} {1,choice,1#is|2#are} marked as ''@final'' and should not be subclassed
|
||||
INSP.final.final.should.be.placed.on.first.overload='@final' should be placed on the first overload
|
||||
INSP.final.method.marked.as.final.should.not.be.overridden=''{0}'' is marked as ''@final'' and should not be overridden
|
||||
INSP.final.final.should.be.placed.on.implementation='@final' should be placed on the implementation
|
||||
INSP.final.final.could.not.be.mixed.with.abstract.decorators='Final' could not be mixed with abstract decorators
|
||||
INSP.final.final.class.could.not.contain.abstract.methods='Final' class could not contain abstract methods
|
||||
INSP.final.no.need.to.mark.method.in.final.class.as.final=No need to mark method in 'Final' class as '@final'
|
||||
INSP.final.non.method.function.could.not.be.marked.as.final=Non-method function could not be marked as '@final'
|
||||
INSP.final.final.could.not.be.used.in.annotations.for.function.parameters='Final' could not be used in annotations for function parameters
|
||||
INSP.final.final.could.not.be.used.in.annotation.for.function.return.value='Final' could not be used in annotation for function return value
|
||||
INSP.final.if.assigned.value.omitted.there.should.be.explicit.type.argument.to.final=If assigned value is omitted, there should be an explicit type argument to 'Final'
|
||||
INSP.final.final.name.should.be.initialized.with.value='Final' name should be initialized with a value
|
||||
INSP.final.already.declared.name.could.not.be.redefined.as.final=Already declared name could not be redefined as 'Final'
|
||||
INSP.final.either.instance.attribute.or.class.attribute.could.be.type.hinted.as.final=Either instance attribute or class attribute could be type hinted as 'Final'
|
||||
INSP.final.final.attribute.could.not.be.overridden=''{0}'' is ''Final'' and could not be overridden
|
||||
INSP.final.final.attribute.should.be.declared.in.class.body.or.init='Final' attribute should be declared in class body or '__init__'
|
||||
INSP.final.final.target.could.not.be.reassigned=''{0}'' is ''Final'' and could not be reassigned
|
||||
INSP.final.final.could.only.be.used.as.outermost.type='Final' could only be used as the outermost type
|
||||
INSP.final.final.could.not.be.used.inside.loop='Final' could not be used inside a loop
|
||||
|
||||
# PyInconsistentIndentationInspection
|
||||
INSP.NAME.inconsistent.indentation=Inconsistent indentation
|
||||
INSP.inconsistent.indentation.mix.tabs.spaces=Inconsistent indentation: mix of tabs and spaces
|
||||
INSP.inconsistent.indentation.previous.line.used.tabs.this.line.uses.spaces=Inconsistent indentation: previous line used tabs, this line uses spaces
|
||||
INSP.inconsistent.indentation.previous.line.used.spaces.this.line.uses.tabs=Inconsistent indentation: previous line used spaces, this line uses tabs
|
||||
|
||||
# PyMissingTypeHintsInspection
|
||||
INSP.NAME.missing.type.hints=Missing type hinting for function definition
|
||||
INSP.missing.type.hints.type.hinting.missing.for.function.definition=Type hinting is missing for function definition
|
||||
INSP.missing.type.hints.add.type.hints=Add type hints
|
||||
INSP.missing.type.hints.add.type.hints.for=Add type hints for ''{0}''
|
||||
INSP.missing.type.hints.checkbox.only.when.types.are.known=Only when types are known (collected from run-time or inferred)
|
||||
|
||||
# PyOverloadsInspection
|
||||
INSP.NAME.overloads.in.regular.python.files=Overloads in regular Python files
|
||||
INSP.overloads.series.overload.decorated.methods.should.always.be.followed.by.implementation=A series of @overload-decorated methods should always be followed by an implementation that is not @overload-ed
|
||||
INSP.overloads.series.overload.decorated.functions.should.always.be.followed.by.implementation=A series of @overload-decorated functions should always be followed by an implementation that is not @overload-ed
|
||||
INSP.overloads.this.method.overload.signature.not.compatible.with.implementation=Signature of this @overload-decorated method is not compatible with the implementation
|
||||
INSP.overloads.this.function.overload.signature.not.compatible.with.implementation=Signature of this @overload-decorated function is not compatible with the implementation
|
||||
|
||||
# PyPep8NamingInspection
|
||||
INSP.NAME.pep8.naming=PEP 8 naming convention violation
|
||||
INSP.pep8.naming.column.name.excluded.base.classes=Excluded Base Classes
|
||||
INSP.pep8.naming.column.name.ignored.errors=Ignored Errors
|
||||
QFIX.NAME.ignore.errors.like.this=Ignore errors like this
|
||||
INSP.pep8.naming.class.names.should.use.camelcase.convention=Class names should use CamelCase convention
|
||||
INSP.pep8.naming.function.name.should.be.lowercase=Function name should be lowercase
|
||||
INSP.pep8.naming.argument.name.should.be.lowercase=Argument name should be lowercase
|
||||
INSP.pep8.naming.variable.in.function.should.be.lowercase=Variable in function should be lowercase
|
||||
INSP.pep8.naming.constant.variable.imported.as.non.constant=Constant variable imported as non constant
|
||||
INSP.pep8.naming.lowercase.variable.imported.as.non.lowercase=Lowercase variable imported as non lowercase
|
||||
INSP.pep8.naming.camelcase.variable.imported.as.lowercase=CamelCase variable imported as lowercase
|
||||
INSP.pep8.naming.camelcase.variable.imported.as.constant=CamelCase variable imported as constant
|
||||
|
||||
# PyProtocolInspection
|
||||
INSP.NAME.protocol.definition.and.usages=Protocol definition and usages
|
||||
INSP.protocol.all.bases.protocol.must.be.protocols=All bases of a protocol must be protocols
|
||||
INSP.protocol.only.runtime.checkable.protocols.can.be.used.with.instance.class.checks=Only @runtime_checkable protocols can be used with instance and class checks
|
||||
INSP.protocol.newtype.cannot.be.used.with.protocol.classes=NewType cannot be used with protocol classes
|
||||
INSP.protocol.element.type.incompatible.with.protocol=Type of ''{0}'' is incompatible with ''{1}''
|
||||
|
||||
# PyShadowingBuiltinsInspection
|
||||
INSP.NAME.shadowing.builtins=Shadowing built-ins
|
||||
INSP.shadowing.builtins.shadows.built.in.name=Shadows built-in name ''{0}''
|
||||
INSP.shadowing.builtins.column.name.ignore.built.ins=Ignore Built-Ins
|
||||
QFIX.FAMILY.NAME.ignore.shadowed.built.in.name=Ignore shadowed built-in name
|
||||
QFIX.NAME.ignore.shadowed.built.in.name=Ignore shadowed built-in name "{0}"
|
||||
|
||||
# PyInspectionsSuppressor
|
||||
INSP.python.suppressor.suppress.for.function=Suppress for function
|
||||
INSP.python.suppressor.suppress.for.class=Suppress for class
|
||||
|
||||
@@ -10,7 +10,6 @@ import com.intellij.openapi.ui.InputValidator;
|
||||
import com.intellij.openapi.util.JDOMExternalizableStringList;
|
||||
import com.intellij.openapi.util.NlsContexts;
|
||||
import com.intellij.openapi.util.NlsContexts.Checkbox;
|
||||
import com.intellij.openapi.util.NlsContexts.Label;
|
||||
import com.intellij.openapi.util.NlsContexts.*;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -80,7 +79,7 @@ public class PythonUiService {
|
||||
return null;
|
||||
}
|
||||
|
||||
public JComponent createSingleCheckboxOptionsPanel(@Label String label, InspectionProfileEntry inspection, String property) {
|
||||
public JComponent createSingleCheckboxOptionsPanel(@Checkbox String label, InspectionProfileEntry inspection, String property) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -109,7 +108,7 @@ public class PythonUiService {
|
||||
return null;
|
||||
}
|
||||
|
||||
public JComponent createListEditForm(String title, List<String> stringList) {
|
||||
public JComponent createListEditForm(@ColumnName String title, List<String> stringList) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,9 +4,11 @@ package com.jetbrains.python.inspections
|
||||
import com.intellij.codeInspection.LocalInspectionToolSession
|
||||
import com.intellij.codeInspection.ProblemHighlightType
|
||||
import com.intellij.codeInspection.ProblemsHolder
|
||||
import com.intellij.openapi.util.NlsSafe
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiElementVisitor
|
||||
import com.jetbrains.python.PyNames
|
||||
import com.jetbrains.python.PyPsiBundle
|
||||
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner
|
||||
import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil
|
||||
import com.jetbrains.python.codeInsight.functionTypeComments.psi.PyFunctionTypeAnnotation
|
||||
@@ -33,8 +35,10 @@ class PyFinalInspection : PyInspection() {
|
||||
node.getSuperClasses(myTypeEvalContext).filter { isFinal(it) }.let { finalSuperClasses ->
|
||||
if (finalSuperClasses.isEmpty()) return@let
|
||||
|
||||
val postfix = " ${if (finalSuperClasses.size == 1) "is" else "are"} marked as '@final' and should not be subclassed"
|
||||
registerProblem(node.nameIdentifier, finalSuperClasses.joinToString(postfix = postfix) { "'${it.name}'" })
|
||||
@NlsSafe val superClassList = finalSuperClasses.joinToString { "'${it.name}'" }
|
||||
registerProblem(node.nameIdentifier,
|
||||
PyPsiBundle.message("INSP.final.super.classes.are.marked.as.final.and.should.not.be.subclassed",
|
||||
superClassList, finalSuperClasses.size))
|
||||
}
|
||||
|
||||
if (PyiUtil.isInsideStub(node)) {
|
||||
@@ -43,7 +47,7 @@ class PyFinalInspection : PyInspection() {
|
||||
node.visitMethods(
|
||||
{ m ->
|
||||
if (!visitedNames.add(m.name) && isFinal(m)) {
|
||||
registerProblem(m.nameIdentifier, "'@final' should be placed on the first overload")
|
||||
registerProblem(m.nameIdentifier, PyPsiBundle.message("INSP.final.final.should.be.placed.on.first.overload"))
|
||||
}
|
||||
true
|
||||
},
|
||||
@@ -71,13 +75,14 @@ class PyFinalInspection : PyInspection() {
|
||||
.filterIsInstance<PyFunction>()
|
||||
.firstOrNull { isFinal(it) }
|
||||
?.let {
|
||||
val qualifiedName = it.qualifiedName ?: it.containingClass?.name + "." + it.name
|
||||
registerProblem(node.nameIdentifier, "'$qualifiedName' is marked as '@final' and should not be overridden")
|
||||
@NlsSafe val qualifiedName = it.qualifiedName ?: it.containingClass?.name + "." + it.name
|
||||
registerProblem(node.nameIdentifier,
|
||||
PyPsiBundle.message("INSP.final.method.marked.as.final.should.not.be.overridden", qualifiedName))
|
||||
}
|
||||
|
||||
if (!PyiUtil.isInsideStub(node)) {
|
||||
if (isFinal(node) && PyiUtil.isOverload(node, myTypeEvalContext)) {
|
||||
registerProblem(node.nameIdentifier, "'@final' should be placed on the implementation")
|
||||
registerProblem(node.nameIdentifier, PyPsiBundle.message("INSP.final.final.should.be.placed.on.implementation"))
|
||||
}
|
||||
|
||||
checkInstanceFinalsOutsideInit(node)
|
||||
@@ -85,31 +90,34 @@ class PyFinalInspection : PyInspection() {
|
||||
|
||||
if (PyKnownDecoratorUtil.hasAbstractDecorator(node, myTypeEvalContext)) {
|
||||
if (isFinal(node)) {
|
||||
registerProblem(node.nameIdentifier, "'Final' could not be mixed with abstract decorators")
|
||||
registerProblem(node.nameIdentifier, PyPsiBundle.message("INSP.final.final.could.not.be.mixed.with.abstract.decorators"))
|
||||
}
|
||||
else if (isFinal(cls)) {
|
||||
val message = "'Final' class could not contain abstract methods"
|
||||
val message = PyPsiBundle.message("INSP.final.final.class.could.not.contain.abstract.methods")
|
||||
registerProblem(node.nameIdentifier, message)
|
||||
registerProblem(cls.nameIdentifier, message)
|
||||
}
|
||||
}
|
||||
else if (isFinal(node) && isFinal(cls)) {
|
||||
registerProblem(node.nameIdentifier, "No need to mark method in 'Final' class as '@final'", ProblemHighlightType.WEAK_WARNING)
|
||||
registerProblem(node.nameIdentifier, PyPsiBundle.message("INSP.final.no.need.to.mark.method.in.final.class.as.final"),
|
||||
ProblemHighlightType.WEAK_WARNING)
|
||||
}
|
||||
}
|
||||
else if (isFinal(node)) {
|
||||
registerProblem(node.nameIdentifier, "Non-method function could not be marked as '@final'")
|
||||
registerProblem(node.nameIdentifier, PyPsiBundle.message("INSP.final.non.method.function.could.not.be.marked.as.final"))
|
||||
}
|
||||
|
||||
getFunctionTypeAnnotation(node)?.let { comment ->
|
||||
if (comment.parameterTypeList.parameterTypes.any { resolvesToFinal(if (it is PySubscriptionExpression) it.operand else it) }) {
|
||||
registerProblem(node.typeComment, "'Final' could not be used in annotations for function parameters")
|
||||
registerProblem(node.typeComment,
|
||||
PyPsiBundle.message("INSP.final.final.could.not.be.used.in.annotations.for.function.parameters"))
|
||||
}
|
||||
}
|
||||
|
||||
getReturnTypeAnnotation(node, myTypeEvalContext)?.let {
|
||||
if (resolvesToFinal(if (it is PySubscriptionExpression) it.operand else it)) {
|
||||
registerProblem(node.typeComment ?: node.annotation, "'Final' could not be used in annotation for function return value")
|
||||
registerProblem(node.typeComment ?: node.annotation,
|
||||
PyPsiBundle.message("INSP.final.final.could.not.be.used.in.annotation.for.function.return.value"))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -121,12 +129,13 @@ class PyFinalInspection : PyInspection() {
|
||||
node.annotation?.value?.let {
|
||||
if (PyiUtil.isInsideStub(node) || ScopeUtil.getScopeOwner(node) is PyClass) {
|
||||
if (resolvesToFinal(it)) {
|
||||
registerProblem(it, "If assigned value is omitted, there should be an explicit type argument to 'Final'")
|
||||
registerProblem(it,
|
||||
PyPsiBundle.message("INSP.final.if.assigned.value.omitted.there.should.be.explicit.type.argument.to.final"))
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (resolvesToFinal(if (it is PySubscriptionExpression) it.operand else it)) {
|
||||
registerProblem(node, "'Final' name should be initialized with a value")
|
||||
registerProblem(node, PyPsiBundle.message("INSP.final.final.name.should.be.initialized.with.value"))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -136,7 +145,7 @@ class PyFinalInspection : PyInspection() {
|
||||
}
|
||||
|
||||
if (isFinal(node) && PyUtil.multiResolveTopPriority(node, resolveContext).any { it != node }) {
|
||||
registerProblem(node, "Already declared name could not be redefined as 'Final'")
|
||||
registerProblem(node, PyPsiBundle.message("INSP.final.already.declared.name.could.not.be.redefined.as.final"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,7 +153,8 @@ class PyFinalInspection : PyInspection() {
|
||||
super.visitPyNamedParameter(node)
|
||||
|
||||
if (isFinal(node)) {
|
||||
registerProblem(node.annotation?.value ?: node.typeComment, "'Final' could not be used in annotations for function parameters")
|
||||
registerProblem(node.annotation?.value ?: node.typeComment,
|
||||
PyPsiBundle.message("INSP.final.final.could.not.be.used.in.annotations.for.function.parameters"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,7 +219,7 @@ class PyFinalInspection : PyInspection() {
|
||||
initAttributes: Map<String, PyTargetExpression>) {
|
||||
classLevelFinals.forEach { (name, psi) ->
|
||||
if (!psi.hasAssignedValue() && name !in initAttributes) {
|
||||
registerProblem(psi, "'Final' name should be initialized with a value")
|
||||
registerProblem(psi, PyPsiBundle.message("INSP.final.final.name.should.be.initialized.with.value"))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -221,10 +231,10 @@ class PyFinalInspection : PyInspection() {
|
||||
|
||||
if (sameNameClassLevelFinal != null && isFinal(initAttribute)) {
|
||||
if (sameNameClassLevelFinal.hasAssignedValue()) {
|
||||
registerProblem(initAttribute, "Already declared name could not be redefined as 'Final'")
|
||||
registerProblem(initAttribute, PyPsiBundle.message("INSP.final.already.declared.name.could.not.be.redefined.as.final"))
|
||||
}
|
||||
else {
|
||||
val message = "Either instance attribute or class attribute could be type hinted as 'Final'"
|
||||
val message = PyPsiBundle.message("INSP.final.either.instance.attribute.or.class.attribute.could.be.type.hinted.as.final")
|
||||
registerProblem(sameNameClassLevelFinal, message)
|
||||
registerProblem(initAttribute, message)
|
||||
}
|
||||
@@ -256,7 +266,8 @@ class PyFinalInspection : PyInspection() {
|
||||
if (notRegistered.isEmpty()) return
|
||||
|
||||
for (commonFinal in newFinals.keys.intersect(inheritedFinals.keys)) {
|
||||
registerProblem(newFinals[commonFinal], "'$ancestorName.$commonFinal' is 'Final' and could not be overridden")
|
||||
@NlsSafe val qualifiedName = "$ancestorName.$commonFinal"
|
||||
registerProblem(newFinals[commonFinal], PyPsiBundle.message("INSP.final.final.attribute.could.not.be.overridden", qualifiedName))
|
||||
notRegistered.remove(commonFinal)
|
||||
}
|
||||
}
|
||||
@@ -267,7 +278,7 @@ class PyFinalInspection : PyInspection() {
|
||||
val instanceAttributes = mutableMapOf<String, PyTargetExpression>()
|
||||
PyClassImpl.collectInstanceAttributes(method, instanceAttributes)
|
||||
instanceAttributes.values.forEach {
|
||||
if (isFinal(it)) registerProblem(it, "'Final' attribute should be declared in class body or '__init__'")
|
||||
if (isFinal(it)) registerProblem(it, PyPsiBundle.message("INSP.final.final.attribute.should.be.declared.in.class.body.or.init"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -285,7 +296,7 @@ class PyFinalInspection : PyInspection() {
|
||||
}
|
||||
|
||||
if (resolved.any { it is PyTargetExpression && isFinal(it) }) {
|
||||
registerProblem(target, "'${target.name}' is 'Final' and could not be reassigned")
|
||||
registerProblem(target, PyPsiBundle.message("INSP.final.final.target.could.not.be.reassigned", target.name))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -293,7 +304,7 @@ class PyFinalInspection : PyInspection() {
|
||||
if (myTypeEvalContext.maySwitchToAST(e) &&
|
||||
e.parent.let { it is PyNonlocalStatement || it is PyGlobalStatement } &&
|
||||
PyUtil.multiResolveTopPriority(e, resolveContext).any { it is PyTargetExpression && isFinal(it) }) {
|
||||
registerProblem(target, "'${target.name}' is 'Final' and could not be reassigned")
|
||||
registerProblem(target, PyPsiBundle.message("INSP.final.final.target.could.not.be.reassigned", target.name))
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -315,13 +326,14 @@ class PyFinalInspection : PyInspection() {
|
||||
ScopeUtil.getScopeOwner(target).let { it is PyFunction && PyUtil.turnConstructorIntoClass(it) == cls }) {
|
||||
return
|
||||
}
|
||||
registerProblem(target, "'$name' is 'Final' and could not be reassigned")
|
||||
registerProblem(target, PyPsiBundle.message("INSP.final.final.target.could.not.be.reassigned", name))
|
||||
}
|
||||
|
||||
for (ancestor in cls.getAncestorClasses(myTypeEvalContext)) {
|
||||
val inheritedClassAttribute = ancestor.findClassAttribute(name, false, myTypeEvalContext)
|
||||
if (inheritedClassAttribute != null && !inheritedClassAttribute.hasAssignedValue() && isFinal(inheritedClassAttribute)) {
|
||||
registerProblem(target, "'${ancestor.name}.$name' is 'Final' and could not be reassigned")
|
||||
@NlsSafe val qualifiedName = "${ancestor.name}.$name"
|
||||
registerProblem(target, PyPsiBundle.message("INSP.final.final.target.could.not.be.reassigned", qualifiedName))
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -332,8 +344,8 @@ class PyFinalInspection : PyInspection() {
|
||||
val attributesInInit = mutableMapOf<String, PyTargetExpression>()
|
||||
PyClassImpl.collectInstanceAttributes(init, attributesInInit)
|
||||
if (attributesInInit[name]?.let { it != target && isFinal(it) } == true) {
|
||||
val qualifier = if (cls == current) "" else "${current.name}."
|
||||
registerProblem(target, "'$qualifier$name' is 'Final' and could not be reassigned")
|
||||
@NlsSafe val qualifiedName = (if (cls == current) "" else "${current.name}.") + name
|
||||
registerProblem(target, PyPsiBundle.message("INSP.final.final.target.could.not.be.reassigned", qualifiedName))
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -347,7 +359,8 @@ class PyFinalInspection : PyInspection() {
|
||||
val ancestorClassAttribute = ancestor.findClassAttribute(name, false, myTypeEvalContext)
|
||||
|
||||
if (ancestorClassAttribute != null && ancestorClassAttribute.hasAssignedValue() && isFinal(ancestorClassAttribute)) {
|
||||
registerProblem(target, "'${ancestor.name}.$name' is 'Final' and could not be reassigned")
|
||||
@NlsSafe val qualifiedName = "${ancestor.name}.$name"
|
||||
registerProblem(target, PyPsiBundle.message("INSP.final.final.target.could.not.be.reassigned", qualifiedName))
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -360,7 +373,7 @@ class PyFinalInspection : PyInspection() {
|
||||
}
|
||||
|
||||
if (isInAnnotationOrTypeComment(node) && resolvesToFinal(node)) {
|
||||
registerProblem(node, "'Final' could only be used as the outermost type")
|
||||
registerProblem(node, PyPsiBundle.message("INSP.final.final.could.only.be.used.as.outermost.type"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -376,7 +389,7 @@ class PyFinalInspection : PyInspection() {
|
||||
override fun visitPyWhileStatement(node: PyWhileStatement) {}
|
||||
|
||||
override fun visitPyTargetExpression(node: PyTargetExpression) {
|
||||
if (isFinal(node)) registerProblem(node, "'Final' could not be used inside a loop")
|
||||
if (isFinal(node)) registerProblem(node, PyPsiBundle.message("INSP.final.final.could.not.be.used.inside.loop"))
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
+2
-1
@@ -20,6 +20,7 @@ import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.PyPsiBundle;
|
||||
import com.jetbrains.python.inspections.quickfix.MoveFromFutureImportQuickFix;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -69,7 +70,7 @@ public class PyFromFutureImportInspection extends PyInspection {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
registerProblem(node, "from __future__ imports must occur at the beginning of the file",
|
||||
registerProblem(node, PyPsiBundle.message("INSP.from.future.import.from.future.imports.must.occur.at.beginning.file"),
|
||||
new MoveFromFutureImportQuickFix());
|
||||
return;
|
||||
}
|
||||
|
||||
+8
-5
@@ -18,15 +18,16 @@ package com.jetbrains.python.inspections;
|
||||
import com.intellij.codeInspection.InspectionManager;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.codeInspection.ProblemHighlightType;
|
||||
import com.intellij.codeInspection.util.InspectionMessage;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.jetbrains.python.PyPsiBundle;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.PythonLanguage;
|
||||
import com.jetbrains.python.inspections.quickfix.ConvertIndentsFix;
|
||||
import com.jetbrains.python.lexer.PythonIndentingLexer;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -94,7 +95,7 @@ public class PyInconsistentIndentationInspection extends PyInspection {
|
||||
}
|
||||
final int problemStart = tokenStart + lastLF + 1;
|
||||
if (spaces > 0 && tabs > 0) {
|
||||
reportProblem("Inconsistent indentation: mix of tabs and spaces", problemStart, length);
|
||||
reportProblem(PyPsiBundle.message("INSP.inconsistent.indentation.mix.tabs.spaces"), problemStart, length);
|
||||
// don't know which one is correct => don't complain about inconsistent indentation on subsequent lines which use
|
||||
// either tabs or spaces
|
||||
myLastSpaces = 0;
|
||||
@@ -102,10 +103,12 @@ public class PyInconsistentIndentationInspection extends PyInspection {
|
||||
}
|
||||
else {
|
||||
if (spaces > 0 && myLastTabs > 0) {
|
||||
reportProblem("Inconsistent indentation: previous line used tabs, this line uses spaces", problemStart, length);
|
||||
reportProblem(PyPsiBundle.message("INSP.inconsistent.indentation.previous.line.used.tabs.this.line.uses.spaces"),
|
||||
problemStart, length);
|
||||
}
|
||||
else if (tabs > 0 && myLastSpaces > 0) {
|
||||
reportProblem("Inconsistent indentation: previous line used spaces, this line uses tabs", problemStart, length);
|
||||
reportProblem(PyPsiBundle.message("INSP.inconsistent.indentation.previous.line.used.spaces.this.line.uses.tabs"),
|
||||
problemStart, length);
|
||||
}
|
||||
if (spaces > 0 || tabs > 0) {
|
||||
myLastTabs = tabs;
|
||||
@@ -114,7 +117,7 @@ public class PyInconsistentIndentationInspection extends PyInspection {
|
||||
}
|
||||
}
|
||||
|
||||
private void reportProblem(final String descriptionTemplate, final int problemStart, final int problemLength) {
|
||||
private void reportProblem(@InspectionMessage String descriptionTemplate, final int problemStart, final int problemLength) {
|
||||
PsiElement elt = myFile.findElementAt(problemStart);
|
||||
int startOffset = problemStart - elt.getTextRange().getStartOffset();
|
||||
int endOffset = startOffset + problemLength;
|
||||
|
||||
+2
-1
@@ -19,6 +19,7 @@ import com.intellij.codeInspection.LocalInspectionToolSession;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.jetbrains.python.PyPsiBundle;
|
||||
import com.jetbrains.python.inspections.quickfix.ListCreationQuickFix;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -57,7 +58,7 @@ public class PyListCreationInspection extends PyInspection {
|
||||
|
||||
ListCreationQuickFix quickFix = null;
|
||||
|
||||
final String message = "This list creation could be rewritten as a list literal";
|
||||
final String message = PyPsiBundle.message("INSP.list.creation.this.list.creation.could.be.rewritten.as.list.literal");
|
||||
while (expressionStatement instanceof PyExpressionStatement) {
|
||||
final PyExpression statement = ((PyExpressionStatement)expressionStatement).getExpression();
|
||||
if (!(statement instanceof PyCallExpression)) break;
|
||||
|
||||
+5
-4
@@ -17,6 +17,7 @@ package com.jetbrains.python.inspections;
|
||||
|
||||
import com.intellij.codeInspection.LocalInspectionToolSession;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.openapi.util.NlsSafe;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.jetbrains.python.PyPsiBundle;
|
||||
@@ -72,7 +73,7 @@ public class PyMandatoryEncodingInspection extends PyInspection {
|
||||
}
|
||||
}
|
||||
|
||||
public String myDefaultEncoding = "utf-8";
|
||||
public @NlsSafe String myDefaultEncoding = "utf-8";
|
||||
public int myEncodingFormatIndex = 0;
|
||||
public boolean myAllPythons = false;
|
||||
|
||||
@@ -121,7 +122,7 @@ public class PyMandatoryEncodingInspection extends PyInspection {
|
||||
private JPanel onlyPython2Box() {
|
||||
final JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
|
||||
JCheckBox checkBox =
|
||||
PythonUiService.getInstance().createInspectionCheckBox(PyPsiBundle.message("enable.in.python.3"), this, "myAllPythons");
|
||||
PythonUiService.getInstance().createInspectionCheckBox(PyPsiBundle.message("INSP.mandatory.encoding.checkbox.enable.in.python.3"), this, "myAllPythons");
|
||||
if (checkBox != null) {
|
||||
panel.add(checkBox);
|
||||
}
|
||||
@@ -131,7 +132,7 @@ public class PyMandatoryEncodingInspection extends PyInspection {
|
||||
@NotNull
|
||||
private static JPanel defaultEncodingLabel() {
|
||||
final JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
|
||||
panel.add(new JLabel(PyPsiBundle.message("INSP.mandatory.encoding.select.default.encoding")));
|
||||
panel.add(new JLabel(PyPsiBundle.message("INSP.mandatory.encoding.label.select.default.encoding")));
|
||||
return panel;
|
||||
}
|
||||
|
||||
@@ -154,7 +155,7 @@ public class PyMandatoryEncodingInspection extends PyInspection {
|
||||
@NotNull
|
||||
private static JPanel encodingFormatLabel() {
|
||||
final JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
|
||||
panel.add(new JLabel(PyPsiBundle.message("INSP.mandatory.encoding.encoding.comment.format")));
|
||||
panel.add(new JLabel(PyPsiBundle.message("INSP.mandatory.encoding.label.encoding.comment.format")));
|
||||
return panel;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -43,7 +43,7 @@ public class PyMissingTypeHintsInspection extends PyInspection {
|
||||
ASTNode nameNode = function.getNameNode();
|
||||
if (nameNode != null) {
|
||||
registerProblem(nameNode.getPsi(),
|
||||
"Type hinting is missing for function definition",
|
||||
PyPsiBundle.message("INSP.missing.type.hints.type.hinting.missing.for.function.definition"),
|
||||
new AddTypeHintsQuickFix(function.getName()));
|
||||
}
|
||||
}
|
||||
@@ -92,7 +92,7 @@ public class PyMissingTypeHintsInspection extends PyInspection {
|
||||
@Override
|
||||
public JComponent createOptionsPanel() {
|
||||
return PythonUiService.getInstance().createSingleCheckboxOptionsPanel(
|
||||
PyPsiBundle.message("INSP.missing.type.hints.only.when.types.are.known.collected.from.run.time.or.inferred"),
|
||||
PyPsiBundle.message("INSP.missing.type.hints.checkbox.only.when.types.are.known"),
|
||||
this, "m_onlyWhenTypesAreKnown");
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -21,6 +21,7 @@ import com.intellij.psi.PsiComment;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.jetbrains.python.PyPsiBundle;
|
||||
import com.jetbrains.python.PythonFileType;
|
||||
import com.jetbrains.python.PythonUiService;
|
||||
import com.jetbrains.python.inspections.quickfix.AddEncodingQuickFix;
|
||||
@@ -79,7 +80,7 @@ public class PyNonAsciiCharInspection extends PyInspection {
|
||||
|
||||
if (hasNonAscii) {
|
||||
if (charsetString == null) {
|
||||
registerProblem(node, "Non-ASCII character " + c + " in file, but no encoding declared",
|
||||
registerProblem(node, PyPsiBundle.message("INSP.non.ascii.char.non.ascii.character.in.file.but.no.encoding.declared", c),
|
||||
new AddEncodingQuickFix(myDefaultEncoding, myEncodingFormatIndex));
|
||||
}
|
||||
}
|
||||
|
||||
+19
-13
@@ -6,6 +6,7 @@ import com.intellij.codeInspection.ProblemsHolder
|
||||
import com.intellij.psi.PsiElementVisitor
|
||||
import com.intellij.util.Processor
|
||||
import com.intellij.util.containers.SortedList
|
||||
import com.jetbrains.python.PyPsiBundle
|
||||
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner
|
||||
import com.jetbrains.python.psi.PyClass
|
||||
import com.jetbrains.python.psi.PyFile
|
||||
@@ -59,33 +60,38 @@ class PyOverloadsInspection : PyInspection() {
|
||||
functions
|
||||
.maxBy { it.textOffset }
|
||||
?.let {
|
||||
registerProblem(it.nameIdentifier,
|
||||
"A series of @overload-decorated ${chooseBetweenFunctionsAndMethods(owner)} " +
|
||||
"should always be followed by an implementation that is not @overload-ed")
|
||||
registerProblem(it.nameIdentifier, if (owner is PyClass) {
|
||||
PyPsiBundle.message("INSP.overloads.series.overload.decorated.methods.should.always.be.followed.by.implementation")
|
||||
}
|
||||
else {
|
||||
PyPsiBundle.message("INSP.overloads.series.overload.decorated.functions.should.always.be.followed.by.implementation")
|
||||
})
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (implementation != functions.last()) {
|
||||
registerProblem(functions.last().nameIdentifier,
|
||||
"A series of @overload-decorated ${chooseBetweenFunctionsAndMethods(owner)} " +
|
||||
"should always be followed by an implementation that is not @overload-ed")
|
||||
registerProblem(functions.last().nameIdentifier, if (owner is PyClass) {
|
||||
PyPsiBundle.message("INSP.overloads.series.overload.decorated.methods.should.always.be.followed.by.implementation")
|
||||
}
|
||||
else {
|
||||
PyPsiBundle.message("INSP.overloads.series.overload.decorated.functions.should.always.be.followed.by.implementation")
|
||||
})
|
||||
}
|
||||
|
||||
functions
|
||||
.asSequence()
|
||||
.filter { isIncompatibleOverload(implementation, it) }
|
||||
.forEach {
|
||||
registerProblem(it.nameIdentifier,
|
||||
"Signature of this @overload-decorated ${chooseBetweenFunctionAndMethod(owner)} " +
|
||||
"is not compatible with the implementation")
|
||||
registerProblem(it.nameIdentifier, if (owner is PyClass) {
|
||||
PyPsiBundle.message("INSP.overloads.this.method.overload.signature.not.compatible.with.implementation")
|
||||
}
|
||||
else {
|
||||
PyPsiBundle.message("INSP.overloads.this.function.overload.signature.not.compatible.with.implementation")
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun chooseBetweenFunctionsAndMethods(owner: ScopeOwner) = if (owner is PyClass) "methods" else "functions"
|
||||
|
||||
private fun chooseBetweenFunctionAndMethod(owner: ScopeOwner) = if (owner is PyClass) "method" else "function"
|
||||
|
||||
private fun isIncompatibleOverload(implementation: PyFunction, overload: PyFunction): Boolean {
|
||||
return implementation != overload &&
|
||||
PyiUtil.isOverload(overload, myTypeEvalContext) &&
|
||||
|
||||
+21
-23
@@ -1,7 +1,6 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.jetbrains.python.inspections;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.codeInspection.LocalInspectionToolSession;
|
||||
@@ -9,6 +8,7 @@ import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.codeInspection.ex.InspectionProfileModifiableModelKt;
|
||||
import com.intellij.codeInspection.util.InspectionMessage;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
@@ -27,7 +27,6 @@ import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.search.PySuperMethodsSearch;
|
||||
import com.jetbrains.python.psi.types.PyClassLikeType;
|
||||
import com.jetbrains.python.psi.types.TypeEvalContext;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -37,6 +36,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
@@ -49,16 +49,16 @@ public class PyPep8NamingInspection extends PyInspection {
|
||||
private static final Pattern UPPERCASE_REGEX = Pattern.compile("[_\\p{javaUpperCase}][_\\p{javaUpperCase}0-9]*");
|
||||
private static final Pattern MIXEDCASE_REGEX = Pattern.compile("_?_?[\\p{javaUpperCase}][\\p{javaLowerCase}\\p{javaUpperCase}0-9]*");
|
||||
// See error codes of the tool "pep8-naming"
|
||||
private static final Map<String, String> ERROR_CODES_DESCRIPTION = ImmutableMap.<String, String>builder()
|
||||
.put("N801", "Class names should use CamelCase convention")
|
||||
.put("N802", "Function name should be lowercase")
|
||||
.put("N803", "Argument name should be lowercase")
|
||||
.put("N806", "Variable in function should be lowercase")
|
||||
.put("N811", "Constant variable imported as non constant")
|
||||
.put("N812", "Lowercase variable imported as non lowercase")
|
||||
.put("N813", "CamelCase variable imported as lowercase")
|
||||
.put("N814", "CamelCase variable imported as constant")
|
||||
.build();
|
||||
private static final Map<String, Supplier<@InspectionMessage String>> ERROR_CODES_DESCRIPTION = Map.of(
|
||||
"N801", PyPsiBundle.messagePointer("INSP.pep8.naming.class.names.should.use.camelcase.convention"),
|
||||
"N802", PyPsiBundle.messagePointer("INSP.pep8.naming.function.name.should.be.lowercase"),
|
||||
"N803", PyPsiBundle.messagePointer("INSP.pep8.naming.argument.name.should.be.lowercase"),
|
||||
"N806", PyPsiBundle.messagePointer("INSP.pep8.naming.variable.in.function.should.be.lowercase"),
|
||||
"N811", PyPsiBundle.messagePointer("INSP.pep8.naming.constant.variable.imported.as.non.constant"),
|
||||
"N812", PyPsiBundle.messagePointer("INSP.pep8.naming.lowercase.variable.imported.as.non.lowercase"),
|
||||
"N813", PyPsiBundle.messagePointer("INSP.pep8.naming.camelcase.variable.imported.as.lowercase"),
|
||||
"N814", PyPsiBundle.messagePointer("INSP.pep8.naming.camelcase.variable.imported.as.constant")
|
||||
);
|
||||
public final List<String> ignoredErrors = new ArrayList<>();
|
||||
public boolean ignoreOverriddenFunctions = true;
|
||||
public final List<String> ignoredBaseClasses = Lists.newArrayList("unittest.TestCase", "unittest.case.TestCase");
|
||||
@@ -67,17 +67,17 @@ public class PyPep8NamingInspection extends PyInspection {
|
||||
@Override
|
||||
public JComponent createOptionsPanel() {
|
||||
final JPanel rootPanel = new JPanel(new BorderLayout());
|
||||
JCheckBox checkBox = PythonUiService.getInstance()
|
||||
.createInspectionCheckBox(PyPsiBundle.message("ignore.overridden.functions"), this, "ignoreOverriddenFunctions");
|
||||
PythonUiService uiService = PythonUiService.getInstance();
|
||||
JCheckBox checkBox = uiService.createInspectionCheckBox(PyPsiBundle.message("ignore.overridden.functions"), this, "ignoreOverriddenFunctions");
|
||||
if (checkBox != null) {
|
||||
rootPanel.add(checkBox, BorderLayout.NORTH);
|
||||
}
|
||||
|
||||
JComponent classes = PythonUiService.getInstance().createListEditForm(PyPsiBundle.message("INSP.pep8.naming.excluded.base.classes"), ignoredBaseClasses);
|
||||
JComponent errors = PythonUiService.getInstance().createListEditForm(PyPsiBundle.message("INSP.pep8.naming.ignored.errors"), ignoredErrors);
|
||||
JComponent classes = uiService.createListEditForm(PyPsiBundle.message("INSP.pep8.naming.column.name.excluded.base.classes"), ignoredBaseClasses);
|
||||
JComponent errors = uiService.createListEditForm(PyPsiBundle.message("INSP.pep8.naming.column.name.ignored.errors"), ignoredErrors);
|
||||
|
||||
if (classes != null && errors != null) {
|
||||
JComponent splitter = PythonUiService.getInstance().onePixelSplitter(false, classes, errors);
|
||||
JComponent splitter = uiService.onePixelSplitter(false, classes, errors);
|
||||
|
||||
if (splitter != null) {
|
||||
rootPanel.add(splitter, BorderLayout.CENTER);
|
||||
@@ -161,17 +161,15 @@ public class PyPep8NamingInspection extends PyInspection {
|
||||
|
||||
protected static class IgnoreErrorFix implements LocalQuickFix {
|
||||
private final String myCode;
|
||||
private static final String myText = "Ignore errors like this";
|
||||
|
||||
IgnoreErrorFix(String code) {
|
||||
myCode = code;
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return myText;
|
||||
return PyPsiBundle.message("QFIX.NAME.ignore.errors.like.this");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -233,10 +231,10 @@ public class PyPep8NamingInspection extends PyInspection {
|
||||
|
||||
protected void registerAndAddRenameAndIgnoreErrorQuickFixes(@Nullable final PsiElement node, @NotNull final String errorCode) {
|
||||
if (getHolder() != null && getHolder().isOnTheFly()) {
|
||||
registerProblem(node, ERROR_CODES_DESCRIPTION.get(errorCode), createRenameAndIngoreErrorQuickFixes(node, errorCode));
|
||||
registerProblem(node, ERROR_CODES_DESCRIPTION.get(errorCode).get(), createRenameAndIngoreErrorQuickFixes(node, errorCode));
|
||||
}
|
||||
else {
|
||||
registerProblem(node, ERROR_CODES_DESCRIPTION.get(errorCode), new IgnoreErrorFix(errorCode));
|
||||
registerProblem(node, ERROR_CODES_DESCRIPTION.get(errorCode).get(), new IgnoreErrorFix(errorCode));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,7 +255,7 @@ public class PyPep8NamingInspection extends PyInspection {
|
||||
final String errorCode = "N802";
|
||||
if (!ignoredErrors.contains(errorCode)) {
|
||||
quickFixes.add(new IgnoreErrorFix(errorCode));
|
||||
registerProblem(nameNode.getPsi(), ERROR_CODES_DESCRIPTION.get(errorCode),
|
||||
registerProblem(nameNode.getPsi(), ERROR_CODES_DESCRIPTION.get(errorCode).get(),
|
||||
quickFixes.toArray(LocalQuickFix.EMPTY_ARRAY));
|
||||
}
|
||||
}
|
||||
|
||||
+7
-31
@@ -6,6 +6,7 @@ import com.intellij.codeInsight.controlflow.ControlFlowUtil;
|
||||
import com.intellij.codeInspection.LocalInspectionToolSession;
|
||||
import com.intellij.codeInspection.ProblemHighlightType;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.codeInspection.util.InspectionMessage;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.psi.PsiElement;
|
||||
@@ -20,42 +21,17 @@ import com.jetbrains.python.PyPsiBundle;
|
||||
import com.jetbrains.python.codeInsight.controlflow.ControlFlowCache;
|
||||
import com.jetbrains.python.inspections.quickfix.PyUpdatePropertySignatureQuickFix;
|
||||
import com.jetbrains.python.inspections.quickfix.RenameParameterQuickFix;
|
||||
import com.jetbrains.python.psi.LanguageLevel;
|
||||
import com.jetbrains.python.psi.PyArgumentList;
|
||||
import com.jetbrains.python.psi.PyCallExpression;
|
||||
import com.jetbrains.python.psi.PyCallable;
|
||||
import com.jetbrains.python.psi.PyClass;
|
||||
import com.jetbrains.python.psi.PyDecorator;
|
||||
import com.jetbrains.python.psi.PyDecoratorList;
|
||||
import com.jetbrains.python.psi.PyExpression;
|
||||
import com.jetbrains.python.psi.PyFile;
|
||||
import com.jetbrains.python.psi.PyFunction;
|
||||
import com.jetbrains.python.psi.PyKnownDecoratorUtil;
|
||||
import com.jetbrains.python.psi.PyLambdaExpression;
|
||||
import com.jetbrains.python.psi.PyNoneLiteralExpression;
|
||||
import com.jetbrains.python.psi.PyParameter;
|
||||
import com.jetbrains.python.psi.PyParameterList;
|
||||
import com.jetbrains.python.psi.PyRaiseStatement;
|
||||
import com.jetbrains.python.psi.PyReferenceExpression;
|
||||
import com.jetbrains.python.psi.PyReturnStatement;
|
||||
import com.jetbrains.python.psi.PySubscriptionExpression;
|
||||
import com.jetbrains.python.psi.PyTargetExpression;
|
||||
import com.jetbrains.python.psi.PyTypedElement;
|
||||
import com.jetbrains.python.psi.PyUtil;
|
||||
import com.jetbrains.python.psi.PyYieldExpression;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyBuiltinCache;
|
||||
import com.jetbrains.python.psi.types.PyCallableParameter;
|
||||
import com.jetbrains.python.psi.types.PyClassType;
|
||||
import com.jetbrains.python.psi.types.PyNoneType;
|
||||
import com.jetbrains.python.psi.types.PyType;
|
||||
import com.jetbrains.python.psi.types.PyTypeChecker;
|
||||
import com.jetbrains.python.psi.types.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Checks that arguments to property() and @property and friends are ok.
|
||||
@@ -302,7 +278,7 @@ public class PyPropertyDefinitionInspection extends PyInspection {
|
||||
private void checkReturnValueAllowed(@NotNull PyCallable callable,
|
||||
@NotNull PsiElement beingChecked,
|
||||
boolean allowed,
|
||||
@NotNull String message) {
|
||||
@NotNull @InspectionMessage String message) {
|
||||
if (callable instanceof PyFunction) {
|
||||
final PyFunction function = (PyFunction)callable;
|
||||
|
||||
|
||||
+6
-4
@@ -6,6 +6,7 @@ import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemHighlightType;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel;
|
||||
import com.intellij.codeInspection.util.InspectionMessage;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.psi.*;
|
||||
@@ -161,9 +162,10 @@ public class PyProtectedMemberInspection extends PyInspection {
|
||||
}
|
||||
}
|
||||
final PyType type = myTypeEvalContext.getType(qualifier);
|
||||
final String bundleKey = type instanceof PyModuleType ? "INSP.protected.member.$0.access.module" : "INSP.protected.member.$0.access";
|
||||
registerProblem(node, PyPsiBundle.message(bundleKey, name), ProblemHighlightType.GENERIC_ERROR_OR_WARNING, null, quickFixes.toArray(
|
||||
LocalQuickFix.EMPTY_ARRAY));
|
||||
final @InspectionMessage String message = type instanceof PyModuleType
|
||||
? PyPsiBundle.message("INSP.protected.member.access.to.protected.member.of.module", name)
|
||||
: PyPsiBundle.message("INSP.protected.member.access.to.protected.member.of.class", name);
|
||||
registerProblem(node, message, ProblemHighlightType.GENERIC_ERROR_OR_WARNING, null, quickFixes.toArray(LocalQuickFix.EMPTY_ARRAY));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,7 +202,7 @@ public class PyProtectedMemberInspection extends PyInspection {
|
||||
)
|
||||
.forEach(
|
||||
referenceExpression -> {
|
||||
final String message = "'" + referenceExpression.getName() + "' is not declared in __all__";
|
||||
final String message = PyPsiBundle.message("INSP.protected.member.name.not.declared.in.all", referenceExpression.getName());
|
||||
registerProblem(referenceExpression, message, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
|
||||
}
|
||||
);
|
||||
|
||||
+10
-5
@@ -8,6 +8,7 @@ import com.intellij.psi.PsiElementVisitor
|
||||
import com.intellij.psi.PsiNameIdentifierOwner
|
||||
import com.intellij.util.containers.isNullOrEmpty
|
||||
import com.jetbrains.python.PyNames
|
||||
import com.jetbrains.python.PyPsiBundle
|
||||
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider
|
||||
import com.jetbrains.python.codeInsight.typing.inspectProtocolSubclass
|
||||
import com.jetbrains.python.codeInsight.typing.isProtocol
|
||||
@@ -78,7 +79,7 @@ class PyProtocolInspection : PyInspection() {
|
||||
}
|
||||
|
||||
if (!superClassTypes.all(correctBase)) {
|
||||
registerProblem(type.pyClass.nameIdentifier, "All bases of a protocol must be protocols")
|
||||
registerProblem(type.pyClass.nameIdentifier, PyPsiBundle.message("INSP.protocol.all.bases.protocol.must.be.protocols"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,7 +90,9 @@ class PyProtocolInspection : PyInspection() {
|
||||
if (base is PyReferenceExpression) {
|
||||
val qNames = PyResolveUtil.resolveImportedElementQNameLocally(base).asSequence().map { it.toString() }
|
||||
if (qNames.any { it == PyTypingTypeProvider.PROTOCOL || it == PyTypingTypeProvider.PROTOCOL_EXT }) {
|
||||
registerProblem(base, "Only @runtime_checkable protocols can be used with instance and class checks", GENERIC_ERROR)
|
||||
registerProblem(base,
|
||||
PyPsiBundle.message("INSP.protocol.only.runtime.checkable.protocols.can.be.used.with.instance.class.checks"),
|
||||
GENERIC_ERROR)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -102,7 +105,9 @@ class PyProtocolInspection : PyInspection() {
|
||||
it == TYPING_RUNTIME_CHECKABLE || it == TYPING_RUNTIME_CHECKABLE_EXT || it == TYPING_RUNTIME || it == TYPING_RUNTIME_EXT
|
||||
}
|
||||
) {
|
||||
registerProblem(base, "Only @runtime_checkable protocols can be used with instance and class checks", GENERIC_ERROR)
|
||||
registerProblem(base,
|
||||
PyPsiBundle.message("INSP.protocol.only.runtime.checkable.protocols.can.be.used.with.instance.class.checks"),
|
||||
GENERIC_ERROR)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -118,7 +123,7 @@ class PyProtocolInspection : PyInspection() {
|
||||
if (base != null) {
|
||||
val type = myTypeEvalContext.getType(base)
|
||||
if (type is PyClassLikeType && isProtocol(type, myTypeEvalContext)) {
|
||||
registerProblem(base, "NewType cannot be used with protocol classes")
|
||||
registerProblem(base, PyPsiBundle.message("INSP.protocol.newtype.cannot.be.used.with.protocol.classes"))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -138,7 +143,7 @@ class PyProtocolInspection : PyInspection() {
|
||||
.filterNot { PyTypeChecker.match(expectedMemberType, myTypeEvalContext.getType(it), myTypeEvalContext) }
|
||||
.forEach {
|
||||
val place = if (it is PsiNameIdentifierOwner) it.nameIdentifier else it
|
||||
registerProblem(place, "Type of '${it.name}' is incompatible with '${protocol.name}'")
|
||||
registerProblem(place, PyPsiBundle.message("INSP.protocol.element.type.incompatible.with.protocol", it.name, protocol.name))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-5
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.intention.LowPriorityAction;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.codeInspection.ex.InspectionProfileModifiableModelKt;
|
||||
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.PsiNameIdentifierOwner;
|
||||
@@ -61,7 +62,7 @@ public class PyShadowingBuiltinsInspection extends PyInspection {
|
||||
|
||||
@Override
|
||||
public JComponent createOptionsPanel() {
|
||||
return PythonUiService.getInstance().createListEditForm("Ignore built-ins", ignoredNames);
|
||||
return PythonUiService.getInstance().createListEditForm(PyPsiBundle.message("INSP.shadowing.builtins.column.name.ignore.built.ins"), ignoredNames);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -73,7 +74,7 @@ public class PyShadowingBuiltinsInspection extends PyInspection {
|
||||
}
|
||||
|
||||
private static final class PyIgnoreBuiltinQuickFix implements LocalQuickFix, LowPriorityAction {
|
||||
@NotNull private final String myName;
|
||||
@NotNull private final @NlsSafe String myName;
|
||||
|
||||
private PyIgnoreBuiltinQuickFix(@NotNull String name) {
|
||||
myName = name;
|
||||
@@ -82,7 +83,7 @@ public class PyShadowingBuiltinsInspection extends PyInspection {
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return getFamilyName() + " \"" + myName + "\"";
|
||||
return PyPsiBundle.message("QFIX.NAME.ignore.shadowed.built.in.name", myName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -93,7 +94,7 @@ public class PyShadowingBuiltinsInspection extends PyInspection {
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return PyPsiBundle.message("INSP.shadowing.builtins.ignore.shadowed.built.in.name");
|
||||
return PyPsiBundle.message("QFIX.FAMILY.NAME.ignore.shadowed.built.in.name");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -155,7 +156,7 @@ public class PyShadowingBuiltinsInspection extends PyInspection {
|
||||
if (builtin != null && !PyUtil.inSameFile(builtin, element)) {
|
||||
final PsiElement identifier = element.getNameIdentifier();
|
||||
final PsiElement problemElement = identifier != null ? identifier : element;
|
||||
registerProblem(problemElement, String.format("Shadows built-in name '%s'", name),
|
||||
registerProblem(problemElement, PyPsiBundle.message("INSP.shadowing.builtins.shadows.built.in.name", name),
|
||||
ProblemHighlightType.WEAK_WARNING, null, createQuickFixes(name, problemElement));
|
||||
}
|
||||
}
|
||||
|
||||
+6
-3
@@ -76,10 +76,11 @@ public class PyStatementEffectInspection extends PyInspection {
|
||||
}
|
||||
}
|
||||
if (expression instanceof PyReferenceExpression && !((PyReferenceExpression)expression).isQualified()) {
|
||||
registerProblem(expression, PyPsiBundle.message("INSP.NAME.statement.message"));
|
||||
registerProblem(expression, PyPsiBundle.message("INSP.statement.effect.statement.seems.to.have.no.effect"));
|
||||
}
|
||||
else {
|
||||
registerProblem(expression, PyPsiBundle.message("INSP.NAME.statement.message"), new StatementEffectIntroduceVariableQuickFix());
|
||||
registerProblem(expression, PyPsiBundle.message("INSP.statement.effect.statement.seems.to.have.no.effect"),
|
||||
new StatementEffectIntroduceVariableQuickFix());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +139,9 @@ public class PyStatementEffectInspection extends PyInspection {
|
||||
ResolveResult[] results = referenceExpression.getReference(getResolveContext()).multiResolve(true);
|
||||
for (ResolveResult res : results) {
|
||||
if (res.getElement() instanceof PyFunction) {
|
||||
registerProblem(expression, "Statement seems to have no effect and can be replaced with function call to have effect", new StatementEffectFunctionCallQuickFix());
|
||||
registerProblem(expression,
|
||||
PyPsiBundle.message("INSP.statement.effect.statement.having.no.effect.can.be.replaced.with.function.call"),
|
||||
new StatementEffectFunctionCallQuickFix());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+12
-9
@@ -5,6 +5,7 @@ import com.google.common.collect.ImmutableMap;
|
||||
import com.intellij.codeInspection.LocalInspectionToolSession;
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.codeInspection.util.InspectionMessage;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
@@ -298,7 +299,7 @@ public class PyStringFormatInspection extends PyInspection {
|
||||
if (!myUsedMappingKeys.get(key).booleanValue()) {
|
||||
unresolved++;
|
||||
if (unresolved > referenceKeyNumber) {
|
||||
registerProblem(problemTarget, PyPsiBundle.message("INSP.key.$0.has.no.arg", key));
|
||||
registerProblem(problemTarget, PyPsiBundle.message("INSP.str.format.key.has.no.argument", key));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -316,12 +317,14 @@ public class PyStringFormatInspection extends PyInspection {
|
||||
}
|
||||
}
|
||||
|
||||
private void registerProblem(@NotNull PsiElement problemTarget, @NotNull final String message, @NotNull LocalQuickFix quickFix) {
|
||||
private void registerProblem(@NotNull PsiElement problemTarget,
|
||||
@NotNull @InspectionMessage String message,
|
||||
@NotNull LocalQuickFix quickFix) {
|
||||
myProblemRegister = true;
|
||||
myVisitor.registerProblem(problemTarget, message, quickFix);
|
||||
}
|
||||
|
||||
private void registerProblem(@NotNull PsiElement problemTarget, @NotNull final String message) {
|
||||
private void registerProblem(@NotNull PsiElement problemTarget, @NotNull @InspectionMessage String message) {
|
||||
myProblemRegister = true;
|
||||
myVisitor.registerProblem(problemTarget, message);
|
||||
}
|
||||
@@ -343,7 +346,7 @@ public class PyStringFormatInspection extends PyInspection {
|
||||
return;
|
||||
}
|
||||
if (actual != null && !PyTypeChecker.match(expected, actual, myTypeEvalContext)) {
|
||||
registerProblem(problemTarget, PyPsiBundle.message("INSP.unexpected.type.$0", actual.getName()));
|
||||
registerProblem(problemTarget, PyPsiBundle.message("INSP.str.format.unexpected.argument.type", actual.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -381,7 +384,7 @@ public class PyStringFormatInspection extends PyInspection {
|
||||
if (conversionType == 'b') {
|
||||
final LanguageLevel languageLevel = LanguageLevel.forElement(formatExpression);
|
||||
if (languageLevel.isOlderThan(LanguageLevel.PYTHON35) || !isBytesLiteral(formatExpression, myTypeEvalContext)) {
|
||||
registerProblem(formatExpression, "Unsupported format character 'b'");
|
||||
registerProblem(formatExpression, PyPsiBundle.message("INSP.str.format.unsupported.format.character.b"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -408,7 +411,7 @@ public class PyStringFormatInspection extends PyInspection {
|
||||
if ("*".equals(width)) {
|
||||
++myExpectedArguments;
|
||||
if (myUsedMappingKeys.size() > 0) {
|
||||
registerProblem(formatExpression, "Can't use '*' in formats when using a mapping");
|
||||
registerProblem(formatExpression, PyPsiBundle.message("INSP.str.format.can.not.use.star.in.formats.when.using.mapping"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -559,7 +562,7 @@ public class PyStringFormatInspection extends PyInspection {
|
||||
if (chunkMapping != null) {
|
||||
registerProblem(myFormatExpression, hasElementIndex ?
|
||||
PyPsiBundle.message("INSP.too.few.args.for.fmt.string") :
|
||||
PyPsiBundle.message("INSP.key.$0.has.no.arg", chunkMapping));
|
||||
PyPsiBundle.message("INSP.str.format.key.has.no.argument", chunkMapping));
|
||||
}
|
||||
else {
|
||||
registerProblem(myFormatExpression, PyPsiBundle.message("INSP.too.few.args.for.fmt.string"));
|
||||
@@ -570,7 +573,7 @@ public class PyStringFormatInspection extends PyInspection {
|
||||
}
|
||||
}
|
||||
|
||||
private void registerProblem(@NotNull PsiElement problemTarget, @NotNull final String message) {
|
||||
private void registerProblem(@NotNull PsiElement problemTarget, @NotNull @InspectionMessage String message) {
|
||||
myProblemRegister = true;
|
||||
myVisitor.registerProblem(problemTarget, message);
|
||||
}
|
||||
@@ -585,7 +588,7 @@ public class PyStringFormatInspection extends PyInspection {
|
||||
if (expected != null && actual != null
|
||||
&& CHECKED_TYPES.contains(actual.getName())
|
||||
&& !PyTypeChecker.match(expected, actual, myTypeEvalContext)) {
|
||||
registerProblem(typedElement, PyPsiBundle.message("INSP.unexpected.type.$0", actual.getName()));
|
||||
registerProblem(typedElement, PyPsiBundle.message("INSP.str.format.unexpected.argument.type", actual.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-3
@@ -19,6 +19,7 @@ import com.intellij.codeInspection.LocalInspectionToolSession;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.jetbrains.python.PyPsiBundle;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import com.jetbrains.python.psi.types.PyNoneType;
|
||||
@@ -59,7 +60,8 @@ public class PyTupleAssignmentBalanceInspection extends PyInspection {
|
||||
|
||||
final int starExpressions = countStarExpressions(targets);
|
||||
if (starExpressions > 1) {
|
||||
registerProblem(lhsExpression, "Only one starred expression allowed in assignment");
|
||||
registerProblem(lhsExpression,
|
||||
PyPsiBundle.message("INSP.tuple.assignment.balance.only.one.starred.expression.allowed.in.assignment"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -67,10 +69,10 @@ public class PyTupleAssignmentBalanceInspection extends PyInspection {
|
||||
if (valuesLength == -1) return;
|
||||
|
||||
if (targetsLength > valuesLength + starExpressions) {
|
||||
registerProblem(assignedValue, "Need more values to unpack");
|
||||
registerProblem(assignedValue, PyPsiBundle.message("INSP.tuple.assignment.balance.need.more.values.to.unpack"));
|
||||
}
|
||||
else if (starExpressions == 0 && targetsLength < valuesLength) {
|
||||
registerProblem(assignedValue, "Too many values to unpack");
|
||||
registerProblem(assignedValue, PyPsiBundle.message("INSP.tuple.assignment.balance.too.many.values.to.unpack"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -153,7 +153,7 @@ public final class PythonUiServiceImpl extends PythonUiService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent createSingleCheckboxOptionsPanel(String label, InspectionProfileEntry inspection, String property) {
|
||||
public JComponent createSingleCheckboxOptionsPanel(@NlsContexts.Checkbox String label, InspectionProfileEntry inspection, String property) {
|
||||
return new SingleCheckboxOptionsPanel(label, inspection, property);
|
||||
}
|
||||
|
||||
@@ -228,7 +228,7 @@ public final class PythonUiServiceImpl extends PythonUiService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public JCheckBox createInspectionCheckBox(String message, InspectionProfileEntry inspection, String property) {
|
||||
public JCheckBox createInspectionCheckBox(@NlsContexts.Checkbox String message, InspectionProfileEntry inspection, String property) {
|
||||
return new CheckBox(message, inspection, property);
|
||||
}
|
||||
|
||||
@@ -243,7 +243,7 @@ public final class PythonUiServiceImpl extends PythonUiService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent createListEditForm(String title, List<String> stringList) {
|
||||
public JComponent createListEditForm(@NlsContexts.ColumnName String title, List<String> stringList) {
|
||||
final ListEditForm form = new ListEditForm(title, stringList);
|
||||
return form.getContentPanel();
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.intellij.codeInspection.LocalInspectionToolSession;
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.codeInspection.util.InspectionMessage;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.module.ModuleUtilCore;
|
||||
@@ -19,6 +20,7 @@ import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService;
|
||||
import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel;
|
||||
import com.intellij.openapi.util.NlsSafe;
|
||||
import com.intellij.openapi.util.UserDataHolderBase;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
@@ -75,7 +77,6 @@ public final class PyInterpreterInspection extends PyInspection {
|
||||
|
||||
final boolean pyCharm = PythonIdeLanguageCustomization.isMainlyPythonIde();
|
||||
|
||||
final String interpreterOwner = pyCharm ? "project" : "module";
|
||||
final List<LocalQuickFix> fixes = new ArrayList<>();
|
||||
// TODO: Introduce an inspection extension
|
||||
if (UsePipEnvQuickFix.Companion.isApplicable(module)) {
|
||||
@@ -94,33 +95,62 @@ public final class PyInterpreterInspection extends PyInspection {
|
||||
fixes.add(new InterpreterSettingsQuickFix(module));
|
||||
}
|
||||
|
||||
final String product = pyCharm ? "PyCharm" : "Python plugin";
|
||||
|
||||
if (sdk == null) {
|
||||
registerProblem(node, PyPsiBundle.message("python.sdk.no.interpreter.configured.owner", interpreterOwner), fixes.toArray(LocalQuickFix.EMPTY_ARRAY));
|
||||
final @InspectionMessage String message;
|
||||
if (pyCharm) {
|
||||
message = PyPsiBundle.message("INSP.interpreter.no.python.interpreter.configured.for.project");
|
||||
}
|
||||
else {
|
||||
message = PyPsiBundle.message("INSP.interpreter.no.python.interpreter.configured.for.module");
|
||||
}
|
||||
registerProblem(node, message, fixes.toArray(LocalQuickFix.EMPTY_ARRAY));
|
||||
}
|
||||
else {
|
||||
// TODO: Introduce an inspection extension
|
||||
final String associatedModulePath = PySdkExtKt.getAssociatedModulePath(sdk);
|
||||
final @NlsSafe String associatedModulePath = PySdkExtKt.getAssociatedModulePath(sdk);
|
||||
if (PipenvKt.isPipEnv(sdk) && (associatedModulePath == null || PySdkExtKt.isAssociatedWithAnotherModule(sdk, module))) {
|
||||
final String message = associatedModulePath != null ?
|
||||
"Pipenv interpreter is associated with another " + interpreterOwner + ": '" + associatedModulePath + "'" :
|
||||
"Pipenv interpreter is not associated with any " + interpreterOwner;
|
||||
final @InspectionMessage String message;
|
||||
if (associatedModulePath != null) {
|
||||
if (pyCharm) {
|
||||
message = PyPsiBundle.message("INSP.interpreter.pipenv.interpreter.associated.with.another.project", associatedModulePath);
|
||||
}
|
||||
else {
|
||||
message = PyPsiBundle.message("INSP.interpreter.pipenv.interpreter.associated.with.another.module", associatedModulePath);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (pyCharm) {
|
||||
message = PyPsiBundle.message("INSP.interpreter.pipenv.interpreter.not.associated.with.any.project");
|
||||
}
|
||||
else {
|
||||
message = PyPsiBundle.message("INSP.interpreter.pipenv.interpreter.not.associated.with.any.module");
|
||||
}
|
||||
}
|
||||
registerProblem(node, message, fixes.toArray(LocalQuickFix.EMPTY_ARRAY));
|
||||
}
|
||||
else if (PythonSdkUtil.isInvalid(sdk)) {
|
||||
registerProblem(node,
|
||||
"Invalid Python interpreter selected for the " + interpreterOwner,
|
||||
fixes.toArray(LocalQuickFix.EMPTY_ARRAY));
|
||||
final @InspectionMessage String message;
|
||||
if (pyCharm) {
|
||||
message = PyPsiBundle.message("INSP.interpreter.invalid.python.interpreter.selected.for.project");
|
||||
}
|
||||
else {
|
||||
message = PyPsiBundle.message("INSP.interpreter.invalid.python.interpreter.selected.for.module");
|
||||
}
|
||||
registerProblem(node, message, fixes.toArray(LocalQuickFix.EMPTY_ARRAY));
|
||||
}
|
||||
else {
|
||||
final LanguageLevel languageLevel = PythonSdkType.getLanguageLevelForSdk(sdk);
|
||||
if (!LanguageLevel.SUPPORTED_LEVELS.contains(languageLevel)) {
|
||||
registerProblem(
|
||||
node,
|
||||
"Python " + languageLevel + " has reached its end-of-life date and it is no longer supported in " + product + ".",
|
||||
fixes.toArray(LocalQuickFix.EMPTY_ARRAY)
|
||||
);
|
||||
final @InspectionMessage String message;
|
||||
if (pyCharm) {
|
||||
message = PyPsiBundle.message("INSP.interpreter.python.has.reached.its.end.of.life.and.is.no.longer.supported.in.pycharm",
|
||||
languageLevel);
|
||||
}
|
||||
else {
|
||||
message = PyPsiBundle.message("INSP.interpreter.python.has.reached.its.end.life.and.is.no.longer.supported.in.python.plugin",
|
||||
languageLevel);
|
||||
}
|
||||
registerProblem(node, message, fixes.toArray(LocalQuickFix.EMPTY_ARRAY));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import com.intellij.codeInspection.*;
|
||||
import com.intellij.codeInspection.ex.EditInspectionToolsSettingsAction;
|
||||
import com.intellij.codeInspection.ex.InspectionProfileImpl;
|
||||
import com.intellij.codeInspection.ui.ListEditForm;
|
||||
import com.intellij.codeInspection.util.InspectionMessage;
|
||||
import com.intellij.codeInspection.util.IntentionFamilyName;
|
||||
import com.intellij.core.CoreBundle;
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.idea.ActionsBundle;
|
||||
@@ -18,6 +20,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.JDOMExternalizableStringList;
|
||||
import com.intellij.openapi.util.NlsSafe;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -60,7 +63,7 @@ public class PyPackageRequirementsInspection extends PyInspection {
|
||||
|
||||
@Override
|
||||
public JComponent createOptionsPanel() {
|
||||
final ListEditForm form = new ListEditForm("Ignore packages", ignoredPackages);
|
||||
final ListEditForm form = new ListEditForm(PyPsiBundle.message("INSP.requirements.column.name.ignore.packages"), ignoredPackages);
|
||||
return form.getContentPanel();
|
||||
}
|
||||
|
||||
@@ -122,11 +125,9 @@ public class PyPackageRequirementsInspection extends PyInspection {
|
||||
if (sdk != null) {
|
||||
final List<PyRequirement> unsatisfied = findUnsatisfiedRequirements(module, sdk, myIgnoredPackages);
|
||||
if (unsatisfied != null && !unsatisfied.isEmpty()) {
|
||||
final boolean plural = unsatisfied.size() > 1;
|
||||
String msg = String.format("Package requirement%s %s %s not satisfied",
|
||||
plural ? "s" : "",
|
||||
PyPackageUtil.requirementsToString(unsatisfied),
|
||||
plural ? "are" : "is");
|
||||
@NlsSafe String requirementsList = PyPackageUtil.requirementsToString(unsatisfied);
|
||||
@InspectionMessage String msg = PyPsiBundle.message("INSP.requirements.package.requirements.not.satisfied",
|
||||
requirementsList, unsatisfied.size());
|
||||
final List<LocalQuickFix> quickFixes = new ArrayList<>();
|
||||
// TODO: Introduce an inspection extension
|
||||
if (PipenvKt.isPipEnv(sdk)) {
|
||||
@@ -235,7 +236,7 @@ public class PyPackageRequirementsInspection extends PyInspection {
|
||||
new IgnoreRequirementFix(Collections.singleton(packageName))};
|
||||
|
||||
registerProblem(packageReferenceExpression,
|
||||
String.format("Package containing module '%s' is not listed in project requirements", packageName),
|
||||
PyPsiBundle.message("INSP.requirements.package.containing.module.not.listed.in.project.requirements", packageName),
|
||||
ProblemHighlightType.WEAK_WARNING,
|
||||
null,
|
||||
fixes);
|
||||
@@ -372,27 +373,26 @@ public class PyPackageRequirementsInspection extends PyInspection {
|
||||
}
|
||||
|
||||
public static class PyInstallRequirementsFix implements LocalQuickFix {
|
||||
@NotNull private final String myName;
|
||||
@NotNull private final @IntentionFamilyName String myName;
|
||||
@NotNull private final Module myModule;
|
||||
@NotNull private final Sdk mySdk;
|
||||
@NotNull private final List<PyRequirement> myUnsatisfied;
|
||||
@NotNull private final List<String> myExtraArgs;
|
||||
@Nullable private final PyPackageManagerUI.Listener myListener;
|
||||
|
||||
public PyInstallRequirementsFix(@Nullable @Nls(capitalization = Nls.Capitalization.Sentence) String name,
|
||||
public PyInstallRequirementsFix(@Nullable @IntentionFamilyName String name,
|
||||
@NotNull Module module, @NotNull Sdk sdk,
|
||||
@NotNull List<PyRequirement> unsatisfied) {
|
||||
this(name, module, sdk, unsatisfied, Collections.emptyList(), null);
|
||||
}
|
||||
|
||||
public PyInstallRequirementsFix(@Nullable @Nls(capitalization = Nls.Capitalization.Sentence) String name,
|
||||
public PyInstallRequirementsFix(@Nullable @IntentionFamilyName String name,
|
||||
@NotNull Module module,
|
||||
@NotNull Sdk sdk,
|
||||
@NotNull List<PyRequirement> unsatisfied,
|
||||
@NotNull List<String> extraArgs,
|
||||
@Nullable PyPackageManagerUI.Listener listener) {
|
||||
final boolean plural = unsatisfied.size() > 1;
|
||||
myName = name != null ? name : String.format("Install requirement%s", plural ? "s" : "");
|
||||
myName = name != null ? name : PyPsiBundle.message("QFIX.NAME.install.requirements", unsatisfied.size());
|
||||
myModule = module;
|
||||
mySdk = sdk;
|
||||
myUnsatisfied = unsatisfied;
|
||||
@@ -604,8 +604,7 @@ public class PyPackageRequirementsInspection extends PyInspection {
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
final boolean plural = myPackageNames.size() > 1;
|
||||
return String.format("Ignore requirement%s", plural ? "s" : "");
|
||||
return PyPsiBundle.message("QFIX.NAME.ignore.requirements", myPackageNames.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<weak_warning descr="Missing docstring"></weak_warning><warning descr="No encoding specified for file"></warning>def <weak_warning descr="Missing docstring">f</weak_warning>(x):
|
||||
<warning descr="Non-ASCII character М in file, but no encoding declared"># type: (b'Моноцикл') -> None</warning>
|
||||
<warning descr="Non-ASCII character 'М' in file, but no encoding declared"># type: (b'Моноцикл') -> None</warning>
|
||||
pass
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
g = 2
|
||||
i = 2
|
||||
<warning descr="Non-ASCII character ɡ in file, but no encoding declared">ɡ</warning> = 1
|
||||
<warning descr="Non-ASCII character 'ɡ' in file, but no encoding declared">ɡ</warning> = 1
|
||||
a = g + i
|
||||
|
||||
Reference in New Issue
Block a user