mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Python: Add tests
Also fixes an issue with the return type annotations that caused these to not work properly. Currently, annotated assignments don't work properly, due to the fact that our flow relation doesn't consider flow going to the "type" part of an annotated assignment. This means that in `x : Foo`, we do correctly note that `x` is annotated with `Foo`, but we have no idea what `Foo` is, since it has no incoming flow. To fix this we should probably just extend the flow relation, but this may need to be done with some care, so I have left it as future work.
This commit is contained in:
@@ -769,8 +769,8 @@ class Annotation extends Expr {
|
||||
or
|
||||
result = any(Parameter p | p.getAnnotation() = this)
|
||||
or
|
||||
exists(FunctionExpr f |
|
||||
this = f.getReturns() and result = f.getInnerScope().getReturnNode().getNode()
|
||||
exists(FunctionExpr f, Return r |
|
||||
this = f.getReturns() and r.getScope() = f.getInnerScope() and result = r.getValue()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
testFailures
|
||||
debug_callableNotUnique
|
||||
pointsTo_found_typeTracker_notFound
|
||||
typeTracker_found_pointsTo_notFound
|
||||
| type_annotations.py:6:5:6:14 | ControlFlowNode for Attribute() | Foo.method |
|
||||
| type_annotations.py:16:5:16:14 | ControlFlowNode for Attribute() | Foo.method |
|
||||
@@ -0,0 +1 @@
|
||||
../CallGraph/InlineCallGraphTest.ql
|
||||
@@ -0,0 +1,33 @@
|
||||
class Foo:
|
||||
def method(self):
|
||||
pass
|
||||
|
||||
def test_parameter_annotation(x: Foo):
|
||||
x.method() #$ tt=Foo.method
|
||||
|
||||
def test_no_parameter_annotation(x):
|
||||
x.method()
|
||||
|
||||
def function_with_return_annotation() -> Foo:
|
||||
return eval("Foo()")
|
||||
|
||||
def test_return_annotation():
|
||||
x = function_with_return_annotation() #$ pt,tt=function_with_return_annotation
|
||||
x.method() #$ tt=Foo.method
|
||||
|
||||
def function_without_return_annotation():
|
||||
return eval("Foo()")
|
||||
|
||||
def test_no_return_annotation():
|
||||
x = function_without_return_annotation() #$ pt,tt=function_without_return_annotation
|
||||
x.method()
|
||||
|
||||
def test_variable_annotation():
|
||||
x = eval("Foo()")
|
||||
x : Foo
|
||||
# Currently fails because there is no flow from the class definition to the type annotation.
|
||||
x.method() #$ MISSING: tt=Foo.method
|
||||
|
||||
def test_no_variable_annotation():
|
||||
x = eval("Foo()")
|
||||
x.method()
|
||||
Reference in New Issue
Block a user