Skip to content

Commit

Permalink
Add a BindingKind for WithItem variables
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh committed Nov 10, 2023
1 parent 565ddeb commit 9319171
Show file tree
Hide file tree
Showing 8 changed files with 180 additions and 0 deletions.
10 changes: 10 additions & 0 deletions crates/ruff_linter/src/checkers/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1640,6 +1640,16 @@ impl<'a> Checker<'a> {
return;
}

if parent.is_with_stmt() {
self.add_binding(
id,
expr.range(),
BindingKind::WithItemVar,
BindingFlags::empty(),
);
return;
}

if helpers::is_unpacking_assignment(parent, expr) {
self.add_binding(
id,
Expand Down
1 change: 1 addition & 0 deletions crates/ruff_linter/src/renamer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ impl Renamer {
| BindingKind::Assignment
| BindingKind::BoundException
| BindingKind::LoopVar
| BindingKind::WithItemVar
| BindingKind::Global
| BindingKind::Nonlocal(_)
| BindingKind::ClassDefinition(_)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ pub(crate) fn unused_variable(checker: &Checker, scope: &Scope, diagnostics: &mu
.filter_map(|(name, binding)| {
if (binding.kind.is_assignment()
|| binding.kind.is_named_expr_assignment()
|| binding.kind.is_with_item_var()
|| (matches!(checker.settings.preview, PreviewMode::Enabled)
&& binding.kind.is_unpacked_assignment()))
&& !binding.is_nonlocal()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,26 @@ F841_0.py:51:9: F841 [*] Local variable `b` is assigned to but never used
53 53 | def d():
54 54 | nonlocal b

F841_0.py:66:24: F841 Local variable `connection` is assigned to but never used
|
64 | return None, None
65 |
66 | with connect() as (connection, cursor):
| ^^^^^^^^^^ F841
67 | cursor.execute("SELECT * FROM users")
|
= help: Remove assignment to unused variable `connection`

F841_0.py:74:24: F841 Local variable `connection` is assigned to but never used
|
72 | return None, None
73 |
74 | with connect() as (connection, cursor):
| ^^^^^^^^^^ F841
75 | cursor.execute("SELECT * FROM users")
|
= help: Remove assignment to unused variable `connection`

F841_0.py:79:26: F841 [*] Local variable `my_file` is assigned to but never used
|
78 | def f():
Expand All @@ -138,6 +158,24 @@ F841_0.py:79:26: F841 [*] Local variable `my_file` is assigned to but never used
81 81 |
82 82 |

F841_0.py:79:49: F841 Local variable `this` is assigned to but never used
|
78 | def f():
79 | with open("file") as my_file, open("") as ((this, that)):
| ^^^^ F841
80 | print("hello")
|
= help: Remove assignment to unused variable `this`

F841_0.py:79:55: F841 Local variable `that` is assigned to but never used
|
78 | def f():
79 | with open("file") as my_file, open("") as ((this, that)):
| ^^^^ F841
80 | print("hello")
|
= help: Remove assignment to unused variable `that`

F841_0.py:85:25: F841 [*] Local variable `my_file` is assigned to but never used
|
83 | def f():
Expand All @@ -159,6 +197,28 @@ F841_0.py:85:25: F841 [*] Local variable `my_file` is assigned to but never used
87 87 | ):
88 88 | print("hello")

F841_0.py:86:23: F841 Local variable `this` is assigned to but never used
|
84 | with (
85 | open("file") as my_file,
86 | open("") as ((this, that)),
| ^^^^ F841
87 | ):
88 | print("hello")
|
= help: Remove assignment to unused variable `this`

F841_0.py:86:29: F841 Local variable `that` is assigned to but never used
|
84 | with (
85 | open("file") as my_file,
86 | open("") as ((this, that)),
| ^^^^ F841
87 | ):
88 | print("hello")
|
= help: Remove assignment to unused variable `that`

F841_0.py:102:5: F841 [*] Local variable `msg3` is assigned to but never used
|
100 | msg1 = "Hello, world!"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,26 @@ F841_3.py:21:19: F841 [*] Local variable `x1` is assigned to but never used
23 23 |
24 24 | with foo() as (x2, y2):

F841_3.py:24:20: F841 Local variable `x2` is assigned to but never used
|
22 | pass
23 |
24 | with foo() as (x2, y2):
| ^^ F841
25 | pass
|
= help: Remove assignment to unused variable `x2`

F841_3.py:24:24: F841 Local variable `y2` is assigned to but never used
|
22 | pass
23 |
24 | with foo() as (x2, y2):
| ^^ F841
25 | pass
|
= help: Remove assignment to unused variable `y2`

F841_3.py:27:20: F841 [*] Local variable `x3` is assigned to but never used
|
25 | pass
Expand Down Expand Up @@ -377,6 +397,24 @@ F841_3.py:77:25: F841 [*] Local variable `cm` is assigned to but never used
79 79 |
80 80 |

F841_3.py:82:24: F841 Local variable `x` is assigned to but never used
|
81 | def f():
82 | with Nested(m) as (x, y):
| ^ F841
83 | pass
|
= help: Remove assignment to unused variable `x`

F841_3.py:82:27: F841 Local variable `y` is assigned to but never used
|
81 | def f():
82 | with Nested(m) as (x, y):
| ^ F841
83 | pass
|
= help: Remove assignment to unused variable `y`

F841_3.py:87:26: F841 [*] Local variable `cm` is assigned to but never used
|
86 | def f():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,26 @@ F841_0.py:51:9: F841 [*] Local variable `b` is assigned to but never used
53 53 | def d():
54 54 | nonlocal b

F841_0.py:66:24: F841 Local variable `connection` is assigned to but never used
|
64 | return None, None
65 |
66 | with connect() as (connection, cursor):
| ^^^^^^^^^^ F841
67 | cursor.execute("SELECT * FROM users")
|
= help: Remove assignment to unused variable `connection`

F841_0.py:74:24: F841 Local variable `connection` is assigned to but never used
|
72 | return None, None
73 |
74 | with connect() as (connection, cursor):
| ^^^^^^^^^^ F841
75 | cursor.execute("SELECT * FROM users")
|
= help: Remove assignment to unused variable `connection`

F841_0.py:79:26: F841 [*] Local variable `my_file` is assigned to but never used
|
78 | def f():
Expand All @@ -175,6 +195,24 @@ F841_0.py:79:26: F841 [*] Local variable `my_file` is assigned to but never used
81 81 |
82 82 |

F841_0.py:79:49: F841 Local variable `this` is assigned to but never used
|
78 | def f():
79 | with open("file") as my_file, open("") as ((this, that)):
| ^^^^ F841
80 | print("hello")
|
= help: Remove assignment to unused variable `this`

F841_0.py:79:55: F841 Local variable `that` is assigned to but never used
|
78 | def f():
79 | with open("file") as my_file, open("") as ((this, that)):
| ^^^^ F841
80 | print("hello")
|
= help: Remove assignment to unused variable `that`

F841_0.py:85:25: F841 [*] Local variable `my_file` is assigned to but never used
|
83 | def f():
Expand All @@ -196,6 +234,28 @@ F841_0.py:85:25: F841 [*] Local variable `my_file` is assigned to but never used
87 87 | ):
88 88 | print("hello")

F841_0.py:86:23: F841 Local variable `this` is assigned to but never used
|
84 | with (
85 | open("file") as my_file,
86 | open("") as ((this, that)),
| ^^^^ F841
87 | ):
88 | print("hello")
|
= help: Remove assignment to unused variable `this`

F841_0.py:86:29: F841 Local variable `that` is assigned to but never used
|
84 | with (
85 | open("file") as my_file,
86 | open("") as ((this, that)),
| ^^^^ F841
87 | ):
88 | print("hello")
|
= help: Remove assignment to unused variable `that`

F841_0.py:102:5: F841 [*] Local variable `msg3` is assigned to but never used
|
100 | msg1 = "Hello, world!"
Expand Down
3 changes: 3 additions & 0 deletions crates/ruff_linter/src/rules/pylint/rules/non_ascii_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ pub(crate) fn non_ascii_name(binding: &Binding, locator: &Locator) -> Option<Dia
BindingKind::Assignment => Kind::Assignment,
BindingKind::TypeParam => Kind::TypeParam,
BindingKind::LoopVar => Kind::LoopVar,
BindingKind::WithItemVar => Kind::WithItemVar,
BindingKind::Global => Kind::Global,
BindingKind::Nonlocal(_) => Kind::Nonlocal,
BindingKind::ClassDefinition(_) => Kind::ClassDefinition,
Expand Down Expand Up @@ -89,6 +90,7 @@ enum Kind {
Assignment,
TypeParam,
LoopVar,
WithItemVar,
Global,
Nonlocal,
ClassDefinition,
Expand All @@ -106,6 +108,7 @@ impl fmt::Display for Kind {
Kind::Assignment => f.write_str("Variable"),
Kind::TypeParam => f.write_str("Type parameter"),
Kind::LoopVar => f.write_str("Variable"),
Kind::WithItemVar => f.write_str("Variable"),
Kind::Global => f.write_str("Global"),
Kind::Nonlocal => f.write_str("Nonlocal"),
Kind::ClassDefinition => f.write_str("Class"),
Expand Down
7 changes: 7 additions & 0 deletions crates/ruff_python_semantic/src/binding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,13 @@ pub enum BindingKind<'a> {
/// ```
LoopVar,

/// A binding for a with statement variable, like `x` in:
/// ```python
/// with open('foo.py') as x:
/// ...
/// ```
WithItemVar,

/// A binding for a global variable, like `x` in:
/// ```python
/// def foo():
Expand Down

0 comments on commit 9319171

Please sign in to comment.