Python: Port UnusedModuleVariable.ql

A simple use of the ImportResolution module. No test changes.
This commit is contained in:
Taus
2026-02-26 15:23:47 +00:00
parent 5ba6211ec2
commit 4c4fd32a5a

View File

@@ -13,9 +13,21 @@
*/
import python
private import LegacyPointsTo
private import semmle.python.dataflow.new.internal.ImportResolution
import Definition
/**
* Whether `name` is exported from module `m`, following Python's convention:
* if `__all__` is defined, use its entries; otherwise, export public names (not starting with `_`).
*/
private predicate isExported(Module m, string name) {
py_exports(m, name)
or
not py_exports(m, _) and
ImportResolution::module_export(m, name, _) and
not name.charAt(0) = "_"
}
/**
* Whether the module contains an __all__ definition,
* but it is more complex than a simple list of strings
@@ -59,7 +71,7 @@ predicate unused_global(Name unused, GlobalVariable v) {
// indirectly
defn.getBasicBlock().reachesExit() and u.getScope() != unused.getScope()
) and
not unused.getEnclosingModule().(ModuleWithPointsTo).getAnExport() = v.getId() and
not isExported(unused.getEnclosingModule(), v.getId()) and
not exists(unused.getParentNode().(ClassDef).getDefinedClass().getADecorator()) and
not exists(unused.getParentNode().(FunctionDef).getDefinedFunction().getADecorator()) and
unused.defines(v) and