mirror of https://github.com/astral-sh/ruff
Respect scoping rules when identifying builtins (#6468)
## Summary Our `is_builtin` check did a naive walk over the parent scopes; instead, it needs to (e.g.) skip symbols in a class scope if being called outside of the class scope itself. Closes https://github.com/astral-sh/ruff/issues/6466. ## Test Plan `cargo test`
This commit is contained in:
parent
dc3275fe7f
commit
6706ae4828
|
|
@ -61,3 +61,30 @@ if x == types.X:
|
||||||
|
|
||||||
#: E721
|
#: E721
|
||||||
assert type(res) is int
|
assert type(res) is int
|
||||||
|
|
||||||
|
|
||||||
|
class Foo:
|
||||||
|
def asdf(self, value: str | None):
|
||||||
|
#: E721
|
||||||
|
if type(value) is str:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
class Foo:
|
||||||
|
def type(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def asdf(self, value: str | None):
|
||||||
|
#: E721
|
||||||
|
if type(value) is str:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
class Foo:
|
||||||
|
def asdf(self, value: str | None):
|
||||||
|
def type():
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Okay
|
||||||
|
if type(value) is str:
|
||||||
|
...
|
||||||
|
|
|
||||||
|
|
@ -152,4 +152,22 @@ E721.py:63:8: E721 Do not compare types, use `isinstance()`
|
||||||
| ^^^^^^^^^^^^^^^^ E721
|
| ^^^^^^^^^^^^^^^^ E721
|
||||||
|
|
|
|
||||||
|
|
||||||
|
E721.py:69:12: E721 Do not compare types, use `isinstance()`
|
||||||
|
|
|
||||||
|
67 | def asdf(self, value: str | None):
|
||||||
|
68 | #: E721
|
||||||
|
69 | if type(value) is str:
|
||||||
|
| ^^^^^^^^^^^^^^^^^^ E721
|
||||||
|
70 | ...
|
||||||
|
|
|
||||||
|
|
||||||
|
E721.py:79:12: E721 Do not compare types, use `isinstance()`
|
||||||
|
|
|
||||||
|
77 | def asdf(self, value: str | None):
|
||||||
|
78 | #: E721
|
||||||
|
79 | if type(value) is str:
|
||||||
|
| ^^^^^^^^^^^^^^^^^^ E721
|
||||||
|
80 | ...
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -249,14 +249,16 @@ impl<'a> SemanticModel<'a> {
|
||||||
|
|
||||||
/// Return `true` if `member` is bound as a builtin.
|
/// Return `true` if `member` is bound as a builtin.
|
||||||
pub fn is_builtin(&self, member: &str) -> bool {
|
pub fn is_builtin(&self, member: &str) -> bool {
|
||||||
self.find_binding(member)
|
self.lookup_symbol(member)
|
||||||
|
.map(|binding_id| &self.bindings[binding_id])
|
||||||
.is_some_and(|binding| binding.kind.is_builtin())
|
.is_some_and(|binding| binding.kind.is_builtin())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return `true` if `member` is an "available" symbol, i.e., a symbol that has not been bound
|
/// Return `true` if `member` is an "available" symbol, i.e., a symbol that has not been bound
|
||||||
/// in the current scope, or in any containing scope.
|
/// in the current scope, or in any containing scope.
|
||||||
pub fn is_available(&self, member: &str) -> bool {
|
pub fn is_available(&self, member: &str) -> bool {
|
||||||
self.find_binding(member)
|
self.lookup_symbol(member)
|
||||||
|
.map(|binding_id| &self.bindings[binding_id])
|
||||||
.map_or(true, |binding| binding.kind.is_builtin())
|
.map_or(true, |binding| binding.kind.is_builtin())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue