From 8d6db3fcb1281634c810ea8f4084e96b1517fa80 Mon Sep 17 00:00:00 2001 From: Semyon Proshev Date: Mon, 18 Dec 2017 16:44:01 +0300 Subject: [PATCH] Ignore classvars when inspecting fields order (PY-27398) --- .../inspections/PyDataclassInspection.kt | 2 +- .../inspections/PyNamedTupleInspection.kt | 14 +++++++---- .../PyDataclassInspection/fieldsOrder.py | 23 ++++++++++++++++++- 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/python/src/com/jetbrains/python/inspections/PyDataclassInspection.kt b/python/src/com/jetbrains/python/inspections/PyDataclassInspection.kt index 8c1fb7df01a4..dc005dfe33a0 100644 --- a/python/src/com/jetbrains/python/inspections/PyDataclassInspection.kt +++ b/python/src/com/jetbrains/python/inspections/PyDataclassInspection.kt @@ -76,7 +76,7 @@ class PyDataclassInspection : PyInspection() { true } - PyNamedTupleInspection.inspectFieldsOrder(node, this::registerProblem) + PyNamedTupleInspection.inspectFieldsOrder(node, myTypeEvalContext, this::registerProblem) } } } diff --git a/python/src/com/jetbrains/python/inspections/PyNamedTupleInspection.kt b/python/src/com/jetbrains/python/inspections/PyNamedTupleInspection.kt index 1dca5402bb83..e908965cd16f 100644 --- a/python/src/com/jetbrains/python/inspections/PyNamedTupleInspection.kt +++ b/python/src/com/jetbrains/python/inspections/PyNamedTupleInspection.kt @@ -14,13 +14,14 @@ import com.jetbrains.python.psi.LanguageLevel import com.jetbrains.python.psi.PyClass import com.jetbrains.python.psi.PyTargetExpression import com.jetbrains.python.psi.types.PyClassLikeType +import com.jetbrains.python.psi.types.TypeEvalContext import java.util.* class PyNamedTupleInspection : PyInspection() { companion object { - fun inspectFieldsOrder(cls: PyClass, callback: (PsiElement, String, ProblemHighlightType) -> Unit) { - val fieldsProcessor = FieldsProcessor() + fun inspectFieldsOrder(cls: PyClass, context: TypeEvalContext, callback: (PsiElement, String, ProblemHighlightType) -> Unit) { + val fieldsProcessor = FieldsProcessor(context) cls.processClassLevelDeclarations(fieldsProcessor) @@ -52,7 +53,7 @@ class PyNamedTupleInspection : PyInspection() { super.visitPyClass(node) if (node != null && LanguageLevel.forElement(node).isAtLeast(LanguageLevel.PYTHON36) && isTypingNTInheritor(node)) { - inspectFieldsOrder(node, this::registerProblem) + inspectFieldsOrder(node, myTypeEvalContext, this::registerProblem) } } @@ -64,7 +65,7 @@ class PyNamedTupleInspection : PyInspection() { } } - private class FieldsProcessor : PsiScopeProcessor { + private class FieldsProcessor(private val context: TypeEvalContext) : PsiScopeProcessor { val lastFieldWithoutDefaultValue: PyTargetExpression? get() = lastFieldWithoutDefaultValueBox.result @@ -80,6 +81,11 @@ class PyNamedTupleInspection : PyInspection() { override fun execute(element: PsiElement, state: ResolveState): Boolean { if (element is PyTargetExpression) { + val annotation = element.annotation + if (annotation != null && PyTypingTypeProvider.isClassVarAnnotation(annotation, context)) { + return true + } + when { element.findAssignedValue() != null -> fieldsWithDefaultValue.add(element) else -> lastFieldWithoutDefaultValueBox.apply(element) diff --git a/python/testData/inspections/PyDataclassInspection/fieldsOrder.py b/python/testData/inspections/PyDataclassInspection/fieldsOrder.py index 09edce081042..514f23bb0d65 100644 --- a/python/testData/inspections/PyDataclassInspection/fieldsOrder.py +++ b/python/testData/inspections/PyDataclassInspection/fieldsOrder.py @@ -1,4 +1,5 @@ import dataclasses +from typing import ClassVar @dataclasses.dataclass @@ -15,4 +16,24 @@ class A1: class A2: bar: int baz: str = "" - foo: int = 5 \ No newline at end of file + foo: int = 5 + + +@dataclasses.dataclass +class A3: + bar1: int + baz1: ClassVar[int] = 1 + foo1: int + bar2: ClassVar[int] = 2 + baz2: int + foo2: int = 3 + + +@dataclasses.dataclass +class A4: + bar1: int + baz1: ClassVar = 1 + foo1: int + bar2: ClassVar = 2 + baz2: int + foo2: int = 3 \ No newline at end of file