mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 10:48:32 +00:00
Re-code flake8-trio and flake8-async rules to match upstream (#10416)
Co-authored-by: Micha Reiser <micha@reiser.io>
This commit is contained in:
parent
4b3278fe0b
commit
8cc96d7868
51 changed files with 1422 additions and 595 deletions
|
@ -334,7 +334,6 @@ quality tools, including:
|
|||
- [flake8-super](https://pypi.org/project/flake8-super/)
|
||||
- [flake8-tidy-imports](https://pypi.org/project/flake8-tidy-imports/)
|
||||
- [flake8-todos](https://pypi.org/project/flake8-todos/)
|
||||
- [flake8-trio](https://pypi.org/project/flake8-trio/)
|
||||
- [flake8-type-checking](https://pypi.org/project/flake8-type-checking/)
|
||||
- [flake8-use-pathlib](https://pypi.org/project/flake8-use-pathlib/)
|
||||
- [flynt](https://pypi.org/project/flynt/) ([#2102](https://github.com/astral-sh/ruff/issues/2102))
|
||||
|
|
|
@ -1,23 +1,27 @@
|
|||
import urllib.request
|
||||
import requests
|
||||
import httpx
|
||||
import trio
|
||||
|
||||
|
||||
async def foo():
|
||||
urllib.request.urlopen("http://example.com/foo/bar").read()
|
||||
async def func():
|
||||
with trio.fail_after():
|
||||
...
|
||||
|
||||
|
||||
async def foo():
|
||||
requests.get()
|
||||
async def func():
|
||||
with trio.fail_at():
|
||||
await ...
|
||||
|
||||
|
||||
async def foo():
|
||||
httpx.get()
|
||||
async def func():
|
||||
with trio.move_on_after():
|
||||
...
|
||||
|
||||
|
||||
async def foo():
|
||||
requests.post()
|
||||
async def func():
|
||||
with trio.move_at():
|
||||
await ...
|
||||
|
||||
|
||||
async def foo():
|
||||
httpx.post()
|
||||
async def func():
|
||||
with trio.move_at():
|
||||
async with trio.open_nursery() as nursery:
|
||||
...
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
import os
|
||||
|
||||
|
||||
async def foo():
|
||||
os.popen()
|
||||
|
||||
|
||||
async def foo():
|
||||
os.spawnl()
|
||||
|
||||
|
||||
async def foo():
|
||||
os.fspath("foo")
|
|
@ -26,7 +26,7 @@ async def func() -> None:
|
|||
await trio.lowlevel.wait_task_rescheduled(foo)
|
||||
await trio.lowlevel.wait_writable(foo)
|
||||
|
||||
# TRIO105
|
||||
# ASYNC105
|
||||
trio.aclose_forcefully(foo)
|
||||
trio.open_file(foo)
|
||||
trio.open_ssl_over_tcp_listeners(foo, foo)
|
||||
|
@ -55,10 +55,10 @@ async def func() -> None:
|
|||
async with await trio.open_file(foo): # Ok
|
||||
pass
|
||||
|
||||
async with trio.open_file(foo): # TRIO105
|
||||
async with trio.open_file(foo): # ASYNC105
|
||||
pass
|
||||
|
||||
|
||||
def func() -> None:
|
||||
# TRIO105 (without fix)
|
||||
# ASYNC105 (without fix)
|
||||
trio.open_file(foo)
|
|
@ -2,19 +2,19 @@ async def func():
|
|||
import trio
|
||||
from trio import sleep
|
||||
|
||||
await trio.sleep(0) # TRIO115
|
||||
await trio.sleep(0) # ASYNC115
|
||||
await trio.sleep(1) # OK
|
||||
await trio.sleep(0, 1) # OK
|
||||
await trio.sleep(...) # OK
|
||||
await trio.sleep() # OK
|
||||
|
||||
trio.sleep(0) # TRIO115
|
||||
trio.sleep(0) # ASYNC115
|
||||
foo = 0
|
||||
trio.sleep(foo) # OK
|
||||
trio.sleep(1) # OK
|
||||
time.sleep(0) # OK
|
||||
|
||||
sleep(0) # TRIO115
|
||||
sleep(0) # ASYNC115
|
||||
|
||||
bar = "bar"
|
||||
trio.sleep(bar)
|
||||
|
@ -45,18 +45,18 @@ async def func():
|
|||
def func():
|
||||
import trio
|
||||
|
||||
trio.run(trio.sleep(0)) # TRIO115
|
||||
trio.run(trio.sleep(0)) # ASYNC115
|
||||
|
||||
|
||||
from trio import Event, sleep
|
||||
|
||||
|
||||
def func():
|
||||
sleep(0) # TRIO115
|
||||
sleep(0) # ASYNC115
|
||||
|
||||
|
||||
async def func():
|
||||
await sleep(seconds=0) # TRIO115
|
||||
await sleep(seconds=0) # ASYNC115
|
||||
|
||||
|
||||
def func():
|
69
crates/ruff_linter/resources/test/fixtures/flake8_async/ASYNC210.py
vendored
Normal file
69
crates/ruff_linter/resources/test/fixtures/flake8_async/ASYNC210.py
vendored
Normal file
|
@ -0,0 +1,69 @@
|
|||
import urllib
|
||||
import requests
|
||||
import httpx
|
||||
import urllib3
|
||||
|
||||
|
||||
async def foo():
|
||||
urllib.request.urlopen("http://example.com/foo/bar").read() # ASYNC210
|
||||
|
||||
|
||||
async def foo():
|
||||
requests.get() # ASYNC210
|
||||
|
||||
|
||||
async def foo():
|
||||
httpx.get() # ASYNC210
|
||||
|
||||
|
||||
async def foo():
|
||||
requests.post() # ASYNC210
|
||||
|
||||
|
||||
async def foo():
|
||||
httpx.post() # ASYNC210
|
||||
|
||||
|
||||
async def foo():
|
||||
requests.get() # ASYNC210
|
||||
requests.get(...) # ASYNC210
|
||||
requests.get # Ok
|
||||
print(requests.get()) # ASYNC210
|
||||
print(requests.get(requests.get())) # ASYNC210
|
||||
|
||||
requests.options() # ASYNC210
|
||||
requests.head() # ASYNC210
|
||||
requests.post() # ASYNC210
|
||||
requests.put() # ASYNC210
|
||||
requests.patch() # ASYNC210
|
||||
requests.delete() # ASYNC210
|
||||
requests.foo()
|
||||
|
||||
httpx.options("") # ASYNC210
|
||||
httpx.head("") # ASYNC210
|
||||
httpx.post("") # ASYNC210
|
||||
httpx.put("") # ASYNC210
|
||||
httpx.patch("") # ASYNC210
|
||||
httpx.delete("") # ASYNC210
|
||||
httpx.foo() # Ok
|
||||
|
||||
urllib3.request() # ASYNC210
|
||||
urllib3.request(...) # ASYNC210
|
||||
|
||||
urllib.request.urlopen("") # ASYNC210
|
||||
|
||||
r = {}
|
||||
r.get("not a sync http client") # Ok
|
||||
|
||||
|
||||
async def bar():
|
||||
|
||||
def request():
|
||||
pass
|
||||
|
||||
request() # Ok
|
||||
|
||||
def urlopen():
|
||||
pass
|
||||
|
||||
urlopen() # Ok
|
98
crates/ruff_linter/resources/test/fixtures/flake8_async/ASYNC22x.py
vendored
Normal file
98
crates/ruff_linter/resources/test/fixtures/flake8_async/ASYNC22x.py
vendored
Normal file
|
@ -0,0 +1,98 @@
|
|||
import os
|
||||
import subprocess
|
||||
|
||||
# Violation cases:
|
||||
|
||||
|
||||
async def func():
|
||||
subprocess.run("foo") # ASYNC221
|
||||
|
||||
|
||||
async def func():
|
||||
subprocess.call("foo") # ASYNC221
|
||||
|
||||
|
||||
async def func():
|
||||
subprocess.foo(0) # OK
|
||||
|
||||
|
||||
async def func():
|
||||
os.wait4(10) # ASYNC222
|
||||
|
||||
|
||||
async def func():
|
||||
os.wait(12) # ASYNC222
|
||||
|
||||
|
||||
async def foo():
|
||||
await async_fun(
|
||||
subprocess.getoutput() # ASYNC221
|
||||
)
|
||||
subprocess.Popen() # ASYNC220
|
||||
os.system() # ASYNC221
|
||||
|
||||
system()
|
||||
os.system.anything()
|
||||
os.anything()
|
||||
|
||||
subprocess.run() # ASYNC221
|
||||
subprocess.call() # ASYNC221
|
||||
subprocess.check_call() # ASYNC221
|
||||
subprocess.check_output() # ASYNC221
|
||||
subprocess.getoutput() # ASYNC221
|
||||
subprocess.getstatusoutput() # ASYNC221
|
||||
|
||||
await async_fun(
|
||||
subprocess.getoutput() # ASYNC221
|
||||
)
|
||||
|
||||
subprocess.anything()
|
||||
subprocess.foo()
|
||||
subprocess.bar.foo()
|
||||
subprocess()
|
||||
|
||||
os.posix_spawn() # ASYNC221
|
||||
os.posix_spawnp() # ASYNC221
|
||||
|
||||
os.spawn()
|
||||
os.spawn
|
||||
os.spawnllll()
|
||||
|
||||
os.spawnl() # ASYNC221
|
||||
os.spawnle() # ASYNC221
|
||||
os.spawnlp() # ASYNC221
|
||||
os.spawnlpe() # ASYNC221
|
||||
os.spawnv() # ASYNC221
|
||||
os.spawnve() # ASYNC221
|
||||
os.spawnvp() # ASYNC221
|
||||
os.spawnvpe() # ASYNC221
|
||||
|
||||
P_NOWAIT = os.P_NOWAIT
|
||||
|
||||
# if mode is given, and is not os.P_WAIT: ASYNC220
|
||||
os.spawnl(os.P_NOWAIT) # ASYNC220
|
||||
os.spawnl(P_NOWAIT) # ASYNC220
|
||||
os.spawnl(mode=os.P_NOWAIT) # ASYNC220
|
||||
os.spawnl(mode=P_NOWAIT) # ASYNC220
|
||||
|
||||
P_WAIT = os.P_WAIT
|
||||
|
||||
# if it is P_WAIT, ASYNC221
|
||||
os.spawnl(P_WAIT) # ASYNC221
|
||||
os.spawnl(mode=os.P_WAIT) # ASYNC221
|
||||
os.spawnl(mode=P_WAIT) # ASYNC221
|
||||
|
||||
# other weird cases: ASYNC220
|
||||
os.spawnl(0) # ASYNC220
|
||||
os.spawnl(1) # ASYNC220
|
||||
os.spawnl(foo()) # ASYNC220
|
||||
|
||||
# ASYNC222
|
||||
os.wait() # ASYNC222
|
||||
os.wait3() # ASYNC222
|
||||
os.wait4() # ASYNC222
|
||||
os.waitid() # ASYNC222
|
||||
os.waitpid() # ASYNC222
|
||||
|
||||
os.waitpi()
|
||||
os.waiti()
|
|
@ -1,53 +1,48 @@
|
|||
import os
|
||||
import subprocess
|
||||
import time
|
||||
import io
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
async def foo():
|
||||
open("") # ASYNC230
|
||||
io.open_code("") # ASYNC230
|
||||
|
||||
with open(""): # ASYNC230
|
||||
...
|
||||
|
||||
with open("") as f: # ASYNC230
|
||||
...
|
||||
|
||||
with foo(), open(""): # ASYNC230
|
||||
...
|
||||
|
||||
async with open(""): # ASYNC230
|
||||
...
|
||||
|
||||
|
||||
def foo_sync():
|
||||
open("")
|
||||
|
||||
# Violation cases:
|
||||
|
||||
|
||||
async def func():
|
||||
open("foo")
|
||||
|
||||
|
||||
async def func():
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
async def func():
|
||||
subprocess.run("foo")
|
||||
|
||||
|
||||
async def func():
|
||||
subprocess.call("foo")
|
||||
|
||||
|
||||
async def func():
|
||||
subprocess.foo(0)
|
||||
|
||||
|
||||
async def func():
|
||||
os.wait4(10)
|
||||
|
||||
|
||||
async def func():
|
||||
os.wait(12)
|
||||
open("foo") # ASYNC230
|
||||
|
||||
|
||||
# Violation cases for pathlib:
|
||||
|
||||
|
||||
async def func():
|
||||
Path("foo").open() # ASYNC101
|
||||
Path("foo").open() # ASYNC230
|
||||
|
||||
|
||||
async def func():
|
||||
p = Path("foo")
|
||||
p.open() # ASYNC101
|
||||
p.open() # ASYNC230
|
||||
|
||||
|
||||
async def func():
|
||||
with Path("foo").open() as f: # ASYNC101
|
||||
with Path("foo").open() as f: # ASYNC230
|
||||
pass
|
||||
|
||||
|
||||
|
@ -55,13 +50,13 @@ async def func() -> None:
|
|||
p = Path("foo")
|
||||
|
||||
async def bar():
|
||||
p.open() # ASYNC101
|
||||
p.open() # ASYNC230
|
||||
|
||||
|
||||
async def func() -> None:
|
||||
(p1, p2) = (Path("foo"), Path("bar"))
|
||||
|
||||
p1.open() # ASYNC101
|
||||
p1.open() # ASYNC230
|
||||
|
||||
|
||||
# Non-violation cases for pathlib:
|
14
crates/ruff_linter/resources/test/fixtures/flake8_async/ASYNC251.py
vendored
Normal file
14
crates/ruff_linter/resources/test/fixtures/flake8_async/ASYNC251.py
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
import time
|
||||
import asyncio
|
||||
|
||||
|
||||
async def func():
|
||||
time.sleep(1) # ASYNC251
|
||||
|
||||
|
||||
def func():
|
||||
time.sleep(1) # OK
|
||||
|
||||
|
||||
async def func():
|
||||
asyncio.sleep(1) # OK
|
|
@ -1,27 +0,0 @@
|
|||
import trio
|
||||
|
||||
|
||||
async def func():
|
||||
with trio.fail_after():
|
||||
...
|
||||
|
||||
|
||||
async def func():
|
||||
with trio.fail_at():
|
||||
await ...
|
||||
|
||||
|
||||
async def func():
|
||||
with trio.move_on_after():
|
||||
...
|
||||
|
||||
|
||||
async def func():
|
||||
with trio.move_at():
|
||||
await ...
|
||||
|
||||
|
||||
async def func():
|
||||
with trio.move_at():
|
||||
async with trio.open_nursery() as nursery:
|
||||
...
|
|
@ -15,8 +15,8 @@ use crate::rules::{
|
|||
flake8_comprehensions, flake8_datetimez, flake8_debugger, flake8_django,
|
||||
flake8_future_annotations, flake8_gettext, flake8_implicit_str_concat, flake8_logging,
|
||||
flake8_logging_format, flake8_pie, flake8_print, flake8_pyi, flake8_pytest_style, flake8_self,
|
||||
flake8_simplify, flake8_tidy_imports, flake8_trio, flake8_type_checking, flake8_use_pathlib,
|
||||
flynt, numpy, pandas_vet, pep8_naming, pycodestyle, pyflakes, pylint, pyupgrade, refurb, ruff,
|
||||
flake8_simplify, flake8_tidy_imports, flake8_type_checking, flake8_use_pathlib, flynt, numpy,
|
||||
pandas_vet, pep8_naming, pycodestyle, pyflakes, pylint, pyupgrade, refurb, ruff,
|
||||
};
|
||||
use crate::settings::types::PythonVersion;
|
||||
|
||||
|
@ -505,11 +505,18 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) {
|
|||
if checker.enabled(Rule::BlockingHttpCallInAsyncFunction) {
|
||||
flake8_async::rules::blocking_http_call(checker, call);
|
||||
}
|
||||
if checker.enabled(Rule::OpenSleepOrSubprocessInAsyncFunction) {
|
||||
flake8_async::rules::open_sleep_or_subprocess_call(checker, call);
|
||||
if checker.enabled(Rule::BlockingOpenCallInAsyncFunction) {
|
||||
flake8_async::rules::blocking_open_call(checker, call);
|
||||
}
|
||||
if checker.enabled(Rule::BlockingOsCallInAsyncFunction) {
|
||||
flake8_async::rules::blocking_os_call(checker, call);
|
||||
if checker.any_enabled(&[
|
||||
Rule::CreateSubprocessInAsyncFunction,
|
||||
Rule::RunProcessInAsyncFunction,
|
||||
Rule::WaitForProcessInAsyncFunction,
|
||||
]) {
|
||||
flake8_async::rules::blocking_process_invocation(checker, call);
|
||||
}
|
||||
if checker.enabled(Rule::BlockingSleepInAsyncFunction) {
|
||||
flake8_async::rules::blocking_sleep(checker, call);
|
||||
}
|
||||
if checker.enabled(Rule::SleepForeverCall) {
|
||||
flake8_async::rules::sleep_forever_call(checker, call);
|
||||
|
@ -963,10 +970,10 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) {
|
|||
refurb::rules::no_implicit_cwd(checker, call);
|
||||
}
|
||||
if checker.enabled(Rule::TrioSyncCall) {
|
||||
flake8_trio::rules::sync_call(checker, call);
|
||||
flake8_async::rules::sync_call(checker, call);
|
||||
}
|
||||
if checker.enabled(Rule::TrioZeroSleepCall) {
|
||||
flake8_trio::rules::zero_sleep_call(checker, call);
|
||||
flake8_async::rules::zero_sleep_call(checker, call);
|
||||
}
|
||||
if checker.enabled(Rule::UnnecessaryDunderCall) {
|
||||
pylint::rules::unnecessary_dunder_call(checker, call);
|
||||
|
|
|
@ -8,11 +8,11 @@ use ruff_text_size::Ranged;
|
|||
use crate::checkers::ast::Checker;
|
||||
use crate::registry::Rule;
|
||||
use crate::rules::{
|
||||
airflow, flake8_bandit, flake8_boolean_trap, flake8_bugbear, flake8_builtins, flake8_debugger,
|
||||
flake8_django, flake8_errmsg, flake8_import_conventions, flake8_pie, flake8_pyi,
|
||||
flake8_pytest_style, flake8_raise, flake8_return, flake8_simplify, flake8_slots,
|
||||
flake8_tidy_imports, flake8_trio, flake8_type_checking, mccabe, pandas_vet, pep8_naming,
|
||||
perflint, pycodestyle, pyflakes, pygrep_hooks, pylint, pyupgrade, refurb, ruff, tryceratops,
|
||||
airflow, flake8_async, flake8_bandit, flake8_boolean_trap, flake8_bugbear, flake8_builtins,
|
||||
flake8_debugger, flake8_django, flake8_errmsg, flake8_import_conventions, flake8_pie,
|
||||
flake8_pyi, flake8_pytest_style, flake8_raise, flake8_return, flake8_simplify, flake8_slots,
|
||||
flake8_tidy_imports, flake8_type_checking, mccabe, pandas_vet, pep8_naming, perflint,
|
||||
pycodestyle, pyflakes, pygrep_hooks, pylint, pyupgrade, refurb, ruff, tryceratops,
|
||||
};
|
||||
use crate::settings::types::PythonVersion;
|
||||
|
||||
|
@ -357,7 +357,7 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
|
|||
}
|
||||
}
|
||||
if checker.enabled(Rule::TrioAsyncFunctionWithTimeout) {
|
||||
flake8_trio::rules::async_function_with_timeout(checker, function_def);
|
||||
flake8_async::rules::async_function_with_timeout(checker, function_def);
|
||||
}
|
||||
if checker.enabled(Rule::ReimplementedOperator) {
|
||||
refurb::rules::reimplemented_operator(checker, &function_def.into());
|
||||
|
@ -1303,7 +1303,7 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
|
|||
pylint::rules::useless_with_lock(checker, with_stmt);
|
||||
}
|
||||
if checker.enabled(Rule::TrioTimeoutWithoutAwait) {
|
||||
flake8_trio::rules::timeout_without_await(checker, with_stmt, items);
|
||||
flake8_async::rules::timeout_without_await(checker, with_stmt, items);
|
||||
}
|
||||
}
|
||||
Stmt::While(while_stmt @ ast::StmtWhile { body, orelse, .. }) => {
|
||||
|
@ -1320,7 +1320,7 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
|
|||
perflint::rules::try_except_in_loop(checker, body);
|
||||
}
|
||||
if checker.enabled(Rule::TrioUnneededSleep) {
|
||||
flake8_trio::rules::unneeded_sleep(checker, while_stmt);
|
||||
flake8_async::rules::unneeded_sleep(checker, while_stmt);
|
||||
}
|
||||
}
|
||||
Stmt::For(
|
||||
|
|
|
@ -292,17 +292,18 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
|||
(Pylint, "W3301") => (RuleGroup::Stable, rules::pylint::rules::NestedMinMax),
|
||||
|
||||
// flake8-async
|
||||
(Flake8Async, "100") => (RuleGroup::Stable, rules::flake8_async::rules::BlockingHttpCallInAsyncFunction),
|
||||
(Flake8Async, "101") => (RuleGroup::Stable, rules::flake8_async::rules::OpenSleepOrSubprocessInAsyncFunction),
|
||||
(Flake8Async, "102") => (RuleGroup::Stable, rules::flake8_async::rules::BlockingOsCallInAsyncFunction),
|
||||
(Flake8Async, "100") => (RuleGroup::Stable, rules::flake8_async::rules::TrioTimeoutWithoutAwait),
|
||||
(Flake8Async, "105") => (RuleGroup::Stable, rules::flake8_async::rules::TrioSyncCall),
|
||||
(Flake8Async, "109") => (RuleGroup::Stable, rules::flake8_async::rules::TrioAsyncFunctionWithTimeout),
|
||||
(Flake8Async, "110") => (RuleGroup::Stable, rules::flake8_async::rules::TrioUnneededSleep),
|
||||
(Flake8Async, "115") => (RuleGroup::Stable, rules::flake8_async::rules::TrioZeroSleepCall),
|
||||
(Flake8Async, "116") => (RuleGroup::Preview, rules::flake8_async::rules::SleepForeverCall),
|
||||
|
||||
// flake8-trio
|
||||
(Flake8Trio, "100") => (RuleGroup::Stable, rules::flake8_trio::rules::TrioTimeoutWithoutAwait),
|
||||
(Flake8Trio, "105") => (RuleGroup::Stable, rules::flake8_trio::rules::TrioSyncCall),
|
||||
(Flake8Trio, "109") => (RuleGroup::Stable, rules::flake8_trio::rules::TrioAsyncFunctionWithTimeout),
|
||||
(Flake8Trio, "110") => (RuleGroup::Stable, rules::flake8_trio::rules::TrioUnneededSleep),
|
||||
(Flake8Trio, "115") => (RuleGroup::Stable, rules::flake8_trio::rules::TrioZeroSleepCall),
|
||||
(Flake8Async, "210") => (RuleGroup::Stable, rules::flake8_async::rules::BlockingHttpCallInAsyncFunction),
|
||||
(Flake8Async, "220") => (RuleGroup::Stable, rules::flake8_async::rules::CreateSubprocessInAsyncFunction),
|
||||
(Flake8Async, "221") => (RuleGroup::Stable, rules::flake8_async::rules::RunProcessInAsyncFunction),
|
||||
(Flake8Async, "222") => (RuleGroup::Stable, rules::flake8_async::rules::WaitForProcessInAsyncFunction),
|
||||
(Flake8Async, "230") => (RuleGroup::Stable, rules::flake8_async::rules::BlockingOpenCallInAsyncFunction),
|
||||
(Flake8Async, "251") => (RuleGroup::Stable, rules::flake8_async::rules::BlockingSleepInAsyncFunction),
|
||||
|
||||
// flake8-builtins
|
||||
(Flake8Builtins, "001") => (RuleGroup::Stable, rules::flake8_builtins::rules::BuiltinVariableShadowing),
|
||||
|
|
|
@ -64,9 +64,6 @@ pub enum Linter {
|
|||
/// [flake8-async](https://pypi.org/project/flake8-async/)
|
||||
#[prefix = "ASYNC"]
|
||||
Flake8Async,
|
||||
/// [flake8-trio](https://pypi.org/project/flake8-trio/)
|
||||
#[prefix = "TRIO"]
|
||||
Flake8Trio,
|
||||
/// [flake8-bandit](https://pypi.org/project/flake8-bandit/)
|
||||
#[prefix = "S"]
|
||||
Flake8Bandit,
|
||||
|
|
|
@ -103,6 +103,16 @@ static REDIRECTS: Lazy<HashMap<&'static str, &'static str>> = Lazy::new(|| {
|
|||
("TRY200", "B904"),
|
||||
("PGH001", "S307"),
|
||||
("PGH002", "G010"),
|
||||
// flake8-trio and flake8-async merged with name flake8-async
|
||||
("TRIO", "ASYNC1"),
|
||||
("TRIO1", "ASYNC1"),
|
||||
("TRIO10", "ASYNC10"),
|
||||
("TRIO100", "ASYNC100"),
|
||||
("TRIO105", "ASYNC105"),
|
||||
("TRIO109", "ASYNC109"),
|
||||
("TRIO11", "ASYNC11"),
|
||||
("TRIO110", "ASYNC110"),
|
||||
("TRIO115", "ASYNC115"),
|
||||
// Removed in v0.5
|
||||
("PLR1701", "SIM101"),
|
||||
// Test redirect by exact code
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
//! Rules from [flake8-async](https://pypi.org/project/flake8-async/).
|
||||
mod helpers;
|
||||
pub(crate) mod rules;
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -13,10 +14,18 @@ mod tests {
|
|||
use crate::settings::LinterSettings;
|
||||
use crate::test::test_path;
|
||||
|
||||
#[test_case(Rule::BlockingHttpCallInAsyncFunction, Path::new("ASYNC100.py"))]
|
||||
#[test_case(Rule::OpenSleepOrSubprocessInAsyncFunction, Path::new("ASYNC101.py"))]
|
||||
#[test_case(Rule::BlockingOsCallInAsyncFunction, Path::new("ASYNC102.py"))]
|
||||
#[test_case(Rule::TrioTimeoutWithoutAwait, Path::new("ASYNC100.py"))]
|
||||
#[test_case(Rule::TrioSyncCall, Path::new("ASYNC105.py"))]
|
||||
#[test_case(Rule::TrioAsyncFunctionWithTimeout, Path::new("ASYNC109.py"))]
|
||||
#[test_case(Rule::TrioUnneededSleep, Path::new("ASYNC110.py"))]
|
||||
#[test_case(Rule::TrioZeroSleepCall, Path::new("ASYNC115.py"))]
|
||||
#[test_case(Rule::SleepForeverCall, Path::new("ASYNC116.py"))]
|
||||
#[test_case(Rule::BlockingHttpCallInAsyncFunction, Path::new("ASYNC210.py"))]
|
||||
#[test_case(Rule::CreateSubprocessInAsyncFunction, Path::new("ASYNC22x.py"))]
|
||||
#[test_case(Rule::RunProcessInAsyncFunction, Path::new("ASYNC22x.py"))]
|
||||
#[test_case(Rule::WaitForProcessInAsyncFunction, Path::new("ASYNC22x.py"))]
|
||||
#[test_case(Rule::BlockingOpenCallInAsyncFunction, Path::new("ASYNC230.py"))]
|
||||
#[test_case(Rule::BlockingSleepInAsyncFunction, Path::new("ASYNC251.py"))]
|
||||
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
|
||||
let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy());
|
||||
let diagnostics = test_path(
|
||||
|
|
|
@ -40,7 +40,7 @@ impl Violation for TrioAsyncFunctionWithTimeout {
|
|||
}
|
||||
}
|
||||
|
||||
/// TRIO109
|
||||
/// ASYNC109
|
||||
pub(crate) fn async_function_with_timeout(
|
||||
checker: &mut Checker,
|
||||
function_def: &ast::StmtFunctionDef,
|
|
@ -45,6 +45,7 @@ fn is_blocking_http_call(qualified_name: &QualifiedName) -> bool {
|
|||
matches!(
|
||||
qualified_name.segments(),
|
||||
["urllib", "request", "urlopen"]
|
||||
| ["urllib3", "request"]
|
||||
| [
|
||||
"httpx" | "requests",
|
||||
"get"
|
||||
|
@ -60,7 +61,7 @@ fn is_blocking_http_call(qualified_name: &QualifiedName) -> bool {
|
|||
)
|
||||
}
|
||||
|
||||
/// ASYNC100
|
||||
/// ASYNC210
|
||||
pub(crate) fn blocking_http_call(checker: &mut Checker, call: &ExprCall) {
|
||||
if checker.semantic().in_async_context() {
|
||||
if checker
|
||||
|
|
|
@ -7,8 +7,7 @@ use ruff_text_size::Ranged;
|
|||
use crate::checkers::ast::Checker;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks that async functions do not contain calls to `open`, `time.sleep`,
|
||||
/// or `subprocess` methods.
|
||||
/// Checks that async functions do not open files with blocking methods like `open`.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Blocking an async function via a blocking call will block the entire
|
||||
|
@ -21,61 +20,53 @@ use crate::checkers::ast::Checker;
|
|||
/// ## Example
|
||||
/// ```python
|
||||
/// async def foo():
|
||||
/// time.sleep(1000)
|
||||
/// with open("bar.txt") as f:
|
||||
/// contents = f.read()
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// import anyio
|
||||
///
|
||||
///
|
||||
/// async def foo():
|
||||
/// await asyncio.sleep(1000)
|
||||
/// async with await anyio.open_file("bar.txt") as f:
|
||||
/// contents = await f.read()
|
||||
/// ```
|
||||
#[violation]
|
||||
pub struct OpenSleepOrSubprocessInAsyncFunction;
|
||||
pub struct BlockingOpenCallInAsyncFunction;
|
||||
|
||||
impl Violation for OpenSleepOrSubprocessInAsyncFunction {
|
||||
impl Violation for BlockingOpenCallInAsyncFunction {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Async functions should not call `open`, `time.sleep`, or `subprocess` methods")
|
||||
format!("Async functions should not open files with blocking methods like `open`")
|
||||
}
|
||||
}
|
||||
|
||||
/// ASYNC101
|
||||
pub(crate) fn open_sleep_or_subprocess_call(checker: &mut Checker, call: &ast::ExprCall) {
|
||||
/// ASYNC230
|
||||
pub(crate) fn blocking_open_call(checker: &mut Checker, call: &ast::ExprCall) {
|
||||
if !checker.semantic().in_async_context() {
|
||||
return;
|
||||
}
|
||||
|
||||
if is_open_sleep_or_subprocess_call(&call.func, checker.semantic())
|
||||
if is_open_call(&call.func, checker.semantic())
|
||||
|| is_open_call_from_pathlib(call.func.as_ref(), checker.semantic())
|
||||
{
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
OpenSleepOrSubprocessInAsyncFunction,
|
||||
BlockingOpenCallInAsyncFunction,
|
||||
call.func.range(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the expression resolves to a blocking call, like `time.sleep` or
|
||||
/// `subprocess.run`.
|
||||
fn is_open_sleep_or_subprocess_call(func: &Expr, semantic: &SemanticModel) -> bool {
|
||||
/// Returns `true` if the expression resolves to a blocking open call, like `open` or `Path().open()`.
|
||||
fn is_open_call(func: &Expr, semantic: &SemanticModel) -> bool {
|
||||
semantic
|
||||
.resolve_qualified_name(func)
|
||||
.is_some_and(|qualified_name| {
|
||||
matches!(
|
||||
qualified_name.segments(),
|
||||
["" | "builtins", "open"]
|
||||
| ["time", "sleep"]
|
||||
| [
|
||||
"subprocess",
|
||||
"run"
|
||||
| "Popen"
|
||||
| "call"
|
||||
| "check_call"
|
||||
| "check_output"
|
||||
| "getoutput"
|
||||
| "getstatusoutput"
|
||||
]
|
||||
| ["os", "wait" | "wait3" | "wait4" | "waitid" | "waitpid"]
|
||||
["" | "io", "open"] | ["io", "open_code"]
|
||||
)
|
||||
})
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
use ruff_python_ast::ExprCall;
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
use ruff_python_ast::name::QualifiedName;
|
||||
use ruff_python_semantic::Modules;
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks that async functions do not contain calls to blocking synchronous
|
||||
/// process calls via the `os` module.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Blocking an async function via a blocking call will block the entire
|
||||
/// event loop, preventing it from executing other tasks while waiting for the
|
||||
/// call to complete, negating the benefits of asynchronous programming.
|
||||
///
|
||||
/// Instead of making a blocking call, use an equivalent asynchronous library
|
||||
/// or function.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// async def foo():
|
||||
/// os.popen()
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// def foo():
|
||||
/// os.popen()
|
||||
/// ```
|
||||
#[violation]
|
||||
pub struct BlockingOsCallInAsyncFunction;
|
||||
|
||||
impl Violation for BlockingOsCallInAsyncFunction {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Async functions should not call synchronous `os` methods")
|
||||
}
|
||||
}
|
||||
|
||||
/// ASYNC102
|
||||
pub(crate) fn blocking_os_call(checker: &mut Checker, call: &ExprCall) {
|
||||
if checker.semantic().seen_module(Modules::OS) {
|
||||
if checker.semantic().in_async_context() {
|
||||
if checker
|
||||
.semantic()
|
||||
.resolve_qualified_name(call.func.as_ref())
|
||||
.as_ref()
|
||||
.is_some_and(is_unsafe_os_method)
|
||||
{
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
BlockingOsCallInAsyncFunction,
|
||||
call.func.range(),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_unsafe_os_method(qualified_name: &QualifiedName) -> bool {
|
||||
matches!(
|
||||
qualified_name.segments(),
|
||||
[
|
||||
"os",
|
||||
"popen"
|
||||
| "posix_spawn"
|
||||
| "posix_spawnp"
|
||||
| "spawnl"
|
||||
| "spawnle"
|
||||
| "spawnlp"
|
||||
| "spawnlpe"
|
||||
| "spawnv"
|
||||
| "spawnve"
|
||||
| "spawnvp"
|
||||
| "spawnvpe"
|
||||
| "system"
|
||||
]
|
||||
)
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
use ruff_diagnostics::{Diagnostic, DiagnosticKind, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
use ruff_python_ast::{self as ast, Expr};
|
||||
use ruff_python_semantic::analyze::typing::find_assigned_value;
|
||||
use ruff_python_semantic::SemanticModel;
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::registry::AsRule;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks that async functions do not create subprocesses with blocking methods.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Blocking an async function via a blocking call will block the entire
|
||||
/// event loop, preventing it from executing other tasks while waiting for the
|
||||
/// call to complete, negating the benefits of asynchronous programming.
|
||||
///
|
||||
/// Instead of making a blocking call, use an equivalent asynchronous library
|
||||
/// or function.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// async def foo():
|
||||
/// os.popen(cmd)
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// async def foo():
|
||||
/// asyncio.create_subprocess_shell(cmd)
|
||||
/// ```
|
||||
#[violation]
|
||||
pub struct CreateSubprocessInAsyncFunction;
|
||||
|
||||
impl Violation for CreateSubprocessInAsyncFunction {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Async functions should not create subprocesses with blocking methods")
|
||||
}
|
||||
}
|
||||
|
||||
/// ## What it does
|
||||
/// Checks that async functions do not run processes with blocking methods.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Blocking an async function via a blocking call will block the entire
|
||||
/// event loop, preventing it from executing other tasks while waiting for the
|
||||
/// call to complete, negating the benefits of asynchronous programming.
|
||||
///
|
||||
/// Instead of making a blocking call, use an equivalent asynchronous library
|
||||
/// or function.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// async def foo():
|
||||
/// subprocess.run(cmd)
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// async def foo():
|
||||
/// asyncio.create_subprocess_shell(cmd)
|
||||
/// ```
|
||||
#[violation]
|
||||
pub struct RunProcessInAsyncFunction;
|
||||
|
||||
impl Violation for RunProcessInAsyncFunction {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Async functions should not run processes with blocking methods")
|
||||
}
|
||||
}
|
||||
|
||||
/// ## What it does
|
||||
/// Checks that async functions do not wait on processes with blocking methods.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Blocking an async function via a blocking call will block the entire
|
||||
/// event loop, preventing it from executing other tasks while waiting for the
|
||||
/// call to complete, negating the benefits of asynchronous programming.
|
||||
///
|
||||
/// Instead of making a blocking call, use an equivalent asynchronous library
|
||||
/// or function.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// async def foo():
|
||||
/// os.waitpid(0)
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// def wait_for_process():
|
||||
/// os.waitpid(0)
|
||||
///
|
||||
///
|
||||
/// async def foo():
|
||||
/// await asyncio.loop.run_in_executor(None, wait_for_process)
|
||||
/// ```
|
||||
#[violation]
|
||||
pub struct WaitForProcessInAsyncFunction;
|
||||
|
||||
impl Violation for WaitForProcessInAsyncFunction {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Async functions should not wait on processes with blocking methods")
|
||||
}
|
||||
}
|
||||
|
||||
/// ASYNC220, ASYNC221, ASYNC222
|
||||
pub(crate) fn blocking_process_invocation(checker: &mut Checker, call: &ast::ExprCall) {
|
||||
if !checker.semantic().in_async_context() {
|
||||
return;
|
||||
}
|
||||
|
||||
let Some(diagnostic_kind) =
|
||||
checker
|
||||
.semantic()
|
||||
.resolve_qualified_name(call.func.as_ref())
|
||||
.and_then(|qualified_name| match qualified_name.segments() {
|
||||
["subprocess", "Popen"] | ["os", "popen"] => {
|
||||
Some(CreateSubprocessInAsyncFunction.into())
|
||||
}
|
||||
["os", "system" | "posix_spawn" | "posix_spawnp"]
|
||||
| ["subprocess", "run" | "call" | "check_call" | "check_output" | "getoutput"
|
||||
| "getstatusoutput"] => Some(RunProcessInAsyncFunction.into()),
|
||||
["os", "wait" | "wait3" | "wait4" | "waitid" | "waitpid"] => {
|
||||
Some(WaitForProcessInAsyncFunction.into())
|
||||
}
|
||||
["os", "spawnl" | "spawnle" | "spawnlp" | "spawnlpe" | "spawnv" | "spawnve"
|
||||
| "spawnvp" | "spawnvpe"] => {
|
||||
if is_p_wait(call, checker.semantic()) {
|
||||
Some(RunProcessInAsyncFunction.into())
|
||||
} else {
|
||||
Some(CreateSubprocessInAsyncFunction.into())
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
else {
|
||||
return;
|
||||
};
|
||||
let diagnostic = Diagnostic::new::<DiagnosticKind>(diagnostic_kind, call.func.range());
|
||||
if checker.enabled(diagnostic.kind.rule()) {
|
||||
checker.diagnostics.push(diagnostic);
|
||||
}
|
||||
}
|
||||
|
||||
fn is_p_wait(call: &ast::ExprCall, semantic: &SemanticModel) -> bool {
|
||||
let Some(arg) = call.arguments.find_argument("mode", 0) else {
|
||||
return true;
|
||||
};
|
||||
|
||||
if let Some(qualified_name) = semantic.resolve_qualified_name(arg) {
|
||||
return matches!(qualified_name.segments(), ["os", "P_WAIT"]);
|
||||
} else if let Expr::Name(ast::ExprName { id, .. }) = arg {
|
||||
let Some(value) = find_assigned_value(id, semantic) else {
|
||||
return false;
|
||||
};
|
||||
if let Some(qualified_name) = semantic.resolve_qualified_name(value) {
|
||||
return matches!(qualified_name.segments(), ["os", "P_WAIT"]);
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
use ruff_python_ast::ExprCall;
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
use ruff_python_ast::name::QualifiedName;
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks that async functions do not call `time.sleep`.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Blocking an async function via a `time.sleep` call will block the entire
|
||||
/// event loop, preventing it from executing other tasks while waiting for the
|
||||
/// `time.sleep`, negating the benefits of asynchronous programming.
|
||||
///
|
||||
/// Instead of `time.sleep`, use `asyncio.sleep`.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// async def fetch():
|
||||
/// time.sleep(1)
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// async def fetch():
|
||||
/// await asyncio.sleep(1)
|
||||
/// ```
|
||||
#[violation]
|
||||
pub struct BlockingSleepInAsyncFunction;
|
||||
|
||||
impl Violation for BlockingSleepInAsyncFunction {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Async functions should not call `time.sleep`")
|
||||
}
|
||||
}
|
||||
|
||||
fn is_blocking_sleep(qualified_name: &QualifiedName) -> bool {
|
||||
matches!(qualified_name.segments(), ["time", "sleep"])
|
||||
}
|
||||
|
||||
/// ASYNC251
|
||||
pub(crate) fn blocking_sleep(checker: &mut Checker, call: &ExprCall) {
|
||||
if checker.semantic().in_async_context() {
|
||||
if checker
|
||||
.semantic()
|
||||
.resolve_qualified_name(call.func.as_ref())
|
||||
.as_ref()
|
||||
.is_some_and(is_blocking_sleep)
|
||||
{
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
BlockingSleepInAsyncFunction,
|
||||
call.func.range(),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,9 +1,21 @@
|
|||
pub(crate) use async_function_with_timeout::*;
|
||||
pub(crate) use blocking_http_call::*;
|
||||
pub(crate) use blocking_os_call::*;
|
||||
pub(crate) use open_sleep_or_subprocess_call::*;
|
||||
pub(crate) use blocking_open_call::*;
|
||||
pub(crate) use blocking_process_invocation::*;
|
||||
pub(crate) use blocking_sleep::*;
|
||||
pub(crate) use sleep_forever_call::*;
|
||||
pub(crate) use sync_call::*;
|
||||
pub(crate) use timeout_without_await::*;
|
||||
pub(crate) use unneeded_sleep::*;
|
||||
pub(crate) use zero_sleep_call::*;
|
||||
|
||||
mod async_function_with_timeout;
|
||||
mod blocking_http_call;
|
||||
mod blocking_os_call;
|
||||
mod open_sleep_or_subprocess_call;
|
||||
mod blocking_open_call;
|
||||
mod blocking_process_invocation;
|
||||
mod blocking_sleep;
|
||||
mod sleep_forever_call;
|
||||
mod sync_call;
|
||||
mod timeout_without_await;
|
||||
mod unneeded_sleep;
|
||||
mod zero_sleep_call;
|
||||
|
|
|
@ -6,7 +6,7 @@ use ruff_text_size::{Ranged, TextRange};
|
|||
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::fix::edits::pad;
|
||||
use crate::rules::flake8_trio::method_name::MethodName;
|
||||
use crate::rules::flake8_async::helpers::MethodName;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for calls to trio functions that are not immediately awaited.
|
||||
|
@ -50,7 +50,7 @@ impl Violation for TrioSyncCall {
|
|||
}
|
||||
}
|
||||
|
||||
/// TRIO105
|
||||
/// ASYNC105
|
||||
pub(crate) fn sync_call(checker: &mut Checker, call: &ExprCall) {
|
||||
if !checker.semantic().seen_module(Modules::TRIO) {
|
||||
return;
|
|
@ -6,7 +6,7 @@ use ruff_python_ast::{StmtWith, WithItem};
|
|||
use ruff_python_semantic::Modules;
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::rules::flake8_trio::method_name::MethodName;
|
||||
use crate::rules::flake8_async::helpers::MethodName;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for trio functions that should contain await but don't.
|
||||
|
@ -44,7 +44,7 @@ impl Violation for TrioTimeoutWithoutAwait {
|
|||
}
|
||||
}
|
||||
|
||||
/// TRIO100
|
||||
/// ASYNC100
|
||||
pub(crate) fn timeout_without_await(
|
||||
checker: &mut Checker,
|
||||
with_stmt: &StmtWith,
|
|
@ -41,7 +41,7 @@ impl Violation for TrioUnneededSleep {
|
|||
}
|
||||
}
|
||||
|
||||
/// TRIO110
|
||||
/// ASYNC110
|
||||
pub(crate) fn unneeded_sleep(checker: &mut Checker, while_stmt: &ast::StmtWhile) {
|
||||
if !checker.semantic().seen_module(Modules::TRIO) {
|
||||
return;
|
|
@ -45,7 +45,7 @@ impl AlwaysFixableViolation for TrioZeroSleepCall {
|
|||
}
|
||||
}
|
||||
|
||||
/// TRIO115
|
||||
/// ASYNC115
|
||||
pub(crate) fn zero_sleep_call(checker: &mut Checker, call: &ExprCall) {
|
||||
if !checker.semantic().seen_module(Modules::TRIO) {
|
||||
return;
|
|
@ -1,39 +1,20 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_async/mod.rs
|
||||
---
|
||||
ASYNC100.py:7:5: ASYNC100 Async functions should not call blocking HTTP methods
|
||||
ASYNC100.py:5:5: ASYNC100 A `with trio.fail_after(...):` context does not contain any `await` statements. This makes it pointless, as the timeout can only be triggered by a checkpoint.
|
||||
|
|
||||
6 | async def foo():
|
||||
7 | urllib.request.urlopen("http://example.com/foo/bar").read()
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ ASYNC100
|
||||
4 | async def func():
|
||||
5 | with trio.fail_after():
|
||||
| _____^
|
||||
6 | | ...
|
||||
| |___________^ ASYNC100
|
||||
|
|
||||
|
||||
ASYNC100.py:11:5: ASYNC100 Async functions should not call blocking HTTP methods
|
||||
ASYNC100.py:15:5: ASYNC100 A `with trio.move_on_after(...):` context does not contain any `await` statements. This makes it pointless, as the timeout can only be triggered by a checkpoint.
|
||||
|
|
||||
10 | async def foo():
|
||||
11 | requests.get()
|
||||
| ^^^^^^^^^^^^ ASYNC100
|
||||
14 | async def func():
|
||||
15 | with trio.move_on_after():
|
||||
| _____^
|
||||
16 | | ...
|
||||
| |___________^ ASYNC100
|
||||
|
|
||||
|
||||
ASYNC100.py:15:5: ASYNC100 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
14 | async def foo():
|
||||
15 | httpx.get()
|
||||
| ^^^^^^^^^ ASYNC100
|
||||
|
|
||||
|
||||
ASYNC100.py:19:5: ASYNC100 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
18 | async def foo():
|
||||
19 | requests.post()
|
||||
| ^^^^^^^^^^^^^ ASYNC100
|
||||
|
|
||||
|
||||
ASYNC100.py:23:5: ASYNC100 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
22 | async def foo():
|
||||
23 | httpx.post()
|
||||
| ^^^^^^^^^^ ASYNC100
|
||||
|
|
||||
|
||||
|
||||
|
|
|
@ -1,84 +0,0 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_async/mod.rs
|
||||
---
|
||||
ASYNC101.py:10:5: ASYNC101 Async functions should not call `open`, `time.sleep`, or `subprocess` methods
|
||||
|
|
||||
9 | async def func():
|
||||
10 | open("foo")
|
||||
| ^^^^ ASYNC101
|
||||
|
|
||||
|
||||
ASYNC101.py:14:5: ASYNC101 Async functions should not call `open`, `time.sleep`, or `subprocess` methods
|
||||
|
|
||||
13 | async def func():
|
||||
14 | time.sleep(1)
|
||||
| ^^^^^^^^^^ ASYNC101
|
||||
|
|
||||
|
||||
ASYNC101.py:18:5: ASYNC101 Async functions should not call `open`, `time.sleep`, or `subprocess` methods
|
||||
|
|
||||
17 | async def func():
|
||||
18 | subprocess.run("foo")
|
||||
| ^^^^^^^^^^^^^^ ASYNC101
|
||||
|
|
||||
|
||||
ASYNC101.py:22:5: ASYNC101 Async functions should not call `open`, `time.sleep`, or `subprocess` methods
|
||||
|
|
||||
21 | async def func():
|
||||
22 | subprocess.call("foo")
|
||||
| ^^^^^^^^^^^^^^^ ASYNC101
|
||||
|
|
||||
|
||||
ASYNC101.py:30:5: ASYNC101 Async functions should not call `open`, `time.sleep`, or `subprocess` methods
|
||||
|
|
||||
29 | async def func():
|
||||
30 | os.wait4(10)
|
||||
| ^^^^^^^^ ASYNC101
|
||||
|
|
||||
|
||||
ASYNC101.py:34:5: ASYNC101 Async functions should not call `open`, `time.sleep`, or `subprocess` methods
|
||||
|
|
||||
33 | async def func():
|
||||
34 | os.wait(12)
|
||||
| ^^^^^^^ ASYNC101
|
||||
|
|
||||
|
||||
ASYNC101.py:41:5: ASYNC101 Async functions should not call `open`, `time.sleep`, or `subprocess` methods
|
||||
|
|
||||
40 | async def func():
|
||||
41 | Path("foo").open() # ASYNC101
|
||||
| ^^^^^^^^^^^^^^^^ ASYNC101
|
||||
|
|
||||
|
||||
ASYNC101.py:46:5: ASYNC101 Async functions should not call `open`, `time.sleep`, or `subprocess` methods
|
||||
|
|
||||
44 | async def func():
|
||||
45 | p = Path("foo")
|
||||
46 | p.open() # ASYNC101
|
||||
| ^^^^^^ ASYNC101
|
||||
|
|
||||
|
||||
ASYNC101.py:50:10: ASYNC101 Async functions should not call `open`, `time.sleep`, or `subprocess` methods
|
||||
|
|
||||
49 | async def func():
|
||||
50 | with Path("foo").open() as f: # ASYNC101
|
||||
| ^^^^^^^^^^^^^^^^ ASYNC101
|
||||
51 | pass
|
||||
|
|
||||
|
||||
ASYNC101.py:58:9: ASYNC101 Async functions should not call `open`, `time.sleep`, or `subprocess` methods
|
||||
|
|
||||
57 | async def bar():
|
||||
58 | p.open() # ASYNC101
|
||||
| ^^^^^^ ASYNC101
|
||||
|
|
||||
|
||||
ASYNC101.py:64:5: ASYNC101 Async functions should not call `open`, `time.sleep`, or `subprocess` methods
|
||||
|
|
||||
62 | (p1, p2) = (Path("foo"), Path("bar"))
|
||||
63 |
|
||||
64 | p1.open() # ASYNC101
|
||||
| ^^^^^^^ ASYNC101
|
||||
|
|
||||
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_async/mod.rs
|
||||
---
|
||||
ASYNC102.py:5:5: ASYNC102 Async functions should not call synchronous `os` methods
|
||||
|
|
||||
4 | async def foo():
|
||||
5 | os.popen()
|
||||
| ^^^^^^^^ ASYNC102
|
||||
|
|
||||
|
||||
ASYNC102.py:9:5: ASYNC102 Async functions should not call synchronous `os` methods
|
||||
|
|
||||
8 | async def foo():
|
||||
9 | os.spawnl()
|
||||
| ^^^^^^^^^ ASYNC102
|
||||
|
|
||||
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_trio/mod.rs
|
||||
source: crates/ruff_linter/src/rules/flake8_async/mod.rs
|
||||
---
|
||||
TRIO105.py:30:5: TRIO105 [*] Call to `trio.aclose_forcefully` is not immediately awaited
|
||||
ASYNC105.py:30:5: ASYNC105 [*] Call to `trio.aclose_forcefully` is not immediately awaited
|
||||
|
|
||||
29 | # TRIO105
|
||||
29 | # ASYNC105
|
||||
30 | trio.aclose_forcefully(foo)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRIO105
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ASYNC105
|
||||
31 | trio.open_file(foo)
|
||||
32 | trio.open_ssl_over_tcp_listeners(foo, foo)
|
||||
|
|
||||
|
@ -14,19 +14,19 @@ TRIO105.py:30:5: TRIO105 [*] Call to `trio.aclose_forcefully` is not immediately
|
|||
ℹ Unsafe fix
|
||||
27 27 | await trio.lowlevel.wait_writable(foo)
|
||||
28 28 |
|
||||
29 29 | # TRIO105
|
||||
29 29 | # ASYNC105
|
||||
30 |- trio.aclose_forcefully(foo)
|
||||
30 |+ await trio.aclose_forcefully(foo)
|
||||
31 31 | trio.open_file(foo)
|
||||
32 32 | trio.open_ssl_over_tcp_listeners(foo, foo)
|
||||
33 33 | trio.open_ssl_over_tcp_stream(foo, foo)
|
||||
|
||||
TRIO105.py:31:5: TRIO105 [*] Call to `trio.open_file` is not immediately awaited
|
||||
ASYNC105.py:31:5: ASYNC105 [*] Call to `trio.open_file` is not immediately awaited
|
||||
|
|
||||
29 | # TRIO105
|
||||
29 | # ASYNC105
|
||||
30 | trio.aclose_forcefully(foo)
|
||||
31 | trio.open_file(foo)
|
||||
| ^^^^^^^^^^^^^^^^^^^ TRIO105
|
||||
| ^^^^^^^^^^^^^^^^^^^ ASYNC105
|
||||
32 | trio.open_ssl_over_tcp_listeners(foo, foo)
|
||||
33 | trio.open_ssl_over_tcp_stream(foo, foo)
|
||||
|
|
||||
|
@ -34,7 +34,7 @@ TRIO105.py:31:5: TRIO105 [*] Call to `trio.open_file` is not immediately awaited
|
|||
|
||||
ℹ Unsafe fix
|
||||
28 28 |
|
||||
29 29 | # TRIO105
|
||||
29 29 | # ASYNC105
|
||||
30 30 | trio.aclose_forcefully(foo)
|
||||
31 |- trio.open_file(foo)
|
||||
31 |+ await trio.open_file(foo)
|
||||
|
@ -42,19 +42,19 @@ TRIO105.py:31:5: TRIO105 [*] Call to `trio.open_file` is not immediately awaited
|
|||
33 33 | trio.open_ssl_over_tcp_stream(foo, foo)
|
||||
34 34 | trio.open_tcp_listeners(foo)
|
||||
|
||||
TRIO105.py:32:5: TRIO105 [*] Call to `trio.open_ssl_over_tcp_listeners` is not immediately awaited
|
||||
ASYNC105.py:32:5: ASYNC105 [*] Call to `trio.open_ssl_over_tcp_listeners` is not immediately awaited
|
||||
|
|
||||
30 | trio.aclose_forcefully(foo)
|
||||
31 | trio.open_file(foo)
|
||||
32 | trio.open_ssl_over_tcp_listeners(foo, foo)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRIO105
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ASYNC105
|
||||
33 | trio.open_ssl_over_tcp_stream(foo, foo)
|
||||
34 | trio.open_tcp_listeners(foo)
|
||||
|
|
||||
= help: Add `await`
|
||||
|
||||
ℹ Unsafe fix
|
||||
29 29 | # TRIO105
|
||||
29 29 | # ASYNC105
|
||||
30 30 | trio.aclose_forcefully(foo)
|
||||
31 31 | trio.open_file(foo)
|
||||
32 |- trio.open_ssl_over_tcp_listeners(foo, foo)
|
||||
|
@ -63,12 +63,12 @@ TRIO105.py:32:5: TRIO105 [*] Call to `trio.open_ssl_over_tcp_listeners` is not i
|
|||
34 34 | trio.open_tcp_listeners(foo)
|
||||
35 35 | trio.open_tcp_stream(foo, foo)
|
||||
|
||||
TRIO105.py:33:5: TRIO105 [*] Call to `trio.open_ssl_over_tcp_stream` is not immediately awaited
|
||||
ASYNC105.py:33:5: ASYNC105 [*] Call to `trio.open_ssl_over_tcp_stream` is not immediately awaited
|
||||
|
|
||||
31 | trio.open_file(foo)
|
||||
32 | trio.open_ssl_over_tcp_listeners(foo, foo)
|
||||
33 | trio.open_ssl_over_tcp_stream(foo, foo)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRIO105
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ASYNC105
|
||||
34 | trio.open_tcp_listeners(foo)
|
||||
35 | trio.open_tcp_stream(foo, foo)
|
||||
|
|
||||
|
@ -84,12 +84,12 @@ TRIO105.py:33:5: TRIO105 [*] Call to `trio.open_ssl_over_tcp_stream` is not imme
|
|||
35 35 | trio.open_tcp_stream(foo, foo)
|
||||
36 36 | trio.open_unix_socket(foo)
|
||||
|
||||
TRIO105.py:34:5: TRIO105 [*] Call to `trio.open_tcp_listeners` is not immediately awaited
|
||||
ASYNC105.py:34:5: ASYNC105 [*] Call to `trio.open_tcp_listeners` is not immediately awaited
|
||||
|
|
||||
32 | trio.open_ssl_over_tcp_listeners(foo, foo)
|
||||
33 | trio.open_ssl_over_tcp_stream(foo, foo)
|
||||
34 | trio.open_tcp_listeners(foo)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRIO105
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ASYNC105
|
||||
35 | trio.open_tcp_stream(foo, foo)
|
||||
36 | trio.open_unix_socket(foo)
|
||||
|
|
||||
|
@ -105,12 +105,12 @@ TRIO105.py:34:5: TRIO105 [*] Call to `trio.open_tcp_listeners` is not immediatel
|
|||
36 36 | trio.open_unix_socket(foo)
|
||||
37 37 | trio.run_process(foo)
|
||||
|
||||
TRIO105.py:35:5: TRIO105 [*] Call to `trio.open_tcp_stream` is not immediately awaited
|
||||
ASYNC105.py:35:5: ASYNC105 [*] Call to `trio.open_tcp_stream` is not immediately awaited
|
||||
|
|
||||
33 | trio.open_ssl_over_tcp_stream(foo, foo)
|
||||
34 | trio.open_tcp_listeners(foo)
|
||||
35 | trio.open_tcp_stream(foo, foo)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRIO105
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ASYNC105
|
||||
36 | trio.open_unix_socket(foo)
|
||||
37 | trio.run_process(foo)
|
||||
|
|
||||
|
@ -126,12 +126,12 @@ TRIO105.py:35:5: TRIO105 [*] Call to `trio.open_tcp_stream` is not immediately a
|
|||
37 37 | trio.run_process(foo)
|
||||
38 38 | trio.serve_listeners(foo, foo)
|
||||
|
||||
TRIO105.py:36:5: TRIO105 [*] Call to `trio.open_unix_socket` is not immediately awaited
|
||||
ASYNC105.py:36:5: ASYNC105 [*] Call to `trio.open_unix_socket` is not immediately awaited
|
||||
|
|
||||
34 | trio.open_tcp_listeners(foo)
|
||||
35 | trio.open_tcp_stream(foo, foo)
|
||||
36 | trio.open_unix_socket(foo)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ TRIO105
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ASYNC105
|
||||
37 | trio.run_process(foo)
|
||||
38 | trio.serve_listeners(foo, foo)
|
||||
|
|
||||
|
@ -147,12 +147,12 @@ TRIO105.py:36:5: TRIO105 [*] Call to `trio.open_unix_socket` is not immediately
|
|||
38 38 | trio.serve_listeners(foo, foo)
|
||||
39 39 | trio.serve_ssl_over_tcp(foo, foo, foo)
|
||||
|
||||
TRIO105.py:37:5: TRIO105 [*] Call to `trio.run_process` is not immediately awaited
|
||||
ASYNC105.py:37:5: ASYNC105 [*] Call to `trio.run_process` is not immediately awaited
|
||||
|
|
||||
35 | trio.open_tcp_stream(foo, foo)
|
||||
36 | trio.open_unix_socket(foo)
|
||||
37 | trio.run_process(foo)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ TRIO105
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ ASYNC105
|
||||
38 | trio.serve_listeners(foo, foo)
|
||||
39 | trio.serve_ssl_over_tcp(foo, foo, foo)
|
||||
|
|
||||
|
@ -168,12 +168,12 @@ TRIO105.py:37:5: TRIO105 [*] Call to `trio.run_process` is not immediately await
|
|||
39 39 | trio.serve_ssl_over_tcp(foo, foo, foo)
|
||||
40 40 | trio.serve_tcp(foo, foo)
|
||||
|
||||
TRIO105.py:38:5: TRIO105 [*] Call to `trio.serve_listeners` is not immediately awaited
|
||||
ASYNC105.py:38:5: ASYNC105 [*] Call to `trio.serve_listeners` is not immediately awaited
|
||||
|
|
||||
36 | trio.open_unix_socket(foo)
|
||||
37 | trio.run_process(foo)
|
||||
38 | trio.serve_listeners(foo, foo)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRIO105
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ASYNC105
|
||||
39 | trio.serve_ssl_over_tcp(foo, foo, foo)
|
||||
40 | trio.serve_tcp(foo, foo)
|
||||
|
|
||||
|
@ -189,12 +189,12 @@ TRIO105.py:38:5: TRIO105 [*] Call to `trio.serve_listeners` is not immediately a
|
|||
40 40 | trio.serve_tcp(foo, foo)
|
||||
41 41 | trio.sleep(foo)
|
||||
|
||||
TRIO105.py:39:5: TRIO105 [*] Call to `trio.serve_ssl_over_tcp` is not immediately awaited
|
||||
ASYNC105.py:39:5: ASYNC105 [*] Call to `trio.serve_ssl_over_tcp` is not immediately awaited
|
||||
|
|
||||
37 | trio.run_process(foo)
|
||||
38 | trio.serve_listeners(foo, foo)
|
||||
39 | trio.serve_ssl_over_tcp(foo, foo, foo)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRIO105
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ASYNC105
|
||||
40 | trio.serve_tcp(foo, foo)
|
||||
41 | trio.sleep(foo)
|
||||
|
|
||||
|
@ -210,12 +210,12 @@ TRIO105.py:39:5: TRIO105 [*] Call to `trio.serve_ssl_over_tcp` is not immediatel
|
|||
41 41 | trio.sleep(foo)
|
||||
42 42 | trio.sleep_forever()
|
||||
|
||||
TRIO105.py:40:5: TRIO105 [*] Call to `trio.serve_tcp` is not immediately awaited
|
||||
ASYNC105.py:40:5: ASYNC105 [*] Call to `trio.serve_tcp` is not immediately awaited
|
||||
|
|
||||
38 | trio.serve_listeners(foo, foo)
|
||||
39 | trio.serve_ssl_over_tcp(foo, foo, foo)
|
||||
40 | trio.serve_tcp(foo, foo)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ TRIO105
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ ASYNC105
|
||||
41 | trio.sleep(foo)
|
||||
42 | trio.sleep_forever()
|
||||
|
|
||||
|
@ -231,12 +231,12 @@ TRIO105.py:40:5: TRIO105 [*] Call to `trio.serve_tcp` is not immediately awaited
|
|||
42 42 | trio.sleep_forever()
|
||||
43 43 | trio.sleep_until(foo)
|
||||
|
||||
TRIO105.py:41:5: TRIO105 [*] Call to `trio.sleep` is not immediately awaited
|
||||
ASYNC105.py:41:5: ASYNC105 [*] Call to `trio.sleep` is not immediately awaited
|
||||
|
|
||||
39 | trio.serve_ssl_over_tcp(foo, foo, foo)
|
||||
40 | trio.serve_tcp(foo, foo)
|
||||
41 | trio.sleep(foo)
|
||||
| ^^^^^^^^^^^^^^^ TRIO105
|
||||
| ^^^^^^^^^^^^^^^ ASYNC105
|
||||
42 | trio.sleep_forever()
|
||||
43 | trio.sleep_until(foo)
|
||||
|
|
||||
|
@ -252,12 +252,12 @@ TRIO105.py:41:5: TRIO105 [*] Call to `trio.sleep` is not immediately awaited
|
|||
43 43 | trio.sleep_until(foo)
|
||||
44 44 | trio.lowlevel.cancel_shielded_checkpoint()
|
||||
|
||||
TRIO105.py:42:5: TRIO105 [*] Call to `trio.sleep_forever` is not immediately awaited
|
||||
ASYNC105.py:42:5: ASYNC105 [*] Call to `trio.sleep_forever` is not immediately awaited
|
||||
|
|
||||
40 | trio.serve_tcp(foo, foo)
|
||||
41 | trio.sleep(foo)
|
||||
42 | trio.sleep_forever()
|
||||
| ^^^^^^^^^^^^^^^^^^^^ TRIO105
|
||||
| ^^^^^^^^^^^^^^^^^^^^ ASYNC105
|
||||
43 | trio.sleep_until(foo)
|
||||
44 | trio.lowlevel.cancel_shielded_checkpoint()
|
||||
|
|
||||
|
@ -273,12 +273,12 @@ TRIO105.py:42:5: TRIO105 [*] Call to `trio.sleep_forever` is not immediately awa
|
|||
44 44 | trio.lowlevel.cancel_shielded_checkpoint()
|
||||
45 45 | trio.lowlevel.checkpoint()
|
||||
|
||||
TRIO105.py:44:5: TRIO105 [*] Call to `trio.lowlevel.cancel_shielded_checkpoint` is not immediately awaited
|
||||
ASYNC105.py:44:5: ASYNC105 [*] Call to `trio.lowlevel.cancel_shielded_checkpoint` is not immediately awaited
|
||||
|
|
||||
42 | trio.sleep_forever()
|
||||
43 | trio.sleep_until(foo)
|
||||
44 | trio.lowlevel.cancel_shielded_checkpoint()
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRIO105
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ASYNC105
|
||||
45 | trio.lowlevel.checkpoint()
|
||||
46 | trio.lowlevel.checkpoint_if_cancelled()
|
||||
|
|
||||
|
@ -294,12 +294,12 @@ TRIO105.py:44:5: TRIO105 [*] Call to `trio.lowlevel.cancel_shielded_checkpoint`
|
|||
46 46 | trio.lowlevel.checkpoint_if_cancelled()
|
||||
47 47 | trio.lowlevel.open_process()
|
||||
|
||||
TRIO105.py:45:5: TRIO105 [*] Call to `trio.lowlevel.checkpoint` is not immediately awaited
|
||||
ASYNC105.py:45:5: ASYNC105 [*] Call to `trio.lowlevel.checkpoint` is not immediately awaited
|
||||
|
|
||||
43 | trio.sleep_until(foo)
|
||||
44 | trio.lowlevel.cancel_shielded_checkpoint()
|
||||
45 | trio.lowlevel.checkpoint()
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ TRIO105
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ASYNC105
|
||||
46 | trio.lowlevel.checkpoint_if_cancelled()
|
||||
47 | trio.lowlevel.open_process()
|
||||
|
|
||||
|
@ -315,12 +315,12 @@ TRIO105.py:45:5: TRIO105 [*] Call to `trio.lowlevel.checkpoint` is not immediate
|
|||
47 47 | trio.lowlevel.open_process()
|
||||
48 48 | trio.lowlevel.permanently_detach_coroutine_object(foo)
|
||||
|
||||
TRIO105.py:46:5: TRIO105 [*] Call to `trio.lowlevel.checkpoint_if_cancelled` is not immediately awaited
|
||||
ASYNC105.py:46:5: ASYNC105 [*] Call to `trio.lowlevel.checkpoint_if_cancelled` is not immediately awaited
|
||||
|
|
||||
44 | trio.lowlevel.cancel_shielded_checkpoint()
|
||||
45 | trio.lowlevel.checkpoint()
|
||||
46 | trio.lowlevel.checkpoint_if_cancelled()
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRIO105
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ASYNC105
|
||||
47 | trio.lowlevel.open_process()
|
||||
48 | trio.lowlevel.permanently_detach_coroutine_object(foo)
|
||||
|
|
||||
|
@ -336,12 +336,12 @@ TRIO105.py:46:5: TRIO105 [*] Call to `trio.lowlevel.checkpoint_if_cancelled` is
|
|||
48 48 | trio.lowlevel.permanently_detach_coroutine_object(foo)
|
||||
49 49 | trio.lowlevel.reattach_detached_coroutine_object(foo, foo)
|
||||
|
||||
TRIO105.py:47:5: TRIO105 [*] Call to `trio.lowlevel.open_process` is not immediately awaited
|
||||
ASYNC105.py:47:5: ASYNC105 [*] Call to `trio.lowlevel.open_process` is not immediately awaited
|
||||
|
|
||||
45 | trio.lowlevel.checkpoint()
|
||||
46 | trio.lowlevel.checkpoint_if_cancelled()
|
||||
47 | trio.lowlevel.open_process()
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRIO105
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ASYNC105
|
||||
48 | trio.lowlevel.permanently_detach_coroutine_object(foo)
|
||||
49 | trio.lowlevel.reattach_detached_coroutine_object(foo, foo)
|
||||
|
|
||||
|
@ -357,12 +357,12 @@ TRIO105.py:47:5: TRIO105 [*] Call to `trio.lowlevel.open_process` is not immedia
|
|||
49 49 | trio.lowlevel.reattach_detached_coroutine_object(foo, foo)
|
||||
50 50 | trio.lowlevel.temporarily_detach_coroutine_object(foo)
|
||||
|
||||
TRIO105.py:48:5: TRIO105 [*] Call to `trio.lowlevel.permanently_detach_coroutine_object` is not immediately awaited
|
||||
ASYNC105.py:48:5: ASYNC105 [*] Call to `trio.lowlevel.permanently_detach_coroutine_object` is not immediately awaited
|
||||
|
|
||||
46 | trio.lowlevel.checkpoint_if_cancelled()
|
||||
47 | trio.lowlevel.open_process()
|
||||
48 | trio.lowlevel.permanently_detach_coroutine_object(foo)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRIO105
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ASYNC105
|
||||
49 | trio.lowlevel.reattach_detached_coroutine_object(foo, foo)
|
||||
50 | trio.lowlevel.temporarily_detach_coroutine_object(foo)
|
||||
|
|
||||
|
@ -378,12 +378,12 @@ TRIO105.py:48:5: TRIO105 [*] Call to `trio.lowlevel.permanently_detach_coroutine
|
|||
50 50 | trio.lowlevel.temporarily_detach_coroutine_object(foo)
|
||||
51 51 | trio.lowlevel.wait_readable(foo)
|
||||
|
||||
TRIO105.py:49:5: TRIO105 [*] Call to `trio.lowlevel.reattach_detached_coroutine_object` is not immediately awaited
|
||||
ASYNC105.py:49:5: ASYNC105 [*] Call to `trio.lowlevel.reattach_detached_coroutine_object` is not immediately awaited
|
||||
|
|
||||
47 | trio.lowlevel.open_process()
|
||||
48 | trio.lowlevel.permanently_detach_coroutine_object(foo)
|
||||
49 | trio.lowlevel.reattach_detached_coroutine_object(foo, foo)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRIO105
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ASYNC105
|
||||
50 | trio.lowlevel.temporarily_detach_coroutine_object(foo)
|
||||
51 | trio.lowlevel.wait_readable(foo)
|
||||
|
|
||||
|
@ -399,12 +399,12 @@ TRIO105.py:49:5: TRIO105 [*] Call to `trio.lowlevel.reattach_detached_coroutine_
|
|||
51 51 | trio.lowlevel.wait_readable(foo)
|
||||
52 52 | trio.lowlevel.wait_task_rescheduled(foo)
|
||||
|
||||
TRIO105.py:50:5: TRIO105 [*] Call to `trio.lowlevel.temporarily_detach_coroutine_object` is not immediately awaited
|
||||
ASYNC105.py:50:5: ASYNC105 [*] Call to `trio.lowlevel.temporarily_detach_coroutine_object` is not immediately awaited
|
||||
|
|
||||
48 | trio.lowlevel.permanently_detach_coroutine_object(foo)
|
||||
49 | trio.lowlevel.reattach_detached_coroutine_object(foo, foo)
|
||||
50 | trio.lowlevel.temporarily_detach_coroutine_object(foo)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRIO105
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ASYNC105
|
||||
51 | trio.lowlevel.wait_readable(foo)
|
||||
52 | trio.lowlevel.wait_task_rescheduled(foo)
|
||||
|
|
||||
|
@ -420,12 +420,12 @@ TRIO105.py:50:5: TRIO105 [*] Call to `trio.lowlevel.temporarily_detach_coroutine
|
|||
52 52 | trio.lowlevel.wait_task_rescheduled(foo)
|
||||
53 53 | trio.lowlevel.wait_writable(foo)
|
||||
|
||||
TRIO105.py:51:5: TRIO105 [*] Call to `trio.lowlevel.wait_readable` is not immediately awaited
|
||||
ASYNC105.py:51:5: ASYNC105 [*] Call to `trio.lowlevel.wait_readable` is not immediately awaited
|
||||
|
|
||||
49 | trio.lowlevel.reattach_detached_coroutine_object(foo, foo)
|
||||
50 | trio.lowlevel.temporarily_detach_coroutine_object(foo)
|
||||
51 | trio.lowlevel.wait_readable(foo)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRIO105
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ASYNC105
|
||||
52 | trio.lowlevel.wait_task_rescheduled(foo)
|
||||
53 | trio.lowlevel.wait_writable(foo)
|
||||
|
|
||||
|
@ -441,12 +441,12 @@ TRIO105.py:51:5: TRIO105 [*] Call to `trio.lowlevel.wait_readable` is not immedi
|
|||
53 53 | trio.lowlevel.wait_writable(foo)
|
||||
54 54 |
|
||||
|
||||
TRIO105.py:52:5: TRIO105 [*] Call to `trio.lowlevel.wait_task_rescheduled` is not immediately awaited
|
||||
ASYNC105.py:52:5: ASYNC105 [*] Call to `trio.lowlevel.wait_task_rescheduled` is not immediately awaited
|
||||
|
|
||||
50 | trio.lowlevel.temporarily_detach_coroutine_object(foo)
|
||||
51 | trio.lowlevel.wait_readable(foo)
|
||||
52 | trio.lowlevel.wait_task_rescheduled(foo)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRIO105
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ASYNC105
|
||||
53 | trio.lowlevel.wait_writable(foo)
|
||||
|
|
||||
= help: Add `await`
|
||||
|
@ -461,12 +461,12 @@ TRIO105.py:52:5: TRIO105 [*] Call to `trio.lowlevel.wait_task_rescheduled` is no
|
|||
54 54 |
|
||||
55 55 | async with await trio.open_file(foo): # Ok
|
||||
|
||||
TRIO105.py:53:5: TRIO105 [*] Call to `trio.lowlevel.wait_writable` is not immediately awaited
|
||||
ASYNC105.py:53:5: ASYNC105 [*] Call to `trio.lowlevel.wait_writable` is not immediately awaited
|
||||
|
|
||||
51 | trio.lowlevel.wait_readable(foo)
|
||||
52 | trio.lowlevel.wait_task_rescheduled(foo)
|
||||
53 | trio.lowlevel.wait_writable(foo)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRIO105
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ASYNC105
|
||||
54 |
|
||||
55 | async with await trio.open_file(foo): # Ok
|
||||
|
|
||||
|
@ -482,12 +482,12 @@ TRIO105.py:53:5: TRIO105 [*] Call to `trio.lowlevel.wait_writable` is not immedi
|
|||
55 55 | async with await trio.open_file(foo): # Ok
|
||||
56 56 | pass
|
||||
|
||||
TRIO105.py:58:16: TRIO105 [*] Call to `trio.open_file` is not immediately awaited
|
||||
ASYNC105.py:58:16: ASYNC105 [*] Call to `trio.open_file` is not immediately awaited
|
||||
|
|
||||
56 | pass
|
||||
57 |
|
||||
58 | async with trio.open_file(foo): # TRIO105
|
||||
| ^^^^^^^^^^^^^^^^^^^ TRIO105
|
||||
58 | async with trio.open_file(foo): # ASYNC105
|
||||
| ^^^^^^^^^^^^^^^^^^^ ASYNC105
|
||||
59 | pass
|
||||
|
|
||||
= help: Add `await`
|
||||
|
@ -496,19 +496,17 @@ TRIO105.py:58:16: TRIO105 [*] Call to `trio.open_file` is not immediately awaite
|
|||
55 55 | async with await trio.open_file(foo): # Ok
|
||||
56 56 | pass
|
||||
57 57 |
|
||||
58 |- async with trio.open_file(foo): # TRIO105
|
||||
58 |+ async with await trio.open_file(foo): # TRIO105
|
||||
58 |- async with trio.open_file(foo): # ASYNC105
|
||||
58 |+ async with await trio.open_file(foo): # ASYNC105
|
||||
59 59 | pass
|
||||
60 60 |
|
||||
61 61 |
|
||||
|
||||
TRIO105.py:64:5: TRIO105 Call to `trio.open_file` is not immediately awaited
|
||||
ASYNC105.py:64:5: ASYNC105 Call to `trio.open_file` is not immediately awaited
|
||||
|
|
||||
62 | def func() -> None:
|
||||
63 | # TRIO105 (without fix)
|
||||
63 | # ASYNC105 (without fix)
|
||||
64 | trio.open_file(foo)
|
||||
| ^^^^^^^^^^^^^^^^^^^ TRIO105
|
||||
| ^^^^^^^^^^^^^^^^^^^ ASYNC105
|
||||
|
|
||||
= help: Add `await`
|
||||
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_async/mod.rs
|
||||
---
|
||||
ASYNC109.py:8:16: ASYNC109 Prefer `trio.fail_after` and `trio.move_on_after` over manual `async` timeout behavior
|
||||
|
|
||||
8 | async def func(timeout):
|
||||
| ^^^^^^^ ASYNC109
|
||||
9 | ...
|
||||
|
|
||||
|
||||
ASYNC109.py:12:16: ASYNC109 Prefer `trio.fail_after` and `trio.move_on_after` over manual `async` timeout behavior
|
||||
|
|
||||
12 | async def func(timeout=10):
|
||||
| ^^^^^^^^^^ ASYNC109
|
||||
13 | ...
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_async/mod.rs
|
||||
---
|
||||
ASYNC110.py:5:5: ASYNC110 Use `trio.Event` instead of awaiting `trio.sleep` in a `while` loop
|
||||
|
|
||||
4 | async def func():
|
||||
5 | while True:
|
||||
| _____^
|
||||
6 | | await trio.sleep(10)
|
||||
| |____________________________^ ASYNC110
|
||||
|
|
||||
|
||||
ASYNC110.py:10:5: ASYNC110 Use `trio.Event` instead of awaiting `trio.sleep` in a `while` loop
|
||||
|
|
||||
9 | async def func():
|
||||
10 | while True:
|
||||
| _____^
|
||||
11 | | await trio.sleep_until(10)
|
||||
| |__________________________________^ ASYNC110
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_trio/mod.rs
|
||||
source: crates/ruff_linter/src/rules/flake8_async/mod.rs
|
||||
---
|
||||
TRIO115.py:5:11: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)`
|
||||
ASYNC115.py:5:11: ASYNC115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)`
|
||||
|
|
||||
3 | from trio import sleep
|
||||
4 |
|
||||
5 | await trio.sleep(0) # TRIO115
|
||||
| ^^^^^^^^^^^^^ TRIO115
|
||||
5 | await trio.sleep(0) # ASYNC115
|
||||
| ^^^^^^^^^^^^^ ASYNC115
|
||||
6 | await trio.sleep(1) # OK
|
||||
7 | await trio.sleep(0, 1) # OK
|
||||
|
|
||||
|
@ -16,18 +16,18 @@ TRIO115.py:5:11: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.s
|
|||
2 2 | import trio
|
||||
3 3 | from trio import sleep
|
||||
4 4 |
|
||||
5 |- await trio.sleep(0) # TRIO115
|
||||
5 |+ await trio.lowlevel.checkpoint() # TRIO115
|
||||
5 |- await trio.sleep(0) # ASYNC115
|
||||
5 |+ await trio.lowlevel.checkpoint() # ASYNC115
|
||||
6 6 | await trio.sleep(1) # OK
|
||||
7 7 | await trio.sleep(0, 1) # OK
|
||||
8 8 | await trio.sleep(...) # OK
|
||||
|
||||
TRIO115.py:11:5: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)`
|
||||
ASYNC115.py:11:5: ASYNC115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)`
|
||||
|
|
||||
9 | await trio.sleep() # OK
|
||||
10 |
|
||||
11 | trio.sleep(0) # TRIO115
|
||||
| ^^^^^^^^^^^^^ TRIO115
|
||||
11 | trio.sleep(0) # ASYNC115
|
||||
| ^^^^^^^^^^^^^ ASYNC115
|
||||
12 | foo = 0
|
||||
13 | trio.sleep(foo) # OK
|
||||
|
|
||||
|
@ -37,18 +37,18 @@ TRIO115.py:11:5: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.s
|
|||
8 8 | await trio.sleep(...) # OK
|
||||
9 9 | await trio.sleep() # OK
|
||||
10 10 |
|
||||
11 |- trio.sleep(0) # TRIO115
|
||||
11 |+ trio.lowlevel.checkpoint() # TRIO115
|
||||
11 |- trio.sleep(0) # ASYNC115
|
||||
11 |+ trio.lowlevel.checkpoint() # ASYNC115
|
||||
12 12 | foo = 0
|
||||
13 13 | trio.sleep(foo) # OK
|
||||
14 14 | trio.sleep(1) # OK
|
||||
|
||||
TRIO115.py:17:5: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)`
|
||||
ASYNC115.py:17:5: ASYNC115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)`
|
||||
|
|
||||
15 | time.sleep(0) # OK
|
||||
16 |
|
||||
17 | sleep(0) # TRIO115
|
||||
| ^^^^^^^^ TRIO115
|
||||
17 | sleep(0) # ASYNC115
|
||||
| ^^^^^^^^ ASYNC115
|
||||
18 |
|
||||
19 | bar = "bar"
|
||||
|
|
||||
|
@ -58,18 +58,18 @@ TRIO115.py:17:5: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.s
|
|||
14 14 | trio.sleep(1) # OK
|
||||
15 15 | time.sleep(0) # OK
|
||||
16 16 |
|
||||
17 |- sleep(0) # TRIO115
|
||||
17 |+ trio.lowlevel.checkpoint() # TRIO115
|
||||
17 |- sleep(0) # ASYNC115
|
||||
17 |+ trio.lowlevel.checkpoint() # ASYNC115
|
||||
18 18 |
|
||||
19 19 | bar = "bar"
|
||||
20 20 | trio.sleep(bar)
|
||||
|
||||
TRIO115.py:48:14: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)`
|
||||
ASYNC115.py:48:14: ASYNC115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)`
|
||||
|
|
||||
46 | import trio
|
||||
47 |
|
||||
48 | trio.run(trio.sleep(0)) # TRIO115
|
||||
| ^^^^^^^^^^^^^ TRIO115
|
||||
48 | trio.run(trio.sleep(0)) # ASYNC115
|
||||
| ^^^^^^^^^^^^^ ASYNC115
|
||||
|
|
||||
= help: Replace with `trio.lowlevel.checkpoint()`
|
||||
|
||||
|
@ -77,22 +77,22 @@ TRIO115.py:48:14: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.
|
|||
45 45 | def func():
|
||||
46 46 | import trio
|
||||
47 47 |
|
||||
48 |- trio.run(trio.sleep(0)) # TRIO115
|
||||
48 |+ trio.run(trio.lowlevel.checkpoint()) # TRIO115
|
||||
48 |- trio.run(trio.sleep(0)) # ASYNC115
|
||||
48 |+ trio.run(trio.lowlevel.checkpoint()) # ASYNC115
|
||||
49 49 |
|
||||
50 50 |
|
||||
51 51 | from trio import Event, sleep
|
||||
|
||||
TRIO115.py:55:5: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)`
|
||||
ASYNC115.py:55:5: ASYNC115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)`
|
||||
|
|
||||
54 | def func():
|
||||
55 | sleep(0) # TRIO115
|
||||
| ^^^^^^^^ TRIO115
|
||||
55 | sleep(0) # ASYNC115
|
||||
| ^^^^^^^^ ASYNC115
|
||||
|
|
||||
= help: Replace with `trio.lowlevel.checkpoint()`
|
||||
|
||||
ℹ Safe fix
|
||||
48 48 | trio.run(trio.sleep(0)) # TRIO115
|
||||
48 48 | trio.run(trio.sleep(0)) # ASYNC115
|
||||
49 49 |
|
||||
50 50 |
|
||||
51 |-from trio import Event, sleep
|
||||
|
@ -100,22 +100,22 @@ TRIO115.py:55:5: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.s
|
|||
52 52 |
|
||||
53 53 |
|
||||
54 54 | def func():
|
||||
55 |- sleep(0) # TRIO115
|
||||
55 |+ lowlevel.checkpoint() # TRIO115
|
||||
55 |- sleep(0) # ASYNC115
|
||||
55 |+ lowlevel.checkpoint() # ASYNC115
|
||||
56 56 |
|
||||
57 57 |
|
||||
58 58 | async def func():
|
||||
|
||||
TRIO115.py:59:11: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)`
|
||||
ASYNC115.py:59:11: ASYNC115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)`
|
||||
|
|
||||
58 | async def func():
|
||||
59 | await sleep(seconds=0) # TRIO115
|
||||
| ^^^^^^^^^^^^^^^^ TRIO115
|
||||
59 | await sleep(seconds=0) # ASYNC115
|
||||
| ^^^^^^^^^^^^^^^^ ASYNC115
|
||||
|
|
||||
= help: Replace with `trio.lowlevel.checkpoint()`
|
||||
|
||||
ℹ Safe fix
|
||||
48 48 | trio.run(trio.sleep(0)) # TRIO115
|
||||
48 48 | trio.run(trio.sleep(0)) # ASYNC115
|
||||
49 49 |
|
||||
50 50 |
|
||||
51 |-from trio import Event, sleep
|
||||
|
@ -127,8 +127,8 @@ TRIO115.py:59:11: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.
|
|||
56 56 |
|
||||
57 57 |
|
||||
58 58 | async def func():
|
||||
59 |- await sleep(seconds=0) # TRIO115
|
||||
59 |+ await lowlevel.checkpoint() # TRIO115
|
||||
59 |- await sleep(seconds=0) # ASYNC115
|
||||
59 |+ await lowlevel.checkpoint() # ASYNC115
|
||||
60 60 |
|
||||
61 61 |
|
||||
62 62 | def func():
|
|
@ -0,0 +1,229 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_async/mod.rs
|
||||
---
|
||||
ASYNC210.py:8:5: ASYNC210 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
7 | async def foo():
|
||||
8 | urllib.request.urlopen("http://example.com/foo/bar").read() # ASYNC210
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ ASYNC210
|
||||
|
|
||||
|
||||
ASYNC210.py:12:5: ASYNC210 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
11 | async def foo():
|
||||
12 | requests.get() # ASYNC210
|
||||
| ^^^^^^^^^^^^ ASYNC210
|
||||
|
|
||||
|
||||
ASYNC210.py:16:5: ASYNC210 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
15 | async def foo():
|
||||
16 | httpx.get() # ASYNC210
|
||||
| ^^^^^^^^^ ASYNC210
|
||||
|
|
||||
|
||||
ASYNC210.py:20:5: ASYNC210 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
19 | async def foo():
|
||||
20 | requests.post() # ASYNC210
|
||||
| ^^^^^^^^^^^^^ ASYNC210
|
||||
|
|
||||
|
||||
ASYNC210.py:24:5: ASYNC210 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
23 | async def foo():
|
||||
24 | httpx.post() # ASYNC210
|
||||
| ^^^^^^^^^^ ASYNC210
|
||||
|
|
||||
|
||||
ASYNC210.py:28:5: ASYNC210 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
27 | async def foo():
|
||||
28 | requests.get() # ASYNC210
|
||||
| ^^^^^^^^^^^^ ASYNC210
|
||||
29 | requests.get(...) # ASYNC210
|
||||
30 | requests.get # Ok
|
||||
|
|
||||
|
||||
ASYNC210.py:29:5: ASYNC210 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
27 | async def foo():
|
||||
28 | requests.get() # ASYNC210
|
||||
29 | requests.get(...) # ASYNC210
|
||||
| ^^^^^^^^^^^^ ASYNC210
|
||||
30 | requests.get # Ok
|
||||
31 | print(requests.get()) # ASYNC210
|
||||
|
|
||||
|
||||
ASYNC210.py:31:11: ASYNC210 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
29 | requests.get(...) # ASYNC210
|
||||
30 | requests.get # Ok
|
||||
31 | print(requests.get()) # ASYNC210
|
||||
| ^^^^^^^^^^^^ ASYNC210
|
||||
32 | print(requests.get(requests.get())) # ASYNC210
|
||||
|
|
||||
|
||||
ASYNC210.py:32:11: ASYNC210 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
30 | requests.get # Ok
|
||||
31 | print(requests.get()) # ASYNC210
|
||||
32 | print(requests.get(requests.get())) # ASYNC210
|
||||
| ^^^^^^^^^^^^ ASYNC210
|
||||
33 |
|
||||
34 | requests.options() # ASYNC210
|
||||
|
|
||||
|
||||
ASYNC210.py:32:24: ASYNC210 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
30 | requests.get # Ok
|
||||
31 | print(requests.get()) # ASYNC210
|
||||
32 | print(requests.get(requests.get())) # ASYNC210
|
||||
| ^^^^^^^^^^^^ ASYNC210
|
||||
33 |
|
||||
34 | requests.options() # ASYNC210
|
||||
|
|
||||
|
||||
ASYNC210.py:34:5: ASYNC210 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
32 | print(requests.get(requests.get())) # ASYNC210
|
||||
33 |
|
||||
34 | requests.options() # ASYNC210
|
||||
| ^^^^^^^^^^^^^^^^ ASYNC210
|
||||
35 | requests.head() # ASYNC210
|
||||
36 | requests.post() # ASYNC210
|
||||
|
|
||||
|
||||
ASYNC210.py:35:5: ASYNC210 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
34 | requests.options() # ASYNC210
|
||||
35 | requests.head() # ASYNC210
|
||||
| ^^^^^^^^^^^^^ ASYNC210
|
||||
36 | requests.post() # ASYNC210
|
||||
37 | requests.put() # ASYNC210
|
||||
|
|
||||
|
||||
ASYNC210.py:36:5: ASYNC210 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
34 | requests.options() # ASYNC210
|
||||
35 | requests.head() # ASYNC210
|
||||
36 | requests.post() # ASYNC210
|
||||
| ^^^^^^^^^^^^^ ASYNC210
|
||||
37 | requests.put() # ASYNC210
|
||||
38 | requests.patch() # ASYNC210
|
||||
|
|
||||
|
||||
ASYNC210.py:37:5: ASYNC210 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
35 | requests.head() # ASYNC210
|
||||
36 | requests.post() # ASYNC210
|
||||
37 | requests.put() # ASYNC210
|
||||
| ^^^^^^^^^^^^ ASYNC210
|
||||
38 | requests.patch() # ASYNC210
|
||||
39 | requests.delete() # ASYNC210
|
||||
|
|
||||
|
||||
ASYNC210.py:38:5: ASYNC210 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
36 | requests.post() # ASYNC210
|
||||
37 | requests.put() # ASYNC210
|
||||
38 | requests.patch() # ASYNC210
|
||||
| ^^^^^^^^^^^^^^ ASYNC210
|
||||
39 | requests.delete() # ASYNC210
|
||||
40 | requests.foo()
|
||||
|
|
||||
|
||||
ASYNC210.py:39:5: ASYNC210 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
37 | requests.put() # ASYNC210
|
||||
38 | requests.patch() # ASYNC210
|
||||
39 | requests.delete() # ASYNC210
|
||||
| ^^^^^^^^^^^^^^^ ASYNC210
|
||||
40 | requests.foo()
|
||||
|
|
||||
|
||||
ASYNC210.py:42:5: ASYNC210 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
40 | requests.foo()
|
||||
41 |
|
||||
42 | httpx.options("") # ASYNC210
|
||||
| ^^^^^^^^^^^^^ ASYNC210
|
||||
43 | httpx.head("") # ASYNC210
|
||||
44 | httpx.post("") # ASYNC210
|
||||
|
|
||||
|
||||
ASYNC210.py:43:5: ASYNC210 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
42 | httpx.options("") # ASYNC210
|
||||
43 | httpx.head("") # ASYNC210
|
||||
| ^^^^^^^^^^ ASYNC210
|
||||
44 | httpx.post("") # ASYNC210
|
||||
45 | httpx.put("") # ASYNC210
|
||||
|
|
||||
|
||||
ASYNC210.py:44:5: ASYNC210 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
42 | httpx.options("") # ASYNC210
|
||||
43 | httpx.head("") # ASYNC210
|
||||
44 | httpx.post("") # ASYNC210
|
||||
| ^^^^^^^^^^ ASYNC210
|
||||
45 | httpx.put("") # ASYNC210
|
||||
46 | httpx.patch("") # ASYNC210
|
||||
|
|
||||
|
||||
ASYNC210.py:45:5: ASYNC210 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
43 | httpx.head("") # ASYNC210
|
||||
44 | httpx.post("") # ASYNC210
|
||||
45 | httpx.put("") # ASYNC210
|
||||
| ^^^^^^^^^ ASYNC210
|
||||
46 | httpx.patch("") # ASYNC210
|
||||
47 | httpx.delete("") # ASYNC210
|
||||
|
|
||||
|
||||
ASYNC210.py:46:5: ASYNC210 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
44 | httpx.post("") # ASYNC210
|
||||
45 | httpx.put("") # ASYNC210
|
||||
46 | httpx.patch("") # ASYNC210
|
||||
| ^^^^^^^^^^^ ASYNC210
|
||||
47 | httpx.delete("") # ASYNC210
|
||||
48 | httpx.foo() # Ok
|
||||
|
|
||||
|
||||
ASYNC210.py:47:5: ASYNC210 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
45 | httpx.put("") # ASYNC210
|
||||
46 | httpx.patch("") # ASYNC210
|
||||
47 | httpx.delete("") # ASYNC210
|
||||
| ^^^^^^^^^^^^ ASYNC210
|
||||
48 | httpx.foo() # Ok
|
||||
|
|
||||
|
||||
ASYNC210.py:50:5: ASYNC210 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
48 | httpx.foo() # Ok
|
||||
49 |
|
||||
50 | urllib3.request() # ASYNC210
|
||||
| ^^^^^^^^^^^^^^^ ASYNC210
|
||||
51 | urllib3.request(...) # ASYNC210
|
||||
|
|
||||
|
||||
ASYNC210.py:51:5: ASYNC210 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
50 | urllib3.request() # ASYNC210
|
||||
51 | urllib3.request(...) # ASYNC210
|
||||
| ^^^^^^^^^^^^^^^ ASYNC210
|
||||
52 |
|
||||
53 | urllib.request.urlopen("") # ASYNC210
|
||||
|
|
||||
|
||||
ASYNC210.py:53:5: ASYNC210 Async functions should not call blocking HTTP methods
|
||||
|
|
||||
51 | urllib3.request(...) # ASYNC210
|
||||
52 |
|
||||
53 | urllib.request.urlopen("") # ASYNC210
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ ASYNC210
|
||||
54 |
|
||||
55 | r = {}
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_async/mod.rs
|
||||
---
|
||||
ASYNC22x.py:31:5: ASYNC220 Async functions should not create subprocesses with blocking methods
|
||||
|
|
||||
29 | subprocess.getoutput() # ASYNC221
|
||||
30 | )
|
||||
31 | subprocess.Popen() # ASYNC220
|
||||
| ^^^^^^^^^^^^^^^^ ASYNC220
|
||||
32 | os.system() # ASYNC221
|
||||
|
|
||||
|
||||
ASYNC22x.py:73:5: ASYNC220 Async functions should not create subprocesses with blocking methods
|
||||
|
|
||||
72 | # if mode is given, and is not os.P_WAIT: ASYNC220
|
||||
73 | os.spawnl(os.P_NOWAIT) # ASYNC220
|
||||
| ^^^^^^^^^ ASYNC220
|
||||
74 | os.spawnl(P_NOWAIT) # ASYNC220
|
||||
75 | os.spawnl(mode=os.P_NOWAIT) # ASYNC220
|
||||
|
|
||||
|
||||
ASYNC22x.py:74:5: ASYNC220 Async functions should not create subprocesses with blocking methods
|
||||
|
|
||||
72 | # if mode is given, and is not os.P_WAIT: ASYNC220
|
||||
73 | os.spawnl(os.P_NOWAIT) # ASYNC220
|
||||
74 | os.spawnl(P_NOWAIT) # ASYNC220
|
||||
| ^^^^^^^^^ ASYNC220
|
||||
75 | os.spawnl(mode=os.P_NOWAIT) # ASYNC220
|
||||
76 | os.spawnl(mode=P_NOWAIT) # ASYNC220
|
||||
|
|
||||
|
||||
ASYNC22x.py:75:5: ASYNC220 Async functions should not create subprocesses with blocking methods
|
||||
|
|
||||
73 | os.spawnl(os.P_NOWAIT) # ASYNC220
|
||||
74 | os.spawnl(P_NOWAIT) # ASYNC220
|
||||
75 | os.spawnl(mode=os.P_NOWAIT) # ASYNC220
|
||||
| ^^^^^^^^^ ASYNC220
|
||||
76 | os.spawnl(mode=P_NOWAIT) # ASYNC220
|
||||
|
|
||||
|
||||
ASYNC22x.py:76:5: ASYNC220 Async functions should not create subprocesses with blocking methods
|
||||
|
|
||||
74 | os.spawnl(P_NOWAIT) # ASYNC220
|
||||
75 | os.spawnl(mode=os.P_NOWAIT) # ASYNC220
|
||||
76 | os.spawnl(mode=P_NOWAIT) # ASYNC220
|
||||
| ^^^^^^^^^ ASYNC220
|
||||
77 |
|
||||
78 | P_WAIT = os.P_WAIT
|
||||
|
|
||||
|
||||
ASYNC22x.py:86:5: ASYNC220 Async functions should not create subprocesses with blocking methods
|
||||
|
|
||||
85 | # other weird cases: ASYNC220
|
||||
86 | os.spawnl(0) # ASYNC220
|
||||
| ^^^^^^^^^ ASYNC220
|
||||
87 | os.spawnl(1) # ASYNC220
|
||||
88 | os.spawnl(foo()) # ASYNC220
|
||||
|
|
||||
|
||||
ASYNC22x.py:87:5: ASYNC220 Async functions should not create subprocesses with blocking methods
|
||||
|
|
||||
85 | # other weird cases: ASYNC220
|
||||
86 | os.spawnl(0) # ASYNC220
|
||||
87 | os.spawnl(1) # ASYNC220
|
||||
| ^^^^^^^^^ ASYNC220
|
||||
88 | os.spawnl(foo()) # ASYNC220
|
||||
|
|
||||
|
||||
ASYNC22x.py:88:5: ASYNC220 Async functions should not create subprocesses with blocking methods
|
||||
|
|
||||
86 | os.spawnl(0) # ASYNC220
|
||||
87 | os.spawnl(1) # ASYNC220
|
||||
88 | os.spawnl(foo()) # ASYNC220
|
||||
| ^^^^^^^^^ ASYNC220
|
||||
89 |
|
||||
90 | # ASYNC222
|
||||
|
|
|
@ -0,0 +1,226 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_async/mod.rs
|
||||
---
|
||||
ASYNC22x.py:8:5: ASYNC221 Async functions should not run processes with blocking methods
|
||||
|
|
||||
7 | async def func():
|
||||
8 | subprocess.run("foo") # ASYNC221
|
||||
| ^^^^^^^^^^^^^^ ASYNC221
|
||||
|
|
||||
|
||||
ASYNC22x.py:12:5: ASYNC221 Async functions should not run processes with blocking methods
|
||||
|
|
||||
11 | async def func():
|
||||
12 | subprocess.call("foo") # ASYNC221
|
||||
| ^^^^^^^^^^^^^^^ ASYNC221
|
||||
|
|
||||
|
||||
ASYNC22x.py:29:9: ASYNC221 Async functions should not run processes with blocking methods
|
||||
|
|
||||
27 | async def foo():
|
||||
28 | await async_fun(
|
||||
29 | subprocess.getoutput() # ASYNC221
|
||||
| ^^^^^^^^^^^^^^^^^^^^ ASYNC221
|
||||
30 | )
|
||||
31 | subprocess.Popen() # ASYNC220
|
||||
|
|
||||
|
||||
ASYNC22x.py:32:5: ASYNC221 Async functions should not run processes with blocking methods
|
||||
|
|
||||
30 | )
|
||||
31 | subprocess.Popen() # ASYNC220
|
||||
32 | os.system() # ASYNC221
|
||||
| ^^^^^^^^^ ASYNC221
|
||||
33 |
|
||||
34 | system()
|
||||
|
|
||||
|
||||
ASYNC22x.py:38:5: ASYNC221 Async functions should not run processes with blocking methods
|
||||
|
|
||||
36 | os.anything()
|
||||
37 |
|
||||
38 | subprocess.run() # ASYNC221
|
||||
| ^^^^^^^^^^^^^^ ASYNC221
|
||||
39 | subprocess.call() # ASYNC221
|
||||
40 | subprocess.check_call() # ASYNC221
|
||||
|
|
||||
|
||||
ASYNC22x.py:39:5: ASYNC221 Async functions should not run processes with blocking methods
|
||||
|
|
||||
38 | subprocess.run() # ASYNC221
|
||||
39 | subprocess.call() # ASYNC221
|
||||
| ^^^^^^^^^^^^^^^ ASYNC221
|
||||
40 | subprocess.check_call() # ASYNC221
|
||||
41 | subprocess.check_output() # ASYNC221
|
||||
|
|
||||
|
||||
ASYNC22x.py:40:5: ASYNC221 Async functions should not run processes with blocking methods
|
||||
|
|
||||
38 | subprocess.run() # ASYNC221
|
||||
39 | subprocess.call() # ASYNC221
|
||||
40 | subprocess.check_call() # ASYNC221
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ ASYNC221
|
||||
41 | subprocess.check_output() # ASYNC221
|
||||
42 | subprocess.getoutput() # ASYNC221
|
||||
|
|
||||
|
||||
ASYNC22x.py:41:5: ASYNC221 Async functions should not run processes with blocking methods
|
||||
|
|
||||
39 | subprocess.call() # ASYNC221
|
||||
40 | subprocess.check_call() # ASYNC221
|
||||
41 | subprocess.check_output() # ASYNC221
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ ASYNC221
|
||||
42 | subprocess.getoutput() # ASYNC221
|
||||
43 | subprocess.getstatusoutput() # ASYNC221
|
||||
|
|
||||
|
||||
ASYNC22x.py:42:5: ASYNC221 Async functions should not run processes with blocking methods
|
||||
|
|
||||
40 | subprocess.check_call() # ASYNC221
|
||||
41 | subprocess.check_output() # ASYNC221
|
||||
42 | subprocess.getoutput() # ASYNC221
|
||||
| ^^^^^^^^^^^^^^^^^^^^ ASYNC221
|
||||
43 | subprocess.getstatusoutput() # ASYNC221
|
||||
|
|
||||
|
||||
ASYNC22x.py:43:5: ASYNC221 Async functions should not run processes with blocking methods
|
||||
|
|
||||
41 | subprocess.check_output() # ASYNC221
|
||||
42 | subprocess.getoutput() # ASYNC221
|
||||
43 | subprocess.getstatusoutput() # ASYNC221
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ASYNC221
|
||||
44 |
|
||||
45 | await async_fun(
|
||||
|
|
||||
|
||||
ASYNC22x.py:46:9: ASYNC221 Async functions should not run processes with blocking methods
|
||||
|
|
||||
45 | await async_fun(
|
||||
46 | subprocess.getoutput() # ASYNC221
|
||||
| ^^^^^^^^^^^^^^^^^^^^ ASYNC221
|
||||
47 | )
|
||||
|
|
||||
|
||||
ASYNC22x.py:54:5: ASYNC221 Async functions should not run processes with blocking methods
|
||||
|
|
||||
52 | subprocess()
|
||||
53 |
|
||||
54 | os.posix_spawn() # ASYNC221
|
||||
| ^^^^^^^^^^^^^^ ASYNC221
|
||||
55 | os.posix_spawnp() # ASYNC221
|
||||
|
|
||||
|
||||
ASYNC22x.py:55:5: ASYNC221 Async functions should not run processes with blocking methods
|
||||
|
|
||||
54 | os.posix_spawn() # ASYNC221
|
||||
55 | os.posix_spawnp() # ASYNC221
|
||||
| ^^^^^^^^^^^^^^^ ASYNC221
|
||||
56 |
|
||||
57 | os.spawn()
|
||||
|
|
||||
|
||||
ASYNC22x.py:61:5: ASYNC221 Async functions should not run processes with blocking methods
|
||||
|
|
||||
59 | os.spawnllll()
|
||||
60 |
|
||||
61 | os.spawnl() # ASYNC221
|
||||
| ^^^^^^^^^ ASYNC221
|
||||
62 | os.spawnle() # ASYNC221
|
||||
63 | os.spawnlp() # ASYNC221
|
||||
|
|
||||
|
||||
ASYNC22x.py:62:5: ASYNC221 Async functions should not run processes with blocking methods
|
||||
|
|
||||
61 | os.spawnl() # ASYNC221
|
||||
62 | os.spawnle() # ASYNC221
|
||||
| ^^^^^^^^^^ ASYNC221
|
||||
63 | os.spawnlp() # ASYNC221
|
||||
64 | os.spawnlpe() # ASYNC221
|
||||
|
|
||||
|
||||
ASYNC22x.py:63:5: ASYNC221 Async functions should not run processes with blocking methods
|
||||
|
|
||||
61 | os.spawnl() # ASYNC221
|
||||
62 | os.spawnle() # ASYNC221
|
||||
63 | os.spawnlp() # ASYNC221
|
||||
| ^^^^^^^^^^ ASYNC221
|
||||
64 | os.spawnlpe() # ASYNC221
|
||||
65 | os.spawnv() # ASYNC221
|
||||
|
|
||||
|
||||
ASYNC22x.py:64:5: ASYNC221 Async functions should not run processes with blocking methods
|
||||
|
|
||||
62 | os.spawnle() # ASYNC221
|
||||
63 | os.spawnlp() # ASYNC221
|
||||
64 | os.spawnlpe() # ASYNC221
|
||||
| ^^^^^^^^^^^ ASYNC221
|
||||
65 | os.spawnv() # ASYNC221
|
||||
66 | os.spawnve() # ASYNC221
|
||||
|
|
||||
|
||||
ASYNC22x.py:65:5: ASYNC221 Async functions should not run processes with blocking methods
|
||||
|
|
||||
63 | os.spawnlp() # ASYNC221
|
||||
64 | os.spawnlpe() # ASYNC221
|
||||
65 | os.spawnv() # ASYNC221
|
||||
| ^^^^^^^^^ ASYNC221
|
||||
66 | os.spawnve() # ASYNC221
|
||||
67 | os.spawnvp() # ASYNC221
|
||||
|
|
||||
|
||||
ASYNC22x.py:66:5: ASYNC221 Async functions should not run processes with blocking methods
|
||||
|
|
||||
64 | os.spawnlpe() # ASYNC221
|
||||
65 | os.spawnv() # ASYNC221
|
||||
66 | os.spawnve() # ASYNC221
|
||||
| ^^^^^^^^^^ ASYNC221
|
||||
67 | os.spawnvp() # ASYNC221
|
||||
68 | os.spawnvpe() # ASYNC221
|
||||
|
|
||||
|
||||
ASYNC22x.py:67:5: ASYNC221 Async functions should not run processes with blocking methods
|
||||
|
|
||||
65 | os.spawnv() # ASYNC221
|
||||
66 | os.spawnve() # ASYNC221
|
||||
67 | os.spawnvp() # ASYNC221
|
||||
| ^^^^^^^^^^ ASYNC221
|
||||
68 | os.spawnvpe() # ASYNC221
|
||||
|
|
||||
|
||||
ASYNC22x.py:68:5: ASYNC221 Async functions should not run processes with blocking methods
|
||||
|
|
||||
66 | os.spawnve() # ASYNC221
|
||||
67 | os.spawnvp() # ASYNC221
|
||||
68 | os.spawnvpe() # ASYNC221
|
||||
| ^^^^^^^^^^^ ASYNC221
|
||||
69 |
|
||||
70 | P_NOWAIT = os.P_NOWAIT
|
||||
|
|
||||
|
||||
ASYNC22x.py:81:5: ASYNC221 Async functions should not run processes with blocking methods
|
||||
|
|
||||
80 | # if it is P_WAIT, ASYNC221
|
||||
81 | os.spawnl(P_WAIT) # ASYNC221
|
||||
| ^^^^^^^^^ ASYNC221
|
||||
82 | os.spawnl(mode=os.P_WAIT) # ASYNC221
|
||||
83 | os.spawnl(mode=P_WAIT) # ASYNC221
|
||||
|
|
||||
|
||||
ASYNC22x.py:82:5: ASYNC221 Async functions should not run processes with blocking methods
|
||||
|
|
||||
80 | # if it is P_WAIT, ASYNC221
|
||||
81 | os.spawnl(P_WAIT) # ASYNC221
|
||||
82 | os.spawnl(mode=os.P_WAIT) # ASYNC221
|
||||
| ^^^^^^^^^ ASYNC221
|
||||
83 | os.spawnl(mode=P_WAIT) # ASYNC221
|
||||
|
|
||||
|
||||
ASYNC22x.py:83:5: ASYNC221 Async functions should not run processes with blocking methods
|
||||
|
|
||||
81 | os.spawnl(P_WAIT) # ASYNC221
|
||||
82 | os.spawnl(mode=os.P_WAIT) # ASYNC221
|
||||
83 | os.spawnl(mode=P_WAIT) # ASYNC221
|
||||
| ^^^^^^^^^ ASYNC221
|
||||
84 |
|
||||
85 | # other weird cases: ASYNC220
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_async/mod.rs
|
||||
---
|
||||
ASYNC22x.py:20:5: ASYNC222 Async functions should not wait on processes with blocking methods
|
||||
|
|
||||
19 | async def func():
|
||||
20 | os.wait4(10) # ASYNC222
|
||||
| ^^^^^^^^ ASYNC222
|
||||
|
|
||||
|
||||
ASYNC22x.py:24:5: ASYNC222 Async functions should not wait on processes with blocking methods
|
||||
|
|
||||
23 | async def func():
|
||||
24 | os.wait(12) # ASYNC222
|
||||
| ^^^^^^^ ASYNC222
|
||||
|
|
||||
|
||||
ASYNC22x.py:91:5: ASYNC222 Async functions should not wait on processes with blocking methods
|
||||
|
|
||||
90 | # ASYNC222
|
||||
91 | os.wait() # ASYNC222
|
||||
| ^^^^^^^ ASYNC222
|
||||
92 | os.wait3() # ASYNC222
|
||||
93 | os.wait4() # ASYNC222
|
||||
|
|
||||
|
||||
ASYNC22x.py:92:5: ASYNC222 Async functions should not wait on processes with blocking methods
|
||||
|
|
||||
90 | # ASYNC222
|
||||
91 | os.wait() # ASYNC222
|
||||
92 | os.wait3() # ASYNC222
|
||||
| ^^^^^^^^ ASYNC222
|
||||
93 | os.wait4() # ASYNC222
|
||||
94 | os.waitid() # ASYNC222
|
||||
|
|
||||
|
||||
ASYNC22x.py:93:5: ASYNC222 Async functions should not wait on processes with blocking methods
|
||||
|
|
||||
91 | os.wait() # ASYNC222
|
||||
92 | os.wait3() # ASYNC222
|
||||
93 | os.wait4() # ASYNC222
|
||||
| ^^^^^^^^ ASYNC222
|
||||
94 | os.waitid() # ASYNC222
|
||||
95 | os.waitpid() # ASYNC222
|
||||
|
|
||||
|
||||
ASYNC22x.py:94:5: ASYNC222 Async functions should not wait on processes with blocking methods
|
||||
|
|
||||
92 | os.wait3() # ASYNC222
|
||||
93 | os.wait4() # ASYNC222
|
||||
94 | os.waitid() # ASYNC222
|
||||
| ^^^^^^^^^ ASYNC222
|
||||
95 | os.waitpid() # ASYNC222
|
||||
|
|
||||
|
||||
ASYNC22x.py:95:5: ASYNC222 Async functions should not wait on processes with blocking methods
|
||||
|
|
||||
93 | os.wait4() # ASYNC222
|
||||
94 | os.waitid() # ASYNC222
|
||||
95 | os.waitpid() # ASYNC222
|
||||
| ^^^^^^^^^^ ASYNC222
|
||||
96 |
|
||||
97 | os.waitpi()
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_async/mod.rs
|
||||
---
|
||||
ASYNC230.py:6:5: ASYNC230 Async functions should not open files with blocking methods like `open`
|
||||
|
|
||||
5 | async def foo():
|
||||
6 | open("") # ASYNC230
|
||||
| ^^^^ ASYNC230
|
||||
7 | io.open_code("") # ASYNC230
|
||||
|
|
||||
|
||||
ASYNC230.py:7:5: ASYNC230 Async functions should not open files with blocking methods like `open`
|
||||
|
|
||||
5 | async def foo():
|
||||
6 | open("") # ASYNC230
|
||||
7 | io.open_code("") # ASYNC230
|
||||
| ^^^^^^^^^^^^ ASYNC230
|
||||
8 |
|
||||
9 | with open(""): # ASYNC230
|
||||
|
|
||||
|
||||
ASYNC230.py:9:10: ASYNC230 Async functions should not open files with blocking methods like `open`
|
||||
|
|
||||
7 | io.open_code("") # ASYNC230
|
||||
8 |
|
||||
9 | with open(""): # ASYNC230
|
||||
| ^^^^ ASYNC230
|
||||
10 | ...
|
||||
|
|
||||
|
||||
ASYNC230.py:12:10: ASYNC230 Async functions should not open files with blocking methods like `open`
|
||||
|
|
||||
10 | ...
|
||||
11 |
|
||||
12 | with open("") as f: # ASYNC230
|
||||
| ^^^^ ASYNC230
|
||||
13 | ...
|
||||
|
|
||||
|
||||
ASYNC230.py:15:17: ASYNC230 Async functions should not open files with blocking methods like `open`
|
||||
|
|
||||
13 | ...
|
||||
14 |
|
||||
15 | with foo(), open(""): # ASYNC230
|
||||
| ^^^^ ASYNC230
|
||||
16 | ...
|
||||
|
|
||||
|
||||
ASYNC230.py:18:16: ASYNC230 Async functions should not open files with blocking methods like `open`
|
||||
|
|
||||
16 | ...
|
||||
17 |
|
||||
18 | async with open(""): # ASYNC230
|
||||
| ^^^^ ASYNC230
|
||||
19 | ...
|
||||
|
|
||||
|
||||
ASYNC230.py:29:5: ASYNC230 Async functions should not open files with blocking methods like `open`
|
||||
|
|
||||
28 | async def func():
|
||||
29 | open("foo") # ASYNC230
|
||||
| ^^^^ ASYNC230
|
||||
|
|
||||
|
||||
ASYNC230.py:36:5: ASYNC230 Async functions should not open files with blocking methods like `open`
|
||||
|
|
||||
35 | async def func():
|
||||
36 | Path("foo").open() # ASYNC230
|
||||
| ^^^^^^^^^^^^^^^^ ASYNC230
|
||||
|
|
||||
|
||||
ASYNC230.py:41:5: ASYNC230 Async functions should not open files with blocking methods like `open`
|
||||
|
|
||||
39 | async def func():
|
||||
40 | p = Path("foo")
|
||||
41 | p.open() # ASYNC230
|
||||
| ^^^^^^ ASYNC230
|
||||
|
|
||||
|
||||
ASYNC230.py:45:10: ASYNC230 Async functions should not open files with blocking methods like `open`
|
||||
|
|
||||
44 | async def func():
|
||||
45 | with Path("foo").open() as f: # ASYNC230
|
||||
| ^^^^^^^^^^^^^^^^ ASYNC230
|
||||
46 | pass
|
||||
|
|
||||
|
||||
ASYNC230.py:53:9: ASYNC230 Async functions should not open files with blocking methods like `open`
|
||||
|
|
||||
52 | async def bar():
|
||||
53 | p.open() # ASYNC230
|
||||
| ^^^^^^ ASYNC230
|
||||
|
|
||||
|
||||
ASYNC230.py:59:5: ASYNC230 Async functions should not open files with blocking methods like `open`
|
||||
|
|
||||
57 | (p1, p2) = (Path("foo"), Path("bar"))
|
||||
58 |
|
||||
59 | p1.open() # ASYNC230
|
||||
| ^^^^^^^ ASYNC230
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_async/mod.rs
|
||||
---
|
||||
ASYNC251.py:6:5: ASYNC251 Async functions should not call `time.sleep`
|
||||
|
|
||||
5 | async def func():
|
||||
6 | time.sleep(1) # ASYNC251
|
||||
| ^^^^^^^^^^ ASYNC251
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
//! Rules from [flake8-trio](https://pypi.org/project/flake8-trio/).
|
||||
pub(super) mod method_name;
|
||||
pub(crate) mod rules;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::path::Path;
|
||||
|
||||
use anyhow::Result;
|
||||
use test_case::test_case;
|
||||
|
||||
use crate::assert_messages;
|
||||
use crate::registry::Rule;
|
||||
use crate::settings::LinterSettings;
|
||||
use crate::test::test_path;
|
||||
|
||||
#[test_case(Rule::TrioTimeoutWithoutAwait, Path::new("TRIO100.py"))]
|
||||
#[test_case(Rule::TrioSyncCall, Path::new("TRIO105.py"))]
|
||||
#[test_case(Rule::TrioAsyncFunctionWithTimeout, Path::new("TRIO109.py"))]
|
||||
#[test_case(Rule::TrioUnneededSleep, Path::new("TRIO110.py"))]
|
||||
#[test_case(Rule::TrioZeroSleepCall, Path::new("TRIO115.py"))]
|
||||
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
|
||||
let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy());
|
||||
let diagnostics = test_path(
|
||||
Path::new("flake8_trio").join(path).as_path(),
|
||||
&LinterSettings::for_rule(rule_code),
|
||||
)?;
|
||||
assert_messages!(snapshot, diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
pub(crate) use async_function_with_timeout::*;
|
||||
pub(crate) use sync_call::*;
|
||||
pub(crate) use timeout_without_await::*;
|
||||
pub(crate) use unneeded_sleep::*;
|
||||
pub(crate) use zero_sleep_call::*;
|
||||
|
||||
mod async_function_with_timeout;
|
||||
mod sync_call;
|
||||
mod timeout_without_await;
|
||||
mod unneeded_sleep;
|
||||
mod zero_sleep_call;
|
|
@ -1,22 +0,0 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_trio/mod.rs
|
||||
---
|
||||
TRIO100.py:5:5: TRIO100 A `with trio.fail_after(...):` context does not contain any `await` statements. This makes it pointless, as the timeout can only be triggered by a checkpoint.
|
||||
|
|
||||
4 | async def func():
|
||||
5 | with trio.fail_after():
|
||||
| _____^
|
||||
6 | | ...
|
||||
| |___________^ TRIO100
|
||||
|
|
||||
|
||||
TRIO100.py:15:5: TRIO100 A `with trio.move_on_after(...):` context does not contain any `await` statements. This makes it pointless, as the timeout can only be triggered by a checkpoint.
|
||||
|
|
||||
14 | async def func():
|
||||
15 | with trio.move_on_after():
|
||||
| _____^
|
||||
16 | | ...
|
||||
| |___________^ TRIO100
|
||||
|
|
||||
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_trio/mod.rs
|
||||
---
|
||||
TRIO109.py:8:16: TRIO109 Prefer `trio.fail_after` and `trio.move_on_after` over manual `async` timeout behavior
|
||||
|
|
||||
8 | async def func(timeout):
|
||||
| ^^^^^^^ TRIO109
|
||||
9 | ...
|
||||
|
|
||||
|
||||
TRIO109.py:12:16: TRIO109 Prefer `trio.fail_after` and `trio.move_on_after` over manual `async` timeout behavior
|
||||
|
|
||||
12 | async def func(timeout=10):
|
||||
| ^^^^^^^^^^ TRIO109
|
||||
13 | ...
|
||||
|
|
||||
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_trio/mod.rs
|
||||
---
|
||||
TRIO110.py:5:5: TRIO110 Use `trio.Event` instead of awaiting `trio.sleep` in a `while` loop
|
||||
|
|
||||
4 | async def func():
|
||||
5 | while True:
|
||||
| _____^
|
||||
6 | | await trio.sleep(10)
|
||||
| |____________________________^ TRIO110
|
||||
|
|
||||
|
||||
TRIO110.py:10:5: TRIO110 Use `trio.Event` instead of awaiting `trio.sleep` in a `while` loop
|
||||
|
|
||||
9 | async def func():
|
||||
10 | while True:
|
||||
| _____^
|
||||
11 | | await trio.sleep_until(10)
|
||||
| |__________________________________^ TRIO110
|
||||
|
|
||||
|
||||
|
|
@ -37,7 +37,6 @@ pub mod flake8_simplify;
|
|||
pub mod flake8_slots;
|
||||
pub mod flake8_tidy_imports;
|
||||
pub mod flake8_todos;
|
||||
pub mod flake8_trio;
|
||||
pub mod flake8_type_checking;
|
||||
pub mod flake8_unused_arguments;
|
||||
pub mod flake8_use_pathlib;
|
||||
|
|
|
@ -81,7 +81,6 @@ natively, including:
|
|||
- [flake8-super](https://pypi.org/project/flake8-super/)
|
||||
- [flake8-tidy-imports](https://pypi.org/project/flake8-tidy-imports/)
|
||||
- [flake8-todos](https://pypi.org/project/flake8-todos/)
|
||||
- [flake8-trio](https://pypi.org/project/flake8-trio/) ([#8451](https://github.com/astral-sh/ruff/issues/8451))
|
||||
- [flake8-type-checking](https://pypi.org/project/flake8-type-checking/)
|
||||
- [flake8-use-pathlib](https://pypi.org/project/flake8-use-pathlib/)
|
||||
- [flynt](https://pypi.org/project/flynt/) ([#2102](https://github.com/astral-sh/ruff/issues/2102))
|
||||
|
@ -194,7 +193,6 @@ Today, Ruff can be used to replace Flake8 when used with any of the following pl
|
|||
- [flake8-super](https://pypi.org/project/flake8-super/)
|
||||
- [flake8-tidy-imports](https://pypi.org/project/flake8-tidy-imports/)
|
||||
- [flake8-todos](https://pypi.org/project/flake8-todos/)
|
||||
- [flake8-trio](https://pypi.org/project/flake8-trio/) ([#8451](https://github.com/astral-sh/ruff/issues/8451))
|
||||
- [flake8-type-checking](https://pypi.org/project/flake8-type-checking/)
|
||||
- [flake8-use-pathlib](https://pypi.org/project/flake8-use-pathlib/)
|
||||
- [flynt](https://pypi.org/project/flynt/) ([#2102](https://github.com/astral-sh/ruff/issues/2102))
|
||||
|
|
26
ruff.schema.json
generated
26
ruff.schema.json
generated
|
@ -2703,10 +2703,23 @@
|
|||
"ASYNC1",
|
||||
"ASYNC10",
|
||||
"ASYNC100",
|
||||
"ASYNC101",
|
||||
"ASYNC102",
|
||||
"ASYNC105",
|
||||
"ASYNC109",
|
||||
"ASYNC11",
|
||||
"ASYNC110",
|
||||
"ASYNC115",
|
||||
"ASYNC116",
|
||||
"ASYNC2",
|
||||
"ASYNC21",
|
||||
"ASYNC210",
|
||||
"ASYNC22",
|
||||
"ASYNC220",
|
||||
"ASYNC221",
|
||||
"ASYNC222",
|
||||
"ASYNC23",
|
||||
"ASYNC230",
|
||||
"ASYNC25",
|
||||
"ASYNC251",
|
||||
"B",
|
||||
"B0",
|
||||
"B00",
|
||||
|
@ -3847,15 +3860,6 @@
|
|||
"TID251",
|
||||
"TID252",
|
||||
"TID253",
|
||||
"TRIO",
|
||||
"TRIO1",
|
||||
"TRIO10",
|
||||
"TRIO100",
|
||||
"TRIO105",
|
||||
"TRIO109",
|
||||
"TRIO11",
|
||||
"TRIO110",
|
||||
"TRIO115",
|
||||
"TRY",
|
||||
"TRY0",
|
||||
"TRY00",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue