Expand asyncio-dangling-task (RUF006) to include new_event_loop (#9976)
## Summary Fixes #9974 ## Test Plan I added some new test cases.
This commit is contained in:
committed by
GitHub
parent
46db3f96ac
commit
3e9d761b13
@@ -162,3 +162,26 @@ async def f(x: bool):
|
||||
T = asyncio.create_task(asyncio.sleep(1))
|
||||
else:
|
||||
T = None
|
||||
|
||||
|
||||
# Error
|
||||
def f():
|
||||
loop = asyncio.new_event_loop()
|
||||
loop.create_task(main()) # Error
|
||||
|
||||
# Error
|
||||
def f():
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.create_task(main()) # Error
|
||||
|
||||
# OK
|
||||
def f():
|
||||
global task
|
||||
loop = asyncio.new_event_loop()
|
||||
task = loop.create_task(main()) # Error
|
||||
|
||||
# OK
|
||||
def f():
|
||||
global task
|
||||
loop = asyncio.get_event_loop()
|
||||
task = loop.create_task(main()) # Error
|
||||
|
||||
@@ -3,6 +3,7 @@ use std::fmt;
|
||||
use ast::Stmt;
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
use ruff_python_ast::call_path::compose_call_path;
|
||||
use ruff_python_ast::{self as ast, Expr};
|
||||
use ruff_python_semantic::{analyze::typing, Scope, SemanticModel};
|
||||
use ruff_text_size::Ranged;
|
||||
@@ -52,14 +53,15 @@ use ruff_text_size::Ranged;
|
||||
/// - [The Python Standard Library](https://docs.python.org/3/library/asyncio-task.html#asyncio.create_task)
|
||||
#[violation]
|
||||
pub struct AsyncioDanglingTask {
|
||||
expr: String,
|
||||
method: Method,
|
||||
}
|
||||
|
||||
impl Violation for AsyncioDanglingTask {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let AsyncioDanglingTask { method } = self;
|
||||
format!("Store a reference to the return value of `asyncio.{method}`")
|
||||
let AsyncioDanglingTask { expr, method } = self;
|
||||
format!("Store a reference to the return value of `{expr}.{method}`")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,19 +82,29 @@ pub(crate) fn asyncio_dangling_task(expr: &Expr, semantic: &SemanticModel) -> Op
|
||||
})
|
||||
{
|
||||
return Some(Diagnostic::new(
|
||||
AsyncioDanglingTask { method },
|
||||
AsyncioDanglingTask {
|
||||
expr: "asyncio".to_string(),
|
||||
method,
|
||||
},
|
||||
expr.range(),
|
||||
));
|
||||
}
|
||||
|
||||
// Ex) `loop = asyncio.get_running_loop(); loop.create_task(...)`
|
||||
// Ex) `loop = ...; loop.create_task(...)`
|
||||
if let Expr::Attribute(ast::ExprAttribute { attr, value, .. }) = func.as_ref() {
|
||||
if attr == "create_task" {
|
||||
if typing::resolve_assignment(value, semantic).is_some_and(|call_path| {
|
||||
matches!(call_path.as_slice(), ["asyncio", "get_running_loop"])
|
||||
matches!(
|
||||
call_path.as_slice(),
|
||||
[
|
||||
"asyncio",
|
||||
"get_event_loop" | "get_running_loop" | "new_event_loop"
|
||||
]
|
||||
)
|
||||
}) {
|
||||
return Some(Diagnostic::new(
|
||||
AsyncioDanglingTask {
|
||||
expr: compose_call_path(value).unwrap_or_else(|| "asyncio".to_string()),
|
||||
method: Method::CreateTask,
|
||||
},
|
||||
expr.range(),
|
||||
|
||||
@@ -25,7 +25,7 @@ RUF006.py:68:12: RUF006 Store a reference to the return value of `asyncio.create
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF006
|
||||
|
|
||||
|
||||
RUF006.py:74:26: RUF006 Store a reference to the return value of `asyncio.create_task`
|
||||
RUF006.py:74:26: RUF006 Store a reference to the return value of `loop.create_task`
|
||||
|
|
||||
72 | def f():
|
||||
73 | loop = asyncio.get_running_loop()
|
||||
@@ -33,7 +33,7 @@ RUF006.py:74:26: RUF006 Store a reference to the return value of `asyncio.create
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF006
|
||||
|
|
||||
|
||||
RUF006.py:97:5: RUF006 Store a reference to the return value of `asyncio.create_task`
|
||||
RUF006.py:97:5: RUF006 Store a reference to the return value of `loop.create_task`
|
||||
|
|
||||
95 | def f():
|
||||
96 | loop = asyncio.get_running_loop()
|
||||
@@ -41,4 +41,24 @@ RUF006.py:97:5: RUF006 Store a reference to the return value of `asyncio.create_
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF006
|
||||
|
|
||||
|
||||
RUF006.py:170:5: RUF006 Store a reference to the return value of `loop.create_task`
|
||||
|
|
||||
168 | def f():
|
||||
169 | loop = asyncio.new_event_loop()
|
||||
170 | loop.create_task(main()) # Error
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ RUF006
|
||||
171 |
|
||||
172 | # Error
|
||||
|
|
||||
|
||||
RUF006.py:175:5: RUF006 Store a reference to the return value of `loop.create_task`
|
||||
|
|
||||
173 | def f():
|
||||
174 | loop = asyncio.get_event_loop()
|
||||
175 | loop.create_task(main()) # Error
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ RUF006
|
||||
176 |
|
||||
177 | # OK
|
||||
|
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user