Skip to content

Commit 0d4cb1e

Browse files
committed
Python: Add test of PoorMansFunctionResolution
1 parent 6eb4525 commit 0d4cb1e

File tree

3 files changed

+70
-0
lines changed

3 files changed

+70
-0
lines changed

python/ql/test/library-tests/frameworks/internal-ql-helpers/PoorMansFunctionResolutionTest.expected

Whitespace-only changes.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
private import python
2+
private import semmle.python.dataflow.new.DataFlow
3+
private import semmle.python.frameworks.internal.PoorMansFunctionResolution
4+
import TestUtilities.InlineExpectationsTest
5+
6+
class InlinePoorMansFunctionResolutionTest extends InlineExpectationsTest {
7+
InlinePoorMansFunctionResolutionTest() { this = "InlinePoorMansFunctionResolutionTest" }
8+
9+
override string getARelevantTag() { result = "resolved" }
10+
11+
override predicate hasActualResult(Location location, string element, string tag, string value) {
12+
exists(location.getFile().getRelativePath()) and
13+
exists(Function func, DataFlow::Node ref |
14+
ref = poorMansFunctionTracker(func) and
15+
not ref.asExpr() instanceof FunctionExpr and
16+
// exclude things like `GSSA variable func`
17+
exists(ref.asExpr()) and
18+
// exclude decorator calls (which with our extractor rewrites does reference the
19+
// function)
20+
not ref.asExpr() = func.getDefinition().(FunctionExpr).getADecoratorCall()
21+
|
22+
value = func.getName() and
23+
tag = "resolved" and
24+
element = ref.toString() and
25+
location = ref.getLocation()
26+
)
27+
}
28+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
def func():
2+
print("func")
3+
4+
func() # $ resolved=func
5+
6+
7+
class MyBase:
8+
def base_method(self):
9+
print("base_method", self)
10+
11+
12+
class MyClass(MyBase):
13+
def method1(self):
14+
print("method1", self)
15+
16+
@classmethod
17+
def cls_method(cls):
18+
print("cls_method", cls)
19+
20+
@staticmethod
21+
def static():
22+
print("static")
23+
24+
def method2(self):
25+
print("method2", self)
26+
self.method1()
27+
self.base_method()
28+
self.cls_method()
29+
self.static()
30+
31+
32+
33+
34+
MyClass.cls_method() # $ resolved=cls_method
35+
MyClass.static() # $ resolved=static
36+
37+
x = MyClass()
38+
x.base_method()
39+
x.method1()
40+
x.cls_method()
41+
x.static()
42+
x.method2()

0 commit comments

Comments
 (0)