-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathtest.py
More file actions
149 lines (92 loc) · 4.18 KB
/
test.py
File metadata and controls
149 lines (92 loc) · 4.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
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.