Python: Prepare LocalSourceNode for locality

Removes the dependence on the (global) `ModuleVariableNode.getARead()`,
by adding a local version (that doesn't include `import *` reads)
instead.
This commit is contained in:
Taus
2026-01-09 13:49:17 +00:00
parent 8c0baefd3b
commit 4543c66d26
2 changed files with 9 additions and 5 deletions

View File

@@ -440,13 +440,17 @@ class ModuleVariableNode extends Node, TModuleVariableNode {
/** Gets a node that reads this variable. */
Node getARead() {
result.asCfgNode() = var.getALoad().getAFlowNode() and
// Ignore reads that happen when the module is imported. These are only executed once.
not result.getScope() = mod
result = this.getALocalRead()
or
this = import_star_read(result)
}
/** Gets a node that reads this variable, excluding reads that happen through `from ... import *`. */
Node getALocalRead() {
result.asCfgNode() = var.getALoad().getAFlowNode() and
not result.getScope() = mod
}
/** Gets an `EssaNode` that corresponds to an assignment of this global variable. */
Node getAWrite() {
any(EssaNodeDefinition def).definedBy(var, result.asCfgNode().(DefinitionNode))

View File

@@ -67,7 +67,7 @@ class LocalSourceNode extends Node {
or
// We explicitly include any read of a global variable, as some of these may have local flow going
// into them.
this = any(ModuleVariableNode mvn).getARead()
this = any(ModuleVariableNode v).getALocalRead()
or
// We include all scope entry definitions, as these act as the local source within the scope they
// enter.
@@ -248,7 +248,7 @@ private module Cached {
pragma[nomagic]
private predicate localSourceFlowStep(Node nodeFrom, Node nodeTo) {
simpleLocalFlowStep(nodeFrom, nodeTo, _) and
not nodeTo = any(ModuleVariableNode v).getARead()
not nodeTo = any(ModuleVariableNode v).getALocalRead()
}
/**