pub fn python_module_member_mutation(
root: Node<'_>,
source: &str,
module: &str,
member: &str,
max_nodes: usize,
) -> Option<PythonModuleMemberMutation>Expand description
What in this file can replace module.member, or None when nothing can.
An imported module object is shared process-wide, and Python permits
replacing one of its attributes (os.system = fake). A reviewed summary
describes the standard-library implementation, not a value written over it,
so a consumer that closes a call on that summary must first prove no
workspace source can perform the replacement. Two evidence families refuse
it, and both fail closed:
- A write-shaped target – an assignment, an augmented assignment, or a
del– whose attribute access resolves to the module. A statically named attribute refuses that member;setattrand every other dynamic form arrives through the escape rule below. - Any use of a name bound to the module outside its own import statement
and its attribute-object position. An alias, a call argument, a return,
or a subscript can carry the shared module object to a writer this walk
cannot see, so the proof refuses every member instead of following the
value. A read of
sys.modulesis refused for the same reason: it reaches every module object in the process.
A file that never binds the module proves the absence vacuously. The walk is iterative and bounded; exhausting the bound refuses every member.