pub fn module_bindings(module: &Module<'_>) -> HashSet<String>Expand description
Collect the names introduced by module top-level statements of module:
assignment targets (x = …, x: T = …, and destructured a, b = … /
[x, y] = … / *rest, last = …), def names, and class names. Only the
module body is scanned; names bound inside function bodies are not collected.
A write whose root is one of these — when it is not a local/param/global-
declared/import in the writing function — is a write to module-shared state,
escalated to global.mutation (the Python analog of #29).
The function-body prescan (detect/mutation.rs) now covers for/with-as/
except-as locals: a for _cache in …, with ctx as _cache, or
except E as _cache binding shadows the module-level name inside that
function and is collected as a local, preventing false escalation to
global.mutation.
Not collected (accepted misses, consistent with the syntactic flat-scope
approximation in the other frontends): import names (handled by the F5 import
arm via the Imports table); subscript/attribute assignment targets (not new
bindings); names bound by module top-level for/with … as/except … as/
match patterns; names bound only inside nested blocks/comprehensions.
Residual accepted limits in the prescan (not chased): match pattern
captures, comprehension-scope targets (Python 3 gives them their own scope),
and walrus (:=) operator targets.