from pychecker2.TestSupport import WarningTester
from pychecker2 import ClassChecks
class ClassTestCase(WarningTester):
def testClassChecks(self):
self.silent('class A:\n'
' def f(self):\n'
' return 0\n'
'class B(A):\n'
' def g(self):\n'
' return self.f\n')
def testSignature(self):
w = ClassChecks.AttributeCheck.signatureChanged
self.silent('class Base:\n'
' def f(self): pass\n'
'class Derived(Base):\n'
' def f(self): pass\n')
self.warning('class Base:\n'
' def f(self): pass\n'
'class Derived(Base):\n'
' def f(self, x): pass\n',
4, w, 'f', 'Base')
self.silent('class Base:\n'
' def f(self, x, y, *args): pass\n'
'class Derived(Base):\n'
' def f(self, x, *args): pass\n')
self.warning('class Base:\n'
' def f(self, x, *args): pass\n'
'class Derived(Base):\n'
' def f(self, x, y, *args): pass\n',
4, w, 'f', 'Base')
self.silent('class Base:\n'
' def __private(self, x, y): pass\n'
'class Derived(Base):\n'
' def __private(self, x): pass\n')
self.warning('class Base:\n'
' def __private(self, x, y): pass\n'
'class Derived(Base):\n'
' def _Base__private(self, x): pass\n',
4, w, '__private', 'Base')
def testUnknownAttribute(self):
w = ClassChecks.AttributeCheck.unknownAttribute
self.warning('class C:\n'
' def f(self): return self.x\n', 2, w, 'C', 'x')
self.silent('class C:\n'
' def f(self): return self.x\n'
' def __init__(self, v): self.x = v\n')
self.silent('class D:\n'
' def __init__(self): self.x = 1\n'
'class C(D):\n'
' def f(self): return self.x\n')
self.silent('from pychecker2.utest.data import *\n'
'class C(Data):\n'
' def get_value2(self):\n'
' return self.get_value()\n'
'\n')
imp = '\n\nimport'
frm = '\n\nfrom'
import_abuse = [
(imp, 'pychecker2.utest.data', 'pychecker2.utest.data.Data'),
(imp, 'pychecker2.utest.data as F', 'F.Data'),
(frm, 'pychecker2.utest import data', 'data.Data'),
(frm, 'pychecker2.utest import data as F', 'F.Data'),
(frm, 'pychecker2.utest.data import Data', 'Data'),
(frm, 'pychecker2.utest.data import Data as F', 'F'),
(frm, 'pychecker2.utest.data import *', 'Data'),
('class A:\n class B:\n import pychecker2.utest.data',
'',
'A.B.pychecker2.utest.data.Data'),
('class A:\n'
' class B:\n'
' from pychecker2.utest import data as F',
'',
'A.B.F.Data')
]
for fmt in import_abuse:
self.silent('%s %s\n'
'class C(%s):\n'
' def f(self): return self.value\n' % fmt)
self.silent('%s %s\n'
'def g(v):\n'
' class C(%s):\n'
' def f(self): return self.value\n'
' return C(v)\n' % fmt)
self.warning('%s %s\n'
'class C(%s):\n'
' def f(self): self.get_value = 1\n' % fmt,
5, ClassChecks.AttributeCheck.methodRedefined,
'get_value', 'C')
self.warning('%s %s\n'
'def g(v):\n'
' class C(%s):\n'
' def f(self): self.get_value = 1\n'
' return C(v)\n' % fmt,
6, ClassChecks.AttributeCheck.methodRedefined,
'get_value', 'C')
self.warning('%s %s\n'
'class C(%s):\n'
' def get_value(self, x): pass\n' % fmt,
5, ClassChecks.AttributeCheck.signatureChanged,
'get_value', 'Data')
def testSpecial(self):
for fmt in [('__del__', 'self, args', 1),
('__cmp__', 'self', 2),
]:
self.warning('class C:\n'
' def %s(%s):\n'
' pass\n' % fmt[0:2],
2, ClassChecks.SpecialCheck.specialMethod,
fmt[0], fmt[2], fmt[2] > 1 and "s" or "")
for fmt in [('__del__', 'self'),
('__ge__', 'self, a, b = None, c = None'),
]:
self.silent('class C:\n'
' def %s(%s):\n'
' pass\n' % fmt)
self.warning('class C:\n'
' def __not_special__(self):\n'
' pass\n',
2, ClassChecks.SpecialCheck.notSpecial,
'__not_special__')
def testUncheckableAttribute(self):
# inherit from local variable
self.silent('def f(klass):\n'
' class C(klass):\n'
' def __init__(self, x):\n'
' self.foo = x\n'
' def g(self): return self.foo\n'
' return C(1)\n')
# inherit from an expression
self.silent('class A:\n'
' def __add__(self, unused):\n'
' return A\n'
'class B(A): pass\n'
'class C(A() + B()): pass\n')
# inherit from something not in a source module
self.warning('import exceptions\n'
'class C(exceptions):\n'
' def f(self):\n'
' return self.value\n',
4, ClassChecks.AttributeCheck.unknownAttribute,
'C', 'value')
self.warning('import pychecker2.utest.data\n'
'class C(pychecker2.utest.data.exceptions.AssertionError):\n'
' def f(self):\n'
' return self.value\n',
4, ClassChecks.AttributeCheck.unknownAttribute,
'C', 'value')
self.warning('from pychecker2.utest.data import Data as F\n'
'class C(F.DataError):\n'
' def f(self):\n'
' return self.value\n',
4, ClassChecks.AttributeCheck.unknownAttribute,
'C', 'value')
self.silent('def f():\n'
' class Foo(None.__class__): pass\n'
' return Foo()\n')
def testUnused(self):
self.warning('class C:\n'
' def __init__(self):\n'
' self.__x = 1\n',
3, ClassChecks.AttributeCheck.unusedAttribute, '__x', 'C')
self.warning('class C:\n'
' def __init__(self):\n'
' class D:\n'
' def __init__(self): self.__x = 1\n'
' def f(self):\n'
' return self.__x\n'
' self.__x = D()\n',
7, ClassChecks.AttributeCheck.unusedAttribute, '__x', 'C')
self.silent('class C:\n'
' def __init__(self):\n'
' self.x = 1\n')
def testInit(self):
w = ClassChecks.InitCheck.initReturnsValue
self.warning('class C:\n'
' def __init__(self):\n'
' return 1\n', 3, w)
self.warning('class C:\n'
' def __init__(self):\n'
' def f(x):\n'
' return f(x - 1)\n'
' return f(1)\n', 5, w)
w = ClassChecks.AttributeCheck.attributeInitialized
self.silent('class C:\n'
' def f(self):\n'
' self.value = 1\n'
' def __init__(self):\n'
' self.value = None\n')
self.warning('class C:\n'
' def __init__(self): pass\n'
' def f(self):\n'
' self.value = 1',
4, w, 'value')
def testRepr(self):
w = ClassChecks.ReprCheck.backquoteSelf
self.silent('class C:\n'
' def __str__(self):\n'
' return "C" + `self`\n')
self.warning('class C:\n'
' def __repr__(self):\n'
' return "C" + `self`\n', 3, w)
def testMethodRedefined(self):
w = ClassChecks.AttributeCheck.methodRedefined
self.warning('class C:\n'
' def f(self):\n'
' self.f = lambda x: x\n',
3, w, 'f', 'C')
self.warning('class B:\n'
' def g(self): pass\n'
'class C(B):\n'
' def f(self):\n'
' self.g = lambda x: x\n',
5, w, 'g', 'C')
self.warning('from pychecker2.utest.data import Data\n'
'class C(Data):\n'
' def f(self):\n'
' self.get_value = 1\n',
4, w, 'get_value','C')
|