PY-30190 Report unresolved class attributes in decorated classes

Previously, unresolved class attributes were not reported for the decorated classes because of potential dynamical attributes (see PY-7173). This commit enables this warning again because false-negative unresolved reference warning is much more common and distracting than the case with dynamic attributes

Merge-request: IJ-MR-105254
Merged-by: Daniil Kalinin <Daniil.Kalinin@jetbrains.com>

GitOrigin-RevId: 67d1ab3fe1d5a140836d49f8ef6a65cf01873456
This commit is contained in:
Daniil Kalinin
2023-06-20 04:39:38 +00:00
committed by intellij-monorepo-bot
parent 4d60a1ad40
commit eb2a834e65
3 changed files with 18 additions and 4 deletions

View File

@@ -486,9 +486,6 @@ public abstract class PyUnresolvedReferencesVisitor extends PyInspectionVisitor
}
}
else {
if (PyKnownDecoratorUtil.hasUnknownDecorator(cls, myTypeEvalContext)) {
return true;
}
final String docString = cls.getDocStringValue();
if (docString != null && docString.contains("@DynamicAttrs")) {
return true;

View File

@@ -20,4 +20,4 @@ print(c.bar, c.baz, c.quux)
print(c.<warning descr="Unresolved attribute reference 'spam' for class 'C'">spam</warning>) #fail
d = D()
print(d.foo)
print(d.eggs) #pass
print(d.<warning descr="Unresolved attribute reference 'eggs' for class 'D'">eggs</warning>)

View File

@@ -861,6 +861,23 @@ public class PyUnresolvedReferencesInspectionTest extends PyInspectionTestCase {
"a.<warning descr=\"Cannot find reference 'append' in 'None'\">append</warning>(10)");
}
// PY-30190
public void testUnresolvedReferenceInDecoratedClass() {
runWithLanguageLevel(
LanguageLevel.getLatest(),
() -> doTestByText("""
def foo(cls):
return cls
@foo
class Bar2(object):
def __init__(self):
print(self.<warning descr="Unresolved attribute reference 'hello' for class 'Bar2'">hello</warning>)
""")
);
}
// PY-39682
public void testWildcardIgnorePatternReferenceForNestedBinaryModule() {
runWithAdditionalClassEntryInSdkRoots(getTestDirectoryPath() + "/site-packages", () -> {