mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-18 17:40:37 +00:00
Improve inference capabilities of the BuiltinTypeChecker
(#10976)
This commit is contained in:
parent
65edbfe62f
commit
4284e079b5
7 changed files with 63 additions and 11 deletions
|
@ -58,3 +58,8 @@ for key in (
|
||||||
.keys()
|
.keys()
|
||||||
):
|
):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
from builtins import dict as SneakyDict
|
||||||
|
|
||||||
|
d = SneakyDict()
|
||||||
|
key in d.keys() # SIM118
|
||||||
|
|
|
@ -81,3 +81,11 @@ def foo():
|
||||||
result = {}
|
result = {}
|
||||||
for idx, name in enumerate(fruit):
|
for idx, name in enumerate(fruit):
|
||||||
result[name] = idx # PERF403
|
result[name] = idx # PERF403
|
||||||
|
|
||||||
|
|
||||||
|
def foo():
|
||||||
|
from builtins import dict as SneakyDict
|
||||||
|
fruit = ["apple", "pear", "orange"]
|
||||||
|
result = SneakyDict()
|
||||||
|
for idx, name in enumerate(fruit):
|
||||||
|
result[name] = idx # PERF403
|
||||||
|
|
|
@ -49,6 +49,14 @@ def yes_five(x: Dict[int, str]):
|
||||||
|
|
||||||
x = 1
|
x = 1
|
||||||
|
|
||||||
|
|
||||||
|
from builtins import list as SneakyList
|
||||||
|
|
||||||
|
|
||||||
|
sneaky = SneakyList()
|
||||||
|
# FURB131
|
||||||
|
del sneaky[:]
|
||||||
|
|
||||||
# these should not
|
# these should not
|
||||||
|
|
||||||
del names["key"]
|
del names["key"]
|
||||||
|
|
|
@ -397,5 +397,19 @@ SIM118.py:55:5: SIM118 [*] Use `key in dict` instead of `key in dict.keys()`
|
||||||
58 |+
|
58 |+
|
||||||
59 59 | ):
|
59 59 | ):
|
||||||
60 60 | continue
|
60 60 | continue
|
||||||
|
61 61 |
|
||||||
|
|
||||||
|
SIM118.py:65:1: SIM118 [*] Use `key in dict` instead of `key in dict.keys()`
|
||||||
|
|
|
||||||
|
64 | d = SneakyDict()
|
||||||
|
65 | key in d.keys() # SIM118
|
||||||
|
| ^^^^^^^^^^^^^^^ SIM118
|
||||||
|
|
|
||||||
|
= help: Remove `.keys()`
|
||||||
|
|
||||||
|
ℹ Safe fix
|
||||||
|
62 62 | from builtins import dict as SneakyDict
|
||||||
|
63 63 |
|
||||||
|
64 64 | d = SneakyDict()
|
||||||
|
65 |-key in d.keys() # SIM118
|
||||||
|
65 |+key in d # SIM118
|
||||||
|
|
|
@ -49,4 +49,10 @@ PERF403.py:83:9: PERF403 Use a dictionary comprehension instead of a for-loop
|
||||||
| ^^^^^^^^^^^^^^^^^^ PERF403
|
| ^^^^^^^^^^^^^^^^^^ PERF403
|
||||||
|
|
|
|
||||||
|
|
||||||
|
PERF403.py:91:9: PERF403 Use a dictionary comprehension instead of a for-loop
|
||||||
|
|
|
||||||
|
89 | result = SneakyDict()
|
||||||
|
90 | for idx, name in enumerate(fruit):
|
||||||
|
91 | result[name] = idx # PERF403
|
||||||
|
| ^^^^^^^^^^^^^^^^^^ PERF403
|
||||||
|
|
|
||||||
|
|
|
@ -150,4 +150,23 @@ FURB131.py:48:5: FURB131 [*] Prefer `clear` over deleting a full slice
|
||||||
50 50 | x = 1
|
50 50 | x = 1
|
||||||
51 51 |
|
51 51 |
|
||||||
|
|
||||||
|
FURB131.py:58:1: FURB131 [*] Prefer `clear` over deleting a full slice
|
||||||
|
|
|
||||||
|
56 | sneaky = SneakyList()
|
||||||
|
57 | # FURB131
|
||||||
|
58 | del sneaky[:]
|
||||||
|
| ^^^^^^^^^^^^^ FURB131
|
||||||
|
59 |
|
||||||
|
60 | # these should not
|
||||||
|
|
|
||||||
|
= help: Replace with `clear()`
|
||||||
|
|
||||||
|
ℹ Unsafe fix
|
||||||
|
55 55 |
|
||||||
|
56 56 | sneaky = SneakyList()
|
||||||
|
57 57 | # FURB131
|
||||||
|
58 |-del sneaky[:]
|
||||||
|
58 |+sneaky.clear()
|
||||||
|
59 59 |
|
||||||
|
60 60 | # these should not
|
||||||
|
61 61 |
|
||||||
|
|
|
@ -539,7 +539,7 @@ trait BuiltinTypeChecker {
|
||||||
/// Check annotation expression to match the intended type.
|
/// Check annotation expression to match the intended type.
|
||||||
fn match_annotation(annotation: &Expr, semantic: &SemanticModel) -> bool {
|
fn match_annotation(annotation: &Expr, semantic: &SemanticModel) -> bool {
|
||||||
let value = map_subscript(annotation);
|
let value = map_subscript(annotation);
|
||||||
Self::match_builtin_type(value, semantic)
|
semantic.match_builtin_expr(value, Self::BUILTIN_TYPE_NAME)
|
||||||
|| semantic.match_typing_expr(value, Self::TYPING_NAME)
|
|| semantic.match_typing_expr(value, Self::TYPING_NAME)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -562,15 +562,7 @@ trait BuiltinTypeChecker {
|
||||||
let Expr::Call(ast::ExprCall { func, .. }) = initializer else {
|
let Expr::Call(ast::ExprCall { func, .. }) = initializer else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
Self::match_builtin_type(func.as_ref(), semantic)
|
semantic.match_builtin_expr(func, Self::BUILTIN_TYPE_NAME)
|
||||||
}
|
|
||||||
|
|
||||||
/// Check if the given expression names the builtin type.
|
|
||||||
fn match_builtin_type(type_expr: &Expr, semantic: &SemanticModel) -> bool {
|
|
||||||
let Expr::Name(ast::ExprName { id, .. }) = type_expr else {
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
id == Self::BUILTIN_TYPE_NAME && semantic.is_builtin(Self::BUILTIN_TYPE_NAME)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue