Files
2025-09-02 12:02:08 +01:00

150 lines
4.2 KiB
Python

class Base(object):
def meth1(self):
pass
def meth2(self, spam):
pass
def meth3(self):
pass
def foo(self):
self.meth1()
self.meth1(0)
self.meth2()
self.meth2(0)
self.meth1(spam="eggs")
self.meth2(spam="eggs")
class Derived(Base):
def meth1(self, spam): # $Alert[py/inheritance/signature-mismatch] # Has 1 more arg, base called in Base.foo
pass
def meth2(self): # $Alert[py/inheritance/signature-mismatch] # Has 1 fewer arg, base called in Base.foo
pass
def meth3(self, eggs): # $Alert[py/inheritance/signature-mismatch] # Has 1 more arg. Method is not called.
pass
def bar(self):
self.meth1() # Can only call Derived.meth1 so report as incorrect number of arguments
self.meth1(0)
self.meth2()
self.meth2(0) # Can only call Derived.meth2 so report as incorrect number of arguments
self.meth1(spam="eggs")
self.meth2(spam="eggs")
self.foo()
d = Derived()
d.meth1
class Abstract(object):
def meth(self):
raise NotImplementedError()
class Concrete(object):
def meth(self, arg):
pass
#Attempt to fool analysis
x = Abstract() if cond else Concrete()
x.meth("hi")
class BlameBase(object):
def meth(self):
pass
class Correct1(BlameBase):
def meth(self, arg): # $Alert[py/inheritance/signature-mismatch] # Has 1 more arg. The incorrect-overridden-method query would alert for the base method in this case.
pass
class Correct2(BlameBase):
def meth(self, arg): # $Alert[py/inheritance/signature-mismatch] # Has 1 more arg
pass
c = Correct2()
c.meth("hi")
class Base2:
def meth1(self, x=1): pass
def meth2(self, x=1): pass
def meth3(self): pass
def meth4(self, x=1): pass
def meth5(self, x, y, z, w=1): pass
def meth6(self, x, *ys): pass
def meth7(self, *ys): pass
def meth8(self, x, y): pass
def meth9(self, x, y): pass
def meth10(self, x, *, y=3): pass
def meth11(self, x, y): pass
def meth12(self, **kwargs): pass
def meth13(self, /, x): pass
def call_some(self):
self.meth1()
self.meth1(x=2)
self.meth3()
self.meth3(x=2)
self.meth6(2, 3, 4)
self.meth7()
self.meth8(1,y=3)
self.meth9(1,2)
self.meth10(1,y=3)
self.meth11(1,y=3)
self.meth12(x=2)
self.meth13(x=2)
class Derrived2(Base2):
def meth1(self): pass # $Alert[py/inheritance/signature-mismatch] # Weak mismatch (base may be called with 2 args. only alert if mismatching call exists)
def meth2(self): pass # No alert (weak mismatch, but not called)
def meth3(self, x=1): pass # No alert (no mismatch - all base calls are valid for sub)
def meth4(self, x, y, z=1): pass # $Alert[py/inheritance/signature-mismatch] # sub min > base max (strong mismatch)
def meth5(self, x, y=1): pass # $Alert[py/inheritance/signature-mismatch]
def meth6(self, x): pass # $Alert[py/inheritance/signature-mismatch] # weak mismatch (base may be called with 3+ args)
def meth7(self, x, *ys): pass # $Alert[py/inheritance/signature-mismatch] # weak mismatch (base may be called with 1 arg only)
def meth8(self, x, z): pass # $Alert[py/inheritance/signature-mismatch] # weak mismatch (base may be called with arg named y)
def meth9(self, x, z): pass # No alert (never called with wrong keyword arg)
def meth10(self, x, **kwargs): pass # No alert (y is kw-only arg in base, calls that use it are valid for sub)
def meth11(self, x, z, **kwargs): pass # $MISSING:Alert[py/inheritance/signature-mismatch] # call using y kw-arg is invalid due to not specifying z, but this is not detected. Likely a fairly niche situation.
def meth12(self): pass # $Alert[py/inheritance/signature-mismatch] # call including extra kwarg invalid
def meth13(self, /, y): pass # $Alert[py/inheritance/signature-mismatch] # weak mismatch (base may be called with arg named x), however meth13 is incorrectly detected as having 2 minimum positional arguments, whereas x is kw-only; resulting in the witness call not being detected as a valid call to Base2.meth13.