Skip to content

Commit 4a66e48

Browse files
committed
Python: Allow import resolution with recursive phi/refine steps
1 parent e522009 commit 4a66e48

File tree

2 files changed

+16
-11
lines changed

2 files changed

+16
-11
lines changed

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

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,19 @@ private import semmle.python.dataflow.new.internal.DataFlowPrivate
6464
* `bar` subpackage.
6565
*/
6666
module ImportResolution {
67+
/**
68+
* Holds if there is an ESSA step from `defFrom` to `defTo`, which should be allowed
69+
* for import resolution.
70+
*/
71+
private predicate allowedEssaImportStep(EssaDefinition defFrom, EssaDefinition defTo) {
72+
// to handle definitions guarded by if-then-else
73+
defFrom = defTo.(PhiFunction).getAnInput()
74+
or
75+
// refined variable
76+
// example: https://github.com/nvbn/thefuck/blob/ceeaeab94b5df5a4fe9d94d61e4f6b0bbea96378/thefuck/utils.py#L25-L45
77+
defFrom = defTo.(EssaNodeRefinement).getInput().getDefinition()
78+
}
79+
6780
/**
6881
* Holds if the module `m` defines a name `name` by assigning `defn` to it. This is an
6982
* overapproximation, as `name` may not in fact be exported (e.g. by defining an `__all__` that does
@@ -74,15 +87,7 @@ module ImportResolution {
7487
exists(EssaVariable v, EssaDefinition essaDef |
7588
v.getName() = name and
7689
v.getAUse() = ImportStar::getStarImported*(m).getANormalExit() and
77-
(
78-
essaDef = v.getDefinition()
79-
or
80-
// to handle definitions guarded by if-then-else
81-
essaDef = v.getDefinition().(PhiFunction).getAnInput()
82-
or
83-
// refined variable
84-
essaDef = v.getDefinition().(EssaNodeRefinement).getInput().getDefinition()
85-
)
90+
allowedEssaImportStep*(essaDef, v.getDefinition())
8691
|
8792
defn.getNode() = essaDef.(AssignmentDefinition).getValue()
8893
or

python/ql/test/experimental/import-resolution/main.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,10 @@ def local_import():
9595

9696
# check that refined definitions are handled correctly
9797
import refined # $ imports=refined as=refined
98-
check("refined.SOURCE", refined.SOURCE, refined.SOURCE, globals()) #$ MISSING: prints=SOURCE
98+
check("refined.SOURCE", refined.SOURCE, refined.SOURCE, globals()) #$ prints=SOURCE
9999

100100
import if_then_else_refined # $ imports=if_then_else_refined as=if_then_else_refined
101-
check("if_then_else_refined.src", if_then_else_refined.src, if_then_else_refined.src, globals()) #$ MISSING: prints=SOURCE
101+
check("if_then_else_refined.src", if_then_else_refined.src, if_then_else_refined.src, globals()) #$ prints=SOURCE
102102

103103
exit(__file__)
104104

0 commit comments

Comments
 (0)