Propagate reads on global variables (#11584)
## Summary
This PR ensures that if a variable is bound via `global`, and then the
`global` is read, the originating variable is also marked as read. It's
not perfect, in that it won't detect _rebindings_, like:
```python
from app import redis_connection
def func():
global redis_connection
redis_connection = 1
redis_connection()
```
So, above, `redis_connection` is still marked as unused.
But it does avoid flagging `redis_connection` as unused in:
```python
from app import redis_connection
def func():
global redis_connection
redis_connection()
```
Closes https://github.com/astral-sh/ruff/issues/11518.
This commit is contained in:
@@ -540,6 +540,23 @@ impl<'a> SemanticModel<'a> {
|
||||
return ReadResult::Resolved(binding_id);
|
||||
}
|
||||
|
||||
BindingKind::Global(Some(binding_id))
|
||||
| BindingKind::Nonlocal(binding_id, _) => {
|
||||
// Mark the shadowed binding as used.
|
||||
let reference_id = self.resolved_references.push(
|
||||
self.scope_id,
|
||||
self.node_id,
|
||||
ExprContext::Load,
|
||||
self.flags,
|
||||
name.range,
|
||||
);
|
||||
self.bindings[binding_id].references.push(reference_id);
|
||||
|
||||
// Treat it as resolved.
|
||||
self.resolved_names.insert(name.into(), binding_id);
|
||||
return ReadResult::Resolved(binding_id);
|
||||
}
|
||||
|
||||
_ => {
|
||||
// Otherwise, treat it as resolved.
|
||||
self.resolved_names.insert(name.into(), binding_id);
|
||||
|
||||
Reference in New Issue
Block a user