diff --git a/crates/ruff_linter/src/rules/flake8_async/mod.rs b/crates/ruff_linter/src/rules/flake8_async/mod.rs index 39da7b6e00973..19b6551a88a6d 100644 --- a/crates/ruff_linter/src/rules/flake8_async/mod.rs +++ b/crates/ruff_linter/src/rules/flake8_async/mod.rs @@ -11,6 +11,7 @@ mod tests { use crate::assert_messages; use crate::registry::Rule; + use crate::settings::types::PythonVersion; use crate::settings::LinterSettings; use crate::test::test_path; @@ -36,4 +37,18 @@ mod tests { assert_messages!(snapshot, diagnostics); Ok(()) } + + #[test_case(Path::new("ASYNC109_0.py"); "asyncio")] + #[test_case(Path::new("ASYNC109_1.py"); "trio")] + fn async109_python_310_or_older(path: &Path) -> Result<()> { + let diagnostics = test_path( + Path::new("flake8_async").join(path), + &LinterSettings { + target_version: PythonVersion::Py310, + ..LinterSettings::for_rule(Rule::AsyncFunctionWithTimeout) + }, + )?; + assert_messages!(path.file_name().unwrap().to_str().unwrap(), diagnostics); + Ok(()) + } } diff --git a/crates/ruff_linter/src/rules/flake8_async/rules/async_function_with_timeout.rs b/crates/ruff_linter/src/rules/flake8_async/rules/async_function_with_timeout.rs index 8edb208803315..4ceedafb5b435 100644 --- a/crates/ruff_linter/src/rules/flake8_async/rules/async_function_with_timeout.rs +++ b/crates/ruff_linter/src/rules/flake8_async/rules/async_function_with_timeout.rs @@ -6,6 +6,7 @@ use ruff_text_size::Ranged; use crate::checkers::ast::Checker; use crate::rules::flake8_async::helpers::AsyncModule; +use crate::settings::types::PythonVersion; /// ## What it does /// Checks for `async` functions with a `timeout` argument. @@ -86,6 +87,11 @@ pub(crate) fn async_function_with_timeout( AsyncModule::AsyncIo }; + // asyncio.timeout feature was first introduced in Python 3.11 + if module == AsyncModule::AsyncIo && checker.settings.target_version < PythonVersion::Py311 { + return; + } + checker.diagnostics.push(Diagnostic::new( AsyncFunctionWithTimeout { module }, timeout.range(), diff --git a/crates/ruff_linter/src/rules/flake8_async/snapshots/ruff_linter__rules__flake8_async__tests__ASYNC109_0.py.snap b/crates/ruff_linter/src/rules/flake8_async/snapshots/ruff_linter__rules__flake8_async__tests__ASYNC109_0.py.snap new file mode 100644 index 0000000000000..1a624f6dc47f6 --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_async/snapshots/ruff_linter__rules__flake8_async__tests__ASYNC109_0.py.snap @@ -0,0 +1,18 @@ +--- +source: crates/ruff_linter/src/rules/flake8_async/mod.rs +--- +ASYNC109_0.py:8:16: ASYNC109 Async function definition with a `timeout` parameter + | +8 | async def func(timeout): + | ^^^^^^^ ASYNC109 +9 | ... + | + = help: Use `trio.fail_after` instead + +ASYNC109_0.py:12:16: ASYNC109 Async function definition with a `timeout` parameter + | +12 | async def func(timeout=10): + | ^^^^^^^^^^ ASYNC109 +13 | ... + | + = help: Use `trio.fail_after` instead diff --git a/crates/ruff_linter/src/rules/flake8_async/snapshots/ruff_linter__rules__flake8_async__tests__ASYNC109_1.py.snap b/crates/ruff_linter/src/rules/flake8_async/snapshots/ruff_linter__rules__flake8_async__tests__ASYNC109_1.py.snap new file mode 100644 index 0000000000000..78704f6637673 --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_async/snapshots/ruff_linter__rules__flake8_async__tests__ASYNC109_1.py.snap @@ -0,0 +1,4 @@ +--- +source: crates/ruff_linter/src/rules/flake8_async/mod.rs +--- +