diff --git a/python/src/com/jetbrains/python/inspections/PyDataclassInspection.kt b/python/src/com/jetbrains/python/inspections/PyDataclassInspection.kt
index db5d5262d88a..57eca0b4e0b4 100644
--- a/python/src/com/jetbrains/python/inspections/PyDataclassInspection.kt
+++ b/python/src/com/jetbrains/python/inspections/PyDataclassInspection.kt
@@ -9,10 +9,7 @@ import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.PsiElementVisitor
import com.intellij.util.containers.ContainerUtil
import com.jetbrains.python.PyNames
-import com.jetbrains.python.codeInsight.stdlib.DATACLASSES_INITVAR_TYPE
-import com.jetbrains.python.codeInsight.stdlib.DUNDER_POST_INIT
-import com.jetbrains.python.codeInsight.stdlib.PyDataclassParameters
-import com.jetbrains.python.codeInsight.stdlib.parseStdDataclassParameters
+import com.jetbrains.python.codeInsight.stdlib.*
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider
import com.jetbrains.python.psi.*
import com.jetbrains.python.psi.impl.PyCallExpressionHelper
@@ -167,7 +164,7 @@ class PyDataclassInspection : PyInspection() {
private fun checkMutatingFrozenAttribute(expression: PyQualifiedExpression) {
val cls = getInstancePyClass(expression.qualifier) ?: return
- if (parseStdDataclassParameters(cls, myTypeEvalContext)?.frozen == true) {
+ if (parseDataclassParameters(cls, myTypeEvalContext)?.frozen == true) {
registerProblem(expression, "'${cls.name}' object attribute '${expression.name}' is read-only", ProblemHighlightType.GENERIC_ERROR)
}
}
diff --git a/python/testData/inspections/PyDataclassInspection/mutatingFrozenAttrs.py b/python/testData/inspections/PyDataclassInspection/mutatingFrozenAttrs.py
new file mode 100644
index 000000000000..c8e54b717543
--- /dev/null
+++ b/python/testData/inspections/PyDataclassInspection/mutatingFrozenAttrs.py
@@ -0,0 +1,49 @@
+import attr
+
+
+@attr.s(auto_attribs=True)
+class B1:
+ x: int
+ y: str
+ z: float = 0.0
+
+B1.x = 5
+b1 = B1(1, "2")
+b1.x = 2
+b1.y = "3"
+b1.z = 1.0
+del b1.x
+del b1.y
+del b1.z
+
+
+@attr.s(frozen=False, auto_attribs=True)
+class B2:
+ x: int
+ y: str
+ z: float = 0.0
+
+B2.x = 5
+b2 = B2(1, "2")
+b2.x = 2
+b2.y = "3"
+b2.z = 1.0
+del b2.x
+del b2.y
+del b2.z
+
+
+@attr.s(frozen=True, auto_attribs=True)
+class B3:
+ x: int
+ y: str
+ z: float = 0.0
+
+B3.x = 5
+b3 = B3(1, "2")
+b3.x = 2
+b3.y = "3"
+b3.z = 1.0
+del b3.x
+del b3.y
+del b3.z
\ No newline at end of file
diff --git a/python/testSrc/com/jetbrains/python/inspections/PyDataclassInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyDataclassInspectionTest.java
index 4f27c688815e..60f811db6ad1 100644
--- a/python/testSrc/com/jetbrains/python/inspections/PyDataclassInspectionTest.java
+++ b/python/testSrc/com/jetbrains/python/inspections/PyDataclassInspectionTest.java
@@ -16,6 +16,11 @@ public class PyDataclassInspectionTest extends PyInspectionTestCase {
doTest();
}
+ // PY-26354
+ public void testMutatingFrozenAttrs() {
+ doTest();
+ }
+
// PY-27398
public void testOrderAndNotEq() {
doTest();