diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll b/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll index 36773abe2b4..e1290b7758c 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll @@ -278,6 +278,12 @@ module ImportResolution { ) } + /** Join-order helper for `getImmediateModuleReference`. */ + pragma[nomagic] + private predicate module_reference_accesses(DataFlow::AttrRead ar, Module p, string attr_name) { + ar.accesses(getModuleReference(p), attr_name) + } + /** * Gets a dataflow node that is an immediate reference to the module `m`. * @@ -294,16 +300,13 @@ module ImportResolution { ) or // Reading an attribute on a module may return a submodule (or subpackage). - exists(DataFlow::AttrRead ar, Module p, string attr_name | - ar.accesses(getModuleReference(p), attr_name) and - result = ar - | + exists(Module p, string attr_name | module_reference_accesses(result, p, attr_name) | m = getModuleFromName(p.getPackageName() + "." + attr_name) ) or // This is also true for attributes that come from reexports. exists(Module reexporter, string attr_name | - result.(DataFlow::AttrRead).accesses(getModuleReference(reexporter), attr_name) and + module_reference_accesses(result, reexporter, attr_name) and module_reexport(reexporter, attr_name, m) ) or