Avoid adding duplicate capture_output keyword to subprocess.run (#7113)

This commit is contained in:
Charlie Marsh 2023-09-03 22:14:56 +01:00 committed by GitHub
parent 911d4f2918
commit d70247959c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 95 additions and 23 deletions

View file

@ -35,6 +35,13 @@ if output:
encoding="utf-8",
)
output = subprocess.run(
["foo"], stdout=subprocess.PIPE, capture_output=True, stderr=subprocess.PIPE
)
output = subprocess.run(
["foo"], stdout=subprocess.PIPE, capture_output=False, stderr=subprocess.PIPE
)
# Examples that should NOT trigger the rule
from foo import PIPE

View file

@ -50,29 +50,6 @@ impl AlwaysAutofixableViolation for ReplaceStdoutStderr {
}
}
/// Generate a [`Edit`] for a `stdout` and `stderr` [`Keyword`] pair.
fn generate_fix(
stdout: &Keyword,
stderr: &Keyword,
call: &ast::ExprCall,
source: &str,
) -> Result<Fix> {
let (first, second) = if stdout.start() < stderr.start() {
(stdout, stderr)
} else {
(stderr, stdout)
};
Ok(Fix::suggested_edits(
Edit::range_replacement("capture_output=True".to_string(), first.range()),
[remove_argument(
second,
&call.arguments,
Parentheses::Preserve,
source,
)?],
))
}
/// UP022
pub(crate) fn replace_stdout_stderr(checker: &mut Checker, call: &ast::ExprCall) {
if checker
@ -109,3 +86,41 @@ pub(crate) fn replace_stdout_stderr(checker: &mut Checker, call: &ast::ExprCall)
checker.diagnostics.push(diagnostic);
}
}
/// Generate a [`Edit`] for a `stdout` and `stderr` [`Keyword`] pair.
fn generate_fix(
stdout: &Keyword,
stderr: &Keyword,
call: &ast::ExprCall,
source: &str,
) -> Result<Fix> {
let (first, second) = if stdout.start() < stderr.start() {
(stdout, stderr)
} else {
(stderr, stdout)
};
if call.arguments.find_keyword("capture_output").is_some() {
// Remove both arguments.
Ok(Fix::suggested_edits(
remove_argument(first, &call.arguments, Parentheses::Preserve, source)?,
[remove_argument(
second,
&call.arguments,
Parentheses::Preserve,
source,
)?],
))
} else {
// Replace one argument with `capture_output=True`, and remove the other.
Ok(Fix::suggested_edits(
Edit::range_replacement("capture_output=True".to_string(), first.range()),
[remove_argument(
second,
&call.arguments,
Parentheses::Preserve,
source,
)?],
))
}
}

View file

@ -157,6 +157,8 @@ UP022.py:29:14: UP022 [*] Sending `stdout` and `stderr` to `PIPE` is deprecated,
35 | | encoding="utf-8",
36 | | )
| |_____^ UP022
37 |
38 | output = subprocess.run(
|
= help: Replace with `capture_output` keyword argument
@ -172,4 +174,52 @@ UP022.py:29:14: UP022 [*] Sending `stdout` and `stderr` to `PIPE` is deprecated,
35 34 | encoding="utf-8",
36 35 | )
UP022.py:38:10: UP022 [*] Sending `stdout` and `stderr` to `PIPE` is deprecated, use `capture_output`
|
36 | )
37 |
38 | output = subprocess.run(
| __________^
39 | | ["foo"], stdout=subprocess.PIPE, capture_output=True, stderr=subprocess.PIPE
40 | | )
| |_^ UP022
41 |
42 | output = subprocess.run(
|
= help: Replace with `capture_output` keyword argument
Suggested fix
36 36 | )
37 37 |
38 38 | output = subprocess.run(
39 |- ["foo"], stdout=subprocess.PIPE, capture_output=True, stderr=subprocess.PIPE
39 |+ ["foo"], capture_output=True
40 40 | )
41 41 |
42 42 | output = subprocess.run(
UP022.py:42:10: UP022 [*] Sending `stdout` and `stderr` to `PIPE` is deprecated, use `capture_output`
|
40 | )
41 |
42 | output = subprocess.run(
| __________^
43 | | ["foo"], stdout=subprocess.PIPE, capture_output=False, stderr=subprocess.PIPE
44 | | )
| |_^ UP022
45 |
46 | # Examples that should NOT trigger the rule
|
= help: Replace with `capture_output` keyword argument
Suggested fix
40 40 | )
41 41 |
42 42 | output = subprocess.run(
43 |- ["foo"], stdout=subprocess.PIPE, capture_output=False, stderr=subprocess.PIPE
43 |+ ["foo"], capture_output=False
44 44 | )
45 45 |
46 46 | # Examples that should NOT trigger the rule