Skip to content

Commit 091479c

Browse files
yoffCopilot
andcommitted
Python: drop legacy essa import from ImportResolution
`ImportResolution.qll` was the last new-dataflow file with a direct `import semmle.python.essa.SsaDefinitions`, used only for the `SsaSource::init_module_submodule_defn` helper. Inline the 5-line body as a local private predicate. No functional change — the inlined predicate is clause-for-clause equivalent (the `f = init.getEntryNode()` join only constrained `package = init`, since `Scope.getEntryNode()` is unique per scope; we now express that constraint directly). All 70 dataflow + ApiGraphs library-tests pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 4ce6131 commit 091479c

1 file changed

Lines changed: 19 additions & 4 deletions

File tree

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

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,18 @@ private import semmle.python.dataflow.new.DataFlow
1111
private import semmle.python.dataflow.new.internal.ImportStar
1212
private import semmle.python.dataflow.new.TypeTracking
1313
private import semmle.python.dataflow.new.internal.DataFlowPrivate
14-
private import semmle.python.essa.SsaDefinitions
14+
15+
/**
16+
* Holds if the name of `var` refers to a submodule of a package and `init` is
17+
* the `__init__` module of that package. Locally inlined replacement for the
18+
* legacy `SsaSource::init_module_submodule_defn` so that this module has no
19+
* direct dependency on `semmle.python.essa.SsaDefinitions`.
20+
*/
21+
private predicate initModuleSubmoduleDefn(GlobalVariable var, Module init) {
22+
init.isPackageInit() and
23+
exists(init.getPackage().getSubModule(var.getId())) and
24+
var.getScope() = init
25+
}
1526

1627
/**
1728
* Python modules and the way imports are resolved are... complicated. Here's a crash course in how
@@ -71,7 +82,9 @@ module ImportResolution {
7182
* Holds if there is an ESSA step from `defFrom` to `defTo`, which should be allowed
7283
* for import resolution.
7384
*/
74-
private predicate allowedEssaImportStep(SsaImpl::EssaDefinition defFrom, SsaImpl::EssaDefinition defTo) {
85+
private predicate allowedEssaImportStep(
86+
SsaImpl::EssaDefinition defFrom, SsaImpl::EssaDefinition defTo
87+
) {
7588
// to handle definitions guarded by if-then-else
7689
defFrom = defTo.(SsaImpl::PhiFunction).getAnInput()
7790
// Note: legacy ESSA refinement-step (e.g. for `foo.bar = X`) is
@@ -160,7 +173,9 @@ module ImportResolution {
160173
*/
161174
private predicate no_or_complicated_all(Module m) {
162175
// No mention of `__all__` in the module
163-
not exists(Cfg::DefinitionNode def | def.getScope() = m and def.(Cfg::NameNode).getId() = "__all__")
176+
not exists(Cfg::DefinitionNode def |
177+
def.getScope() = m and def.(Cfg::NameNode).getId() = "__all__"
178+
)
164179
or
165180
// `__all__` is set to a non-sequence value
166181
exists(Cfg::DefinitionNode def |
@@ -328,7 +343,7 @@ module ImportResolution {
328343
// imported yet.
329344
exists(string submodule, Module package, SsaImpl::EssaVariable var |
330345
submodule = var.getName() and
331-
SsaSource::init_module_submodule_defn(var.getSourceVariable().getVariable(), package.getEntryNode()) and
346+
initModuleSubmoduleDefn(var.getSourceVariable().getVariable(), package) and
332347
m = getModuleFromName(package.getPackageName() + "." + submodule) and
333348
result.asCfgNode() = var.getDefinition().(SsaImpl::EssaNodeDefinition).getDefiningNode()
334349
)

0 commit comments

Comments
 (0)