Skip to content

Commit

Permalink
WIP: Extract get_assigned_value to method
Browse files Browse the repository at this point in the history
  • Loading branch information
qdegraaf committed Nov 6, 2023
1 parent 5e2bb8c commit 9351855
Show file tree
Hide file tree
Showing 5 changed files with 196 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,7 @@ async def func():

def func():
trio.run(trio.sleep(0)) # TRIO115

x, y = 0, 2000
trio.sleep(x)
trio.sleep(y)
35 changes: 10 additions & 25 deletions crates/ruff_linter/src/rules/flake8_trio/rules/zero_sleep_call.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::Stmt;
use ruff_python_ast::{self as ast, Expr, ExprCall, Int};
use ruff_python_semantic::analyze::typing::get_assigned_value;
use ruff_text_size::Ranged;

use crate::checkers::ast::Checker;
Expand Down Expand Up @@ -65,30 +65,15 @@ pub(crate) fn zero_sleep_call(checker: &mut Checker, call: &ExprCall) {
}
}
Expr::Name(ast::ExprName { id, .. }) => {
let scope = checker.semantic().current_scope();
if let Some(binding_id) = scope.get(id) {
let binding = checker.semantic().binding(binding_id);
if binding.kind.is_assignment() || binding.kind.is_named_expr_assignment() {
if let Some(parent_id) = binding.source {
let parent = checker.semantic().statement(parent_id);
if let Stmt::Assign(ast::StmtAssign { value, .. })
| Stmt::AnnAssign(ast::StmtAnnAssign {
value: Some(value), ..
})
| Stmt::AugAssign(ast::StmtAugAssign { value, .. }) = parent
{
if let Expr::NumberLiteral(ast::ExprNumberLiteral {
value: num, ..
}) = value.as_ref()
{
let Some(int) = num.as_int() else { return };
if *int != Int::ZERO {
return;
}
}
}
}
}
let Some(value) = get_assigned_value(id, checker.semantic()) else {
return;
};
let Expr::NumberLiteral(ast::ExprNumberLiteral { value: num, .. }) = value else {
return;
};
let Some(int) = num.as_int() else { return };
if *int != Int::ZERO {
return;
}
}
_ => return,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
---
source: crates/ruff_linter/src/rules/flake8_trio/mod.rs
assertion_line: 26
---
TRIO115.py:6:11: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)`
|
5 | async def func():
6 | await trio.sleep(0) # TRIO115
| ^^^^^^^^^^^^^ TRIO115
7 | await trio.sleep(1) # OK
8 | await trio.sleep(0, 1) # OK
|
= help: Replace with `trio.lowlevel.checkpoint()`

ℹ Fix
3 3 |
4 4 |
5 5 | async def func():
6 |- await trio.sleep(0) # TRIO115
6 |+ await trio.lowlevel.checkpoint # TRIO115
7 7 | await trio.sleep(1) # OK
8 8 | await trio.sleep(0, 1) # OK
9 9 | await trio.sleep(...) # OK

TRIO115.py:12:5: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)`
|
10 | await trio.sleep() # OK
11 |
12 | trio.sleep(0) # TRIO115
| ^^^^^^^^^^^^^ TRIO115
13 | foo = 0
14 | trio.sleep(foo) # TRIO115
|
= help: Replace with `trio.lowlevel.checkpoint()`

ℹ Fix
9 9 | await trio.sleep(...) # OK
10 10 | await trio.sleep() # OK
11 11 |
12 |- trio.sleep(0) # TRIO115
12 |+ trio.lowlevel.checkpoint # TRIO115
13 13 | foo = 0
14 14 | trio.sleep(foo) # TRIO115
15 15 | trio.sleep(1) # OK

TRIO115.py:14:5: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)`
|
12 | trio.sleep(0) # TRIO115
13 | foo = 0
14 | trio.sleep(foo) # TRIO115
| ^^^^^^^^^^^^^^^ TRIO115
15 | trio.sleep(1) # OK
16 | time.sleep(0) # OK
|
= help: Replace with `trio.lowlevel.checkpoint()`

ℹ Fix
11 11 |
12 12 | trio.sleep(0) # TRIO115
13 13 | foo = 0
14 |- trio.sleep(foo) # TRIO115
14 |+ trio.lowlevel.checkpoint # TRIO115
15 15 | trio.sleep(1) # OK
16 16 | time.sleep(0) # OK
17 17 |

TRIO115.py:18:5: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)`
|
16 | time.sleep(0) # OK
17 |
18 | sleep(0) # TRIO115
| ^^^^^^^^ TRIO115
|
= help: Replace with `trio.lowlevel.checkpoint()`

ℹ Fix
15 15 | trio.sleep(1) # OK
16 16 | time.sleep(0) # OK
17 17 |
18 |- sleep(0) # TRIO115
18 |+ trio.lowlevel.checkpoint # TRIO115
19 19 |
20 20 |
21 21 | trio.sleep(0) # TRIO115

TRIO115.py:21:1: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)`
|
21 | trio.sleep(0) # TRIO115
| ^^^^^^^^^^^^^ TRIO115
|
= help: Replace with `trio.lowlevel.checkpoint()`

ℹ Fix
18 18 | sleep(0) # TRIO115
19 19 |
20 20 |
21 |-trio.sleep(0) # TRIO115
21 |+trio.lowlevel.checkpoint # TRIO115
22 22 |
23 23 |
24 24 | def func():

TRIO115.py:25:14: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)`
|
24 | def func():
25 | trio.run(trio.sleep(0)) # TRIO115
| ^^^^^^^^^^^^^ TRIO115
26 |
27 | x, y = 0, 2000
|
= help: Replace with `trio.lowlevel.checkpoint()`

ℹ Fix
22 22 |
23 23 |
24 24 | def func():
25 |- trio.run(trio.sleep(0)) # TRIO115
25 |+ trio.run(trio.lowlevel.checkpoint) # TRIO115
26 26 |
27 27 | x, y = 0, 2000
28 28 | trio.sleep(x)


Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::Stmt;
use ruff_python_ast::{self as ast, Arguments, Expr};
use ruff_python_semantic::analyze::typing::get_assigned_value;
use ruff_text_size::TextRange;

use crate::checkers::ast::Checker;
Expand Down Expand Up @@ -98,30 +98,13 @@ pub(crate) fn unnecessary_list_cast(checker: &mut Checker, iter: &Expr) {
range: iterable_range,
..
}) => {
let scope = checker.semantic().current_scope();
if let Some(binding_id) = scope.get(id) {
let binding = checker.semantic().binding(binding_id);
if binding.kind.is_assignment() || binding.kind.is_named_expr_assignment() {
if let Some(parent_id) = binding.source {
let parent = checker.semantic().statement(parent_id);
if let Stmt::Assign(ast::StmtAssign { value, .. })
| Stmt::AnnAssign(ast::StmtAnnAssign {
value: Some(value), ..
})
| Stmt::AugAssign(ast::StmtAugAssign { value, .. }) = parent
{
if matches!(
value.as_ref(),
Expr::Tuple(_) | Expr::List(_) | Expr::Set(_)
) {
let mut diagnostic =
Diagnostic::new(UnnecessaryListCast, *list_range);
diagnostic.set_fix(remove_cast(*list_range, *iterable_range));
checker.diagnostics.push(diagnostic);
}
}
}
}
let Some(value) = get_assigned_value(id, checker.semantic()) else {
return;
};
if matches!(value, Expr::Tuple(_) | Expr::List(_) | Expr::Set(_)) {
let mut diagnostic = Diagnostic::new(UnnecessaryListCast, *list_range);
diagnostic.set_fix(remove_cast(*list_range, *iterable_range));
checker.diagnostics.push(diagnostic);
}
}
_ => {}
Expand Down
51 changes: 51 additions & 0 deletions crates/ruff_python_semantic/src/analyze/typing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -571,3 +571,54 @@ pub fn resolve_assignment<'a>(
_ => None,
}
}

/// Get
pub fn get_assigned_value<'a>(id: &str, semantic: &'a SemanticModel<'a>) -> Option<&'a Expr> {
let scope = semantic.current_scope();
let binding_id = scope.get(id)?;
let binding = semantic.binding(binding_id);
if binding.kind.is_assignment() {
println!("{id}: is_assignment");
let parent_id = binding.source?;
let parent = semantic.statement(parent_id);
if let Stmt::Assign(ast::StmtAssign { value, .. })
| Stmt::AnnAssign(ast::StmtAnnAssign {
value: Some(value), ..
})
| Stmt::AugAssign(ast::StmtAugAssign { value, .. }) = parent
{
println!("{:?}", value);
return Some(value.as_ref());
}
return None;
}
if binding.kind.is_unpacked_assignment() {
println!("{id}: is_unpacked_assignment");
let parent_id = binding.source?;
let parent = semantic.statement(parent_id);
if let Stmt::Assign(ast::StmtAssign { value, .. })
| Stmt::AnnAssign(ast::StmtAnnAssign {
value: Some(value), ..
})
| Stmt::AugAssign(ast::StmtAugAssign { value, .. }) = parent
{
return Some(value.as_ref());
}
return None;
}
if binding.kind.is_named_expr_assignment() {
println!("{id}: is_named_expr_assignment");
let parent_id = binding.source?;
let parent = semantic.statement(parent_id);
if let Stmt::Assign(ast::StmtAssign { value, .. })
| Stmt::AnnAssign(ast::StmtAnnAssign {
value: Some(value), ..
})
| Stmt::AugAssign(ast::StmtAugAssign { value, .. }) = parent
{
return Some(value.as_ref());
}
return None;
}
None
}

0 comments on commit 9351855

Please sign in to comment.