mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Highlight init-only fields when __post_init__ is not declared (PY-27398)
This commit is contained in:
@@ -8,6 +8,7 @@ import com.intellij.codeInspection.ProblemHighlightType
|
||||
import com.intellij.codeInspection.ProblemsHolder
|
||||
import com.intellij.psi.PsiElementVisitor
|
||||
import com.jetbrains.python.codeInsight.stdlib.DATACLASSES_INITVAR_TYPE
|
||||
import com.jetbrains.python.codeInsight.stdlib.DUNDER_POST_INIT
|
||||
import com.jetbrains.python.codeInsight.stdlib.parseDataclassParameters
|
||||
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider
|
||||
import com.jetbrains.python.psi.*
|
||||
@@ -52,25 +53,35 @@ class PyDataclassInspection : PyInspection() {
|
||||
}
|
||||
}
|
||||
|
||||
val hasPostInit = node.findMethodByName(DUNDER_POST_INIT, false, myTypeEvalContext) != null
|
||||
|
||||
node.processClassLevelDeclarations { element, _ ->
|
||||
if (element is PyTargetExpression && element.annotationValue != null) {
|
||||
val annotation = element.annotation
|
||||
|
||||
if (annotation != null && !PyTypingTypeProvider.isClassVarAnnotation(annotation, myTypeEvalContext)) {
|
||||
val value = element.findAssignedValue()
|
||||
val cls = getInstancePyClass(value)
|
||||
val valueClass = getInstancePyClass(value)
|
||||
|
||||
if (cls != null) {
|
||||
if (valueClass != null) {
|
||||
val builtinCache = PyBuiltinCache.getInstance(node)
|
||||
|
||||
if (cls == builtinCache.listType?.pyClass ||
|
||||
cls == builtinCache.setType?.pyClass ||
|
||||
cls == builtinCache.tupleType?.pyClass) {
|
||||
if (valueClass == builtinCache.listType?.pyClass ||
|
||||
valueClass == builtinCache.setType?.pyClass ||
|
||||
valueClass == builtinCache.tupleType?.pyClass) {
|
||||
registerProblem(value,
|
||||
"mutable default '${cls.name}' is not allowed",
|
||||
"mutable default '${valueClass.name}' is not allowed",
|
||||
ProblemHighlightType.GENERIC_ERROR)
|
||||
}
|
||||
}
|
||||
else if (!hasPostInit) {
|
||||
val type = myTypeEvalContext.getType(element)
|
||||
if (type is PyClassType && type.classQName == DATACLASSES_INITVAR_TYPE) {
|
||||
registerProblem(element,
|
||||
"attribute '${element.name}' is useless until '${DUNDER_POST_INIT}' is declared",
|
||||
ProblemHighlightType.LIKE_UNUSED_SYMBOL)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
import dataclasses
|
||||
|
||||
@dataclasses.dataclass
|
||||
class A:
|
||||
a: int
|
||||
<warning descr="attribute 'b' is useless until '__post_init__' is declared">b</warning>: dataclasses.InitVar[str]
|
||||
@@ -56,6 +56,11 @@ public class PyDataclassInspectionTest extends PyInspectionTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
// PY-27398
|
||||
public void testUselessInitVar() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doTest() {
|
||||
runWithLanguageLevel(
|
||||
|
||||
Reference in New Issue
Block a user