Skip to content

Implement flake8-async plugin#4433

Closed
inikolaev wants to merge 3 commits intoastral-sh:mainfrom
inikolaev:inikolaev/4246-implement-flake8-async-plugin
Closed

Implement flake8-async plugin#4433
inikolaev wants to merge 3 commits intoastral-sh:mainfrom
inikolaev:inikolaev/4246-implement-flake8-async-plugin

Conversation

@inikolaev
Copy link

Added implementation of flake8-async plugin and copied all the tests from it into ruff.

TODOs:

  • Add some descriptions to the new violations

Comment on lines +15 to +17
#[test_case(Rule::SyncHttpCallInAsyncFunction, Path::new("ASYNC100.py"); "ASYNC100")]
#[test_case(Rule::BlockingSyncCallInAsyncFunction, Path::new("ASYNC101.py"); "ASYNC101")]
#[test_case(Rule::SyncProcessCallInAsyncFunction, Path::new("ASYNC102.py"); "ASYNC102")]
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really sure if 3 different test cases are really necessary, I just followed other plugins. A single test case that tests all of them would work as well - all examples are functions with 1-2 lines.

Comment on lines +56 to +89
const HTTP_PACKAGES: [&str; 2] = ["httpx", "requests"];
const HTTP_METHODS: [&str; 9] = ["get", "options", "head", "post", "put", "patch", "delete", "request", "send"];
const TIME_METHODS: [&str; 1] = ["sleep"];
const SUBPROCESS_METHODS: [&str; 7] = [
"run",
"Popen",
// deprecated methods
"call",
"check_call",
"check_output",
"getoutput",
"getstatusoutput",
];
const OS_PROCESS_METHODS: [&str; 12] = [
"popen",
"posix_spawn",
"posix_spawnp",
"spawnl",
"spawnle",
"spawnlp",
"spawnlpe",
"spawnv",
"spawnve",
"spawnvp",
"spawnvpe",
"system",
];
const OS_WAIT_METHODS: [&str; 5] = [
"wait",
"wait3",
"wait4",
"waitid",
"waitpid",
];
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copied from the original plugin

Comment on lines +93 to +127
if let StmtKind::Expr(ast::StmtExpr { value }) = &stmt.node {
if let ExprKind::Call(ast::ExprCall { func, .. }) = &value.node {
if let ExprKind::Name(ast::ExprName { id, .. }) = &func.node {
if "open" == id.as_str() {
let diagnostic = Diagnostic::new(BlockingSyncCallInAsyncFunction, stmt.range());
checker.diagnostics.push(diagnostic);
}
} else if let ExprKind::Attribute(ast::ExprAttribute { value, attr, .. }) = &func.node {
if let ExprKind::Name(ast::ExprName { id, .. }) = &value.node {
let module = id.as_str();
let method = attr.as_str();
let range = stmt.range();

if HTTP_PACKAGES.contains(&module) && HTTP_METHODS.contains(&method) {
let diagnostic = Diagnostic::new(SyncHttpCallInAsyncFunction, range);
checker.diagnostics.push(diagnostic);
} else if "time" == module && TIME_METHODS.contains(&method) {
let diagnostic = Diagnostic::new(BlockingSyncCallInAsyncFunction, range);
checker.diagnostics.push(diagnostic);
} else if "subprocess" == module && SUBPROCESS_METHODS.contains(&method) {
let diagnostic = Diagnostic::new(BlockingSyncCallInAsyncFunction, range);
checker.diagnostics.push(diagnostic);
} else if "os" == module {
if OS_WAIT_METHODS.contains(&method) {
let diagnostic = Diagnostic::new(BlockingSyncCallInAsyncFunction, range);
checker.diagnostics.push(diagnostic);
} else if OS_PROCESS_METHODS.contains(&method) {
let diagnostic = Diagnostic::new(SyncProcessCallInAsyncFunction, range);
checker.diagnostics.push(diagnostic);
}
}
}
}
}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quite straightforward implementation, happy to hear any feedback

inikolaev and others added 3 commits May 14, 2023 22:42
Co-authored-by: Jonathan Plasse <13716151+JonathanPlasse@users.noreply.github.com>
@inikolaev inikolaev force-pushed the inikolaev/4246-implement-flake8-async-plugin branch from 3fee8ee to 40ea0a2 Compare May 14, 2023 19:47
@mara004
Copy link

mara004 commented May 14, 2023

Looks like #4432 was submitted simultaneously?

@mara004 mara004 mentioned this pull request May 14, 2023
1 task
@github-actions
Copy link
Contributor

PR Check Results

Benchmark

Linux

group                                      main                                   pr
-----                                      ----                                   --
linter/all-rules/large/dataset.py          1.00     16.0±0.15ms     2.5 MB/sec    1.02     16.3±0.15ms     2.5 MB/sec
linter/all-rules/numpy/ctypeslib.py        1.00      4.0±0.04ms     4.2 MB/sec    1.00      4.0±0.08ms     4.2 MB/sec
linter/all-rules/numpy/globals.py          1.01    487.8±8.17µs     6.0 MB/sec    1.00    482.7±6.04µs     6.1 MB/sec
linter/all-rules/pydantic/types.py         1.00      6.8±0.06ms     3.8 MB/sec    1.00      6.8±0.09ms     3.8 MB/sec
linter/default-rules/large/dataset.py      1.00      8.0±0.06ms     5.1 MB/sec    1.04      8.3±0.07ms     4.9 MB/sec
linter/default-rules/numpy/ctypeslib.py    1.00  1724.1±16.14µs     9.7 MB/sec    1.02  1765.0±19.90µs     9.4 MB/sec
linter/default-rules/numpy/globals.py      1.00    189.6±3.35µs    15.6 MB/sec    1.03    195.5±2.25µs    15.1 MB/sec
linter/default-rules/pydantic/types.py     1.00      3.6±0.04ms     7.0 MB/sec    1.03      3.8±0.04ms     6.8 MB/sec
parser/large/dataset.py                    1.01      6.3±0.07ms     6.5 MB/sec    1.00      6.2±0.05ms     6.6 MB/sec
parser/numpy/ctypeslib.py                  1.00  1205.9±17.70µs    13.8 MB/sec    1.00  1201.7±15.94µs    13.9 MB/sec
parser/numpy/globals.py                    1.01    123.4±1.58µs    23.9 MB/sec    1.00    122.0±1.72µs    24.2 MB/sec
parser/pydantic/types.py                   1.00      2.6±0.03ms     9.7 MB/sec    1.00      2.6±0.03ms     9.6 MB/sec

Windows

group                                      main                                   pr
-----                                      ----                                   --
linter/all-rules/large/dataset.py          1.03     16.6±0.14ms     2.5 MB/sec    1.00     16.1±0.10ms     2.5 MB/sec
linter/all-rules/numpy/ctypeslib.py        1.02      4.2±0.06ms     3.9 MB/sec    1.00      4.2±0.05ms     4.0 MB/sec
linter/all-rules/numpy/globals.py          1.03    501.5±7.65µs     5.9 MB/sec    1.00    487.9±7.98µs     6.0 MB/sec
linter/all-rules/pydantic/types.py         1.02      7.0±0.06ms     3.7 MB/sec    1.00      6.8±0.06ms     3.7 MB/sec
linter/default-rules/large/dataset.py      1.01      8.1±0.05ms     5.0 MB/sec    1.00      8.1±0.08ms     5.1 MB/sec
linter/default-rules/numpy/ctypeslib.py    1.02  1742.6±27.00µs     9.6 MB/sec    1.00  1701.5±14.52µs     9.8 MB/sec
linter/default-rules/numpy/globals.py      1.03    198.1±3.76µs    14.9 MB/sec    1.00    192.8±3.59µs    15.3 MB/sec
linter/default-rules/pydantic/types.py     1.01      3.7±0.03ms     6.9 MB/sec    1.00      3.6±0.07ms     7.0 MB/sec
parser/large/dataset.py                    1.00      6.6±0.04ms     6.2 MB/sec    1.01      6.7±0.04ms     6.1 MB/sec
parser/numpy/ctypeslib.py                  1.00  1261.2±13.35µs    13.2 MB/sec    1.01  1272.9±13.87µs    13.1 MB/sec
parser/numpy/globals.py                    1.00    129.6±3.56µs    22.8 MB/sec    1.00    129.7±1.55µs    22.7 MB/sec
parser/pydantic/types.py                   1.00      2.8±0.03ms     9.1 MB/sec    1.01      2.8±0.02ms     9.0 MB/sec

@inikolaev inikolaev closed this May 15, 2023
@inikolaev inikolaev deleted the inikolaev/4246-implement-flake8-async-plugin branch December 29, 2024 17:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants