mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-10-01 06:51:17 +07:00
Highlight removing frozen dataclass attribute (PY-28957)
This commit is contained in:
@@ -37,9 +37,18 @@ class PyDataclassInspection : PyInspection() {
|
||||
override fun visitPyTargetExpression(node: PyTargetExpression?) {
|
||||
super.visitPyTargetExpression(node)
|
||||
|
||||
val cls = getInstancePyClass(node?.qualifier) ?: return
|
||||
if (parseDataclassParameters(cls, myTypeEvalContext)?.frozen == true) {
|
||||
registerProblem(node, "'${cls.name}' object attribute '${node!!.name}' is read-only", ProblemHighlightType.GENERIC_ERROR)
|
||||
if (node != null) checkMutatingFrozenAttribute(node)
|
||||
}
|
||||
|
||||
override fun visitPyDelStatement(node: PyDelStatement?) {
|
||||
super.visitPyDelStatement(node)
|
||||
|
||||
if (node != null) {
|
||||
node
|
||||
.targets
|
||||
.asSequence()
|
||||
.filterIsInstance<PyReferenceExpression>()
|
||||
.forEach { checkMutatingFrozenAttribute(it) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,6 +167,13 @@ class PyDataclassInspection : PyInspection() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkMutatingFrozenAttribute(expression: PyQualifiedExpression) {
|
||||
val cls = getInstancePyClass(expression.qualifier) ?: return
|
||||
if (parseDataclassParameters(cls, myTypeEvalContext)?.frozen == true) {
|
||||
registerProblem(expression, "'${cls.name}' object attribute '${expression.name}' is read-only", ProblemHighlightType.GENERIC_ERROR)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getInstancePyClass(element: PyTypedElement?): PyClass? {
|
||||
val type = element?.let { myTypeEvalContext.getType(it) } as? PyClassType
|
||||
return if (type != null && !type.isDefinition) type.pyClass else null
|
||||
|
||||
+10
-1
@@ -12,6 +12,9 @@ b1 = B1(1, "2")
|
||||
b1.x = 2
|
||||
b1.y = "3"
|
||||
b1.z = 1.0
|
||||
del b1.x
|
||||
del b1.y
|
||||
del b1.z
|
||||
|
||||
|
||||
@dataclasses.dataclass(frozen=False)
|
||||
@@ -25,6 +28,9 @@ b2 = B2(1, "2")
|
||||
b2.x = 2
|
||||
b2.y = "3"
|
||||
b2.z = 1.0
|
||||
del b2.x
|
||||
del b2.y
|
||||
del b2.z
|
||||
|
||||
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
@@ -37,4 +43,7 @@ B3.x = 5
|
||||
b3 = B3(1, "2")
|
||||
<error descr="'B3' object attribute 'x' is read-only">b3.x</error> = 2
|
||||
<error descr="'B3' object attribute 'y' is read-only">b3.y</error> = "3"
|
||||
<error descr="'B3' object attribute 'z' is read-only">b3.z</error> = 1.0
|
||||
<error descr="'B3' object attribute 'z' is read-only">b3.z</error> = 1.0
|
||||
del <error descr="'B3' object attribute 'x' is read-only">b3.x</error>
|
||||
del <error descr="'B3' object attribute 'y' is read-only">b3.y</error>
|
||||
del <error descr="'B3' object attribute 'z' is read-only">b3.z</error>
|
||||
@@ -12,7 +12,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
public class PyDataclassInspectionTest extends PyInspectionTestCase {
|
||||
|
||||
// PY-27398
|
||||
public void testAssignmentsToFrozen() {
|
||||
public void testMutatingFrozen() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user