Skip to content

Commit d1cf7f0

Browse files
tausbnNapalys
andcommitted
Python: Support type annotations in call graph
Adds support for tracking instances via type annotations. Also adds a convenience method to the newly added `Annotation` class, `getAnnotatedExpression`, that returns the expression that is annotated with the given type. For return annotations this is any value returned from the annotated function in question. Co-authored-by: Napalys Klicius <[email protected]>
1 parent 76544f2 commit d1cf7f0

File tree

2 files changed

+16
-0
lines changed

2 files changed

+16
-0
lines changed

python/ql/lib/semmle/python/Exprs.qll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,17 @@ class Annotation extends Expr {
762762
or
763763
this = any(FunctionExpr f).getReturns()
764764
}
765+
766+
/** Gets the expression that this annotation annotates. */
767+
Expr getAnnotatedExpression() {
768+
result = any(AnnAssign a | a.getAnnotation() = this).getTarget()
769+
or
770+
result = any(Parameter p | p.getAnnotation() = this)
771+
or
772+
exists(FunctionExpr f |
773+
this = f.getReturns() and result = f.getInnerScope().getReturnNode().getNode()
774+
)
775+
}
765776
}
766777

767778
/* Expression Contexts */

python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,11 @@ private module TrackClassInstanceInput implements CallGraphConstruction::Simple:
580580
class State = Class;
581581

582582
predicate start(Node start, Class cls) {
583+
exists(Annotation ann |
584+
ann = classTracker(cls).asExpr() and
585+
start.asExpr() = ann.getAnnotatedExpression()
586+
)
587+
or
583588
resolveClassCall(start.(CallCfgNode).asCfgNode(), cls)
584589
or
585590
// result of `super().__new__` as used in a `__new__` method implementation

0 commit comments

Comments
 (0)