mirror of
https://github.com/github/codeql.git
synced 2025-12-24 12:46:34 +01:00
Python: Account for non-evaluation of annotations in cyclic imports.
Should fix #2426. Essentially, we disregard expressions used inside annotations, if these annotations occur in a file that has `from __future__ import annotations`, as this prevents the annotations from being evaluated.
This commit is contained in:
@@ -60,7 +60,8 @@ predicate import_time_module_use(ModuleValue m, ModuleValue enclosing, Expr use,
|
||||
exists(Expr mod |
|
||||
use.getEnclosingModule() = enclosing.getScope() and
|
||||
not use.getScope+() instanceof Function and
|
||||
mod.pointsTo(m)
|
||||
mod.pointsTo(m) and
|
||||
not is_annotation_with_from_future_import_annotations(use)
|
||||
|
|
||||
// either 'M.foo'
|
||||
use.(Attribute).getObject() = mod and use.(Attribute).getName() = attr
|
||||
@@ -70,6 +71,30 @@ predicate import_time_module_use(ModuleValue m, ModuleValue enclosing, Expr use,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `use` appears inside an annotation.
|
||||
*/
|
||||
predicate is_used_in_annotation(Expr use) {
|
||||
exists(FunctionExpr f |
|
||||
f.getReturns().getASubExpression*() = use or
|
||||
f.getArgs().getAnAnnotation().getASubExpression*() = use
|
||||
)
|
||||
or
|
||||
exists(AnnAssign a | a.getAnnotation().getASubExpression*() = use)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `use` appears as a subexpression of an annotation, _and_ if the
|
||||
* postponed evaluation of annotations presented in PEP 563 is in effect.
|
||||
* See https://www.python.org/dev/peps/pep-0563/
|
||||
*/
|
||||
predicate is_annotation_with_from_future_import_annotations(Expr use) {
|
||||
exists(ImportMember i | i.getScope() = use.getEnclosingModule() |
|
||||
i.getModule().pointsTo().getName() = "__future__" and i.getName() = "annotations"
|
||||
) and
|
||||
is_used_in_annotation(use)
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether importing module 'first' before importing module 'other' will fail at runtime, due to an
|
||||
* AttributeError at 'use' (in module 'other') caused by 'first.attr' not being defined as its definition can
|
||||
|
||||
Reference in New Issue
Block a user