Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ruff] Ignore stub functions in unused-async (RUF029) #11026

Merged
merged 1 commit into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 6 additions & 2 deletions crates/ruff_linter/resources/test/fixtures/ruff/RUF029.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ async def pass_3(): # OK: uses an async loop


class Foo:
async def pass_4(): # OK: method of a class
async def pass_4(self): # OK: method of a class
pass


Expand All @@ -31,6 +31,10 @@ async def pass_5(): # OK: uses an await
await bla


async def pass_6(): # OK: just a stub
...


async def fail_1a(): # RUF029
time.sleep(1)

Expand Down Expand Up @@ -58,7 +62,7 @@ async def foo():

async def fail_4b(): # RUF029: the /outer/ function does not await
class Foo:
async def foo():
async def foo(self):
await bla


Expand Down
6 changes: 6 additions & 0 deletions crates/ruff_linter/src/rules/ruff/rules/unused_async.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::identifier::Identifier;
use ruff_python_ast::visitor::preorder;
use ruff_python_ast::{self as ast, AnyNodeRef, Expr, Stmt};
use ruff_python_semantic::analyze::function_type::is_stub;

use crate::checkers::ast::Checker;

Expand Down Expand Up @@ -160,6 +161,11 @@ pub(crate) fn unused_async(
return;
}

// Ignore stubs (e.g., `...`).
if is_stub(function_def, checker.semantic()) {
return;
}

let found_await_or_async = {
let mut visitor = AsyncExprVisitor::default();
preorder::walk_body(&mut visitor, body);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,56 +1,48 @@
---
source: crates/ruff_linter/src/rules/ruff/mod.rs
---
RUF029.py:34:11: RUF029 Function `fail_1a` is declared `async`, but doesn't `await` or use `async` features.
RUF029.py:38:11: RUF029 Function `fail_1a` is declared `async`, but doesn't `await` or use `async` features.
|
34 | async def fail_1a(): # RUF029
38 | async def fail_1a(): # RUF029
| ^^^^^^^ RUF029
35 | time.sleep(1)
39 | time.sleep(1)
|

RUF029.py:38:11: RUF029 Function `fail_1b` is declared `async`, but doesn't `await` or use `async` features.
RUF029.py:42:11: RUF029 Function `fail_1b` is declared `async`, but doesn't `await` or use `async` features.
|
38 | async def fail_1b(): # RUF029: yield does not require async
42 | async def fail_1b(): # RUF029: yield does not require async
| ^^^^^^^ RUF029
39 | yield "hello"
43 | yield "hello"
|

RUF029.py:42:11: RUF029 Function `fail_2` is declared `async`, but doesn't `await` or use `async` features.
RUF029.py:46:11: RUF029 Function `fail_2` is declared `async`, but doesn't `await` or use `async` features.
|
42 | async def fail_2(): # RUF029
46 | async def fail_2(): # RUF029
| ^^^^^^ RUF029
43 | with None as i:
44 | pass
47 | with None as i:
48 | pass
|

RUF029.py:47:11: RUF029 Function `fail_3` is declared `async`, but doesn't `await` or use `async` features.
RUF029.py:51:11: RUF029 Function `fail_3` is declared `async`, but doesn't `await` or use `async` features.
|
47 | async def fail_3(): # RUF029
51 | async def fail_3(): # RUF029
| ^^^^^^ RUF029
48 | for i in []:
49 | pass
52 | for i in []:
53 | pass
|

RUF029.py:54:11: RUF029 Function `fail_4a` is declared `async`, but doesn't `await` or use `async` features.
RUF029.py:58:11: RUF029 Function `fail_4a` is declared `async`, but doesn't `await` or use `async` features.
|
54 | async def fail_4a(): # RUF029: the /outer/ function does not await
58 | async def fail_4a(): # RUF029: the /outer/ function does not await
| ^^^^^^^ RUF029
55 | async def foo():
56 | await bla
59 | async def foo():
60 | await bla
|

RUF029.py:59:11: RUF029 Function `fail_4b` is declared `async`, but doesn't `await` or use `async` features.
RUF029.py:63:11: RUF029 Function `fail_4b` is declared `async`, but doesn't `await` or use `async` features.
|
59 | async def fail_4b(): # RUF029: the /outer/ function does not await
63 | async def fail_4b(): # RUF029: the /outer/ function does not await
| ^^^^^^^ RUF029
60 | class Foo:
61 | async def foo():
|

RUF029.py:66:15: RUF029 Function `fail_4c` is declared `async`, but doesn't `await` or use `async` features.
|
65 | def foo():
66 | async def fail_4c(): # RUF029: the /inner/ function does not await
| ^^^^^^^ RUF029
67 | pass
64 | class Foo:
65 | async def foo(self):
|