diff --git a/python/src/com/jetbrains/python/inspections/PyThirdPartyInspectionExtension.kt b/python/src/com/jetbrains/python/inspections/PyThirdPartyInspectionExtension.kt index 054b7d8a7913..56aa84981d68 100644 --- a/python/src/com/jetbrains/python/inspections/PyThirdPartyInspectionExtension.kt +++ b/python/src/com/jetbrains/python/inspections/PyThirdPartyInspectionExtension.kt @@ -2,12 +2,16 @@ package com.jetbrains.python.inspections import com.intellij.util.containers.ContainerUtil +import com.jetbrains.python.codeInsight.stdlib.PyDataclassParameters +import com.jetbrains.python.codeInsight.stdlib.parseDataclassParameters import com.jetbrains.python.psi.PyElement import com.jetbrains.python.psi.PyExpression import com.jetbrains.python.psi.PyFunction import com.jetbrains.python.psi.PyUtil import com.jetbrains.python.psi.resolve.PyResolveContext import com.jetbrains.python.psi.resolve.QualifiedNameFinder +import com.jetbrains.python.psi.types.PyClassType +import com.jetbrains.python.psi.types.PyType import com.jetbrains.python.psi.types.TypeEvalContext class PyThirdPartyInspectionExtension : PyInspectionExtension() { @@ -29,6 +33,12 @@ class PyThirdPartyInspectionExtension : PyInspectionExtension() { return false } + override fun ignoreUnresolvedMember(type: PyType, name: String, context: TypeEvalContext): Boolean { + return name == "__attrs_attrs__" && + type is PyClassType && + parseDataclassParameters(type.pyClass, context)?.type == PyDataclassParameters.Type.ATTRS + } + private fun resolvesTo(expression: PyExpression, qualifiedName: String, resolveContext: PyResolveContext): Boolean { return ContainerUtil.exists(PyUtil.multiResolveTopPriority(expression, resolveContext)) { it is PyElement && QualifiedNameFinder.getQualifiedName(it) == qualifiedName diff --git a/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java index 6240f8e2d9d5..b8170d242de0 100644 --- a/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java +++ b/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java @@ -770,6 +770,18 @@ public class PyUnresolvedReferencesInspectionTest extends PyInspectionTestCase { "print(module)"); } + // PY-29929 + public void testAttrsSpecialAttribute() { + doTestByText("import attr\n" + + "\n" + + "@attr.s\n" + + "class C:\n" + + " a = attr.ib()\n" + + "\n" + + "print(C.__attrs_attrs__)\n" + + "print(C(1).__attrs_attrs__)"); + } + // PY-32927 public void testPrefixExpressionOnClassHavingSkeletons() { doMultiFileTest();