Improve processing __slots__ in PyUnresolvedReferencesInspection (PY-29229)

Fix false positive when accessed attribute is declared in ancestor `__slots__`
This commit is contained in:
Semyon Proshev
2018-05-29 17:24:36 +03:00
parent 957780c235
commit ae91878f13
9 changed files with 132 additions and 73 deletions
@@ -0,0 +1,34 @@
def access1():
class B(object):
__slots__ = ['foo']
b = B()
print(b.<warning descr="Unresolved attribute reference 'baz' for class 'B'">baz</warning>)
print(b.foo)
def assign1():
class B(object):
__slots__ = ['foo']
b = B()
b.<warning descr="'B' object has no attribute 'bar'">bar</warning> = 1
b.foo = 1
def access2():
class A:
__slots__ = ['foo']
a = A()
print(a.<warning descr="Unresolved attribute reference 'foo' for class 'A'">foo</warning>)
print(a.<warning descr="Unresolved attribute reference 'bar' for class 'A'">bar</warning>)
def assign2():
class A:
__slots__ = ['foo']
a = A()
a.foo = 1
a.bar = 1
@@ -0,0 +1,48 @@
def access1():
class B(object):
__slots__ = ['foo']
class C(B):
pass
c = C()
print(c.<warning descr="Unresolved attribute reference 'bar' for class 'C'">bar</warning>)
print(c.foo)
def assign1():
class B(object):
__slots__ = ['foo']
class C(B):
pass
c = C()
c.bar = 1
c.foo = 1
def access2():
class A(object):
__slots__ = ['foo']
class D(A):
__slots__ = ['bar']
d = D()
print(d.foo)
print(d.bar)
print(d.<warning descr="Unresolved attribute reference 'baz' for class 'D'">baz</warning>)
def assign2():
class A(object):
__slots__ = ['foo']
class D(A):
__slots__ = ['bar']
d = D()
d.foo = 1
d.bar = 1
d.<warning descr="'D' object has no attribute 'baz'">baz</warning> = 1
@@ -1,5 +0,0 @@
class C(object):
__slots__ = ['foo']
c = C()
c.foo
@@ -1,15 +0,0 @@
class A(object):
__slots__ = ['a', 'b']
def __init__(self):
self.a = None # <- all ok here
self.b = None # <- all ok here
class C(A):
__slots__ = ['c', 'd']
def __init__(self, c):
super(C, self).__init__()
self.c = c
self.d = self.b
if self.c:
self.a = 10
@@ -1,8 +0,0 @@
class B(object):
__slots__ = ['foo']
class C(B):
pass
c = C()
c.bar = 1
@@ -2,4 +2,5 @@ class C(object):
__slots__ = ['__local', '__name__', '__dict__']
a = C()
print(a.<warning descr="Unresolved attribute reference 'bar' for class 'C'">bar</warning>)
a.foo = 1 #pass