mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 10:48:32 +00:00
[flake8-bugbear
] Offer unsafe autofix for no-explicit-stacklevel
(B028
) (#14829)
This PR introduces an unsafe autofix for [no-explicit-stacklevel (B028)](https://docs.astral.sh/ruff/rules/no-explicit-stacklevel/#no-explicit-stacklevel-b028): we add the `stacklevel` argument, set to `2`. Closes #14805
This commit is contained in:
parent
2c13e6513d
commit
d34013425f
3 changed files with 74 additions and 9 deletions
|
@ -9,3 +9,9 @@ warnings.warn(DeprecationWarning("test"))
|
|||
warnings.warn(DeprecationWarning("test"), source=None)
|
||||
warnings.warn(DeprecationWarning("test"), source=None, stacklevel=2)
|
||||
warnings.warn(DeprecationWarning("test"), stacklevel=1)
|
||||
|
||||
warnings.warn(
|
||||
DeprecationWarning("test"),
|
||||
# some comments here
|
||||
source = None # no trailing comma
|
||||
)
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix};
|
||||
use ruff_macros::{derive_message_formats, ViolationMetadata};
|
||||
use ruff_python_ast::{self as ast};
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::{checkers::ast::Checker, fix::edits::add_argument};
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for `warnings.warn` calls without an explicit `stacklevel` keyword
|
||||
|
@ -28,16 +28,26 @@ use crate::checkers::ast::Checker;
|
|||
/// warnings.warn("This is a warning", stacklevel=2)
|
||||
/// ```
|
||||
///
|
||||
/// ## Fix safety
|
||||
/// This rule's fix is marked as unsafe because it changes
|
||||
/// the behavior of the code. Moreover, the fix will assign
|
||||
/// a stacklevel of 2, while the user may wish to assign a
|
||||
/// higher stacklevel to address the diagnostic.
|
||||
///
|
||||
/// ## References
|
||||
/// - [Python documentation: `warnings.warn`](https://docs.python.org/3/library/warnings.html#warnings.warn)
|
||||
#[derive(ViolationMetadata)]
|
||||
pub(crate) struct NoExplicitStacklevel;
|
||||
|
||||
impl Violation for NoExplicitStacklevel {
|
||||
impl AlwaysFixableViolation for NoExplicitStacklevel {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
"No explicit `stacklevel` keyword argument found".to_string()
|
||||
}
|
||||
|
||||
fn fix_title(&self) -> String {
|
||||
"Set `stacklevel=2`".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
/// B028
|
||||
|
@ -53,8 +63,16 @@ pub(crate) fn no_explicit_stacklevel(checker: &mut Checker, call: &ast::ExprCall
|
|||
if call.arguments.find_keyword("stacklevel").is_some() {
|
||||
return;
|
||||
}
|
||||
let mut diagnostic = Diagnostic::new(NoExplicitStacklevel, call.func.range());
|
||||
|
||||
checker
|
||||
.diagnostics
|
||||
.push(Diagnostic::new(NoExplicitStacklevel, call.func.range()));
|
||||
let edit = add_argument(
|
||||
"stacklevel=2",
|
||||
&call.arguments,
|
||||
checker.comment_ranges(),
|
||||
checker.locator().contents(),
|
||||
);
|
||||
|
||||
diagnostic.set_fix(Fix::unsafe_edit(edit));
|
||||
|
||||
checker.diagnostics.push(diagnostic);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_bugbear/mod.rs
|
||||
snapshot_kind: text
|
||||
---
|
||||
B028.py:8:1: B028 No explicit `stacklevel` keyword argument found
|
||||
B028.py:8:1: B028 [*] No explicit `stacklevel` keyword argument found
|
||||
|
|
||||
6 | """
|
||||
7 |
|
||||
|
@ -11,8 +10,19 @@ B028.py:8:1: B028 No explicit `stacklevel` keyword argument found
|
|||
9 | warnings.warn(DeprecationWarning("test"), source=None)
|
||||
10 | warnings.warn(DeprecationWarning("test"), source=None, stacklevel=2)
|
||||
|
|
||||
= help: Set `stacklevel=2`
|
||||
|
||||
B028.py:9:1: B028 No explicit `stacklevel` keyword argument found
|
||||
ℹ Unsafe fix
|
||||
5 5 | B028 - on lines 8 and 9
|
||||
6 6 | """
|
||||
7 7 |
|
||||
8 |-warnings.warn(DeprecationWarning("test"))
|
||||
8 |+warnings.warn(DeprecationWarning("test"), stacklevel=2)
|
||||
9 9 | warnings.warn(DeprecationWarning("test"), source=None)
|
||||
10 10 | warnings.warn(DeprecationWarning("test"), source=None, stacklevel=2)
|
||||
11 11 | warnings.warn(DeprecationWarning("test"), stacklevel=1)
|
||||
|
||||
B028.py:9:1: B028 [*] No explicit `stacklevel` keyword argument found
|
||||
|
|
||||
8 | warnings.warn(DeprecationWarning("test"))
|
||||
9 | warnings.warn(DeprecationWarning("test"), source=None)
|
||||
|
@ -20,3 +30,34 @@ B028.py:9:1: B028 No explicit `stacklevel` keyword argument found
|
|||
10 | warnings.warn(DeprecationWarning("test"), source=None, stacklevel=2)
|
||||
11 | warnings.warn(DeprecationWarning("test"), stacklevel=1)
|
||||
|
|
||||
= help: Set `stacklevel=2`
|
||||
|
||||
ℹ Unsafe fix
|
||||
6 6 | """
|
||||
7 7 |
|
||||
8 8 | warnings.warn(DeprecationWarning("test"))
|
||||
9 |-warnings.warn(DeprecationWarning("test"), source=None)
|
||||
10 9 | warnings.warn(DeprecationWarning("test"), source=None, stacklevel=2)
|
||||
10 |+warnings.warn(DeprecationWarning("test"), source=None, stacklevel=2)
|
||||
11 11 | warnings.warn(DeprecationWarning("test"), stacklevel=1)
|
||||
12 12 |
|
||||
13 13 | warnings.warn(
|
||||
|
||||
B028.py:13:1: B028 [*] No explicit `stacklevel` keyword argument found
|
||||
|
|
||||
11 | warnings.warn(DeprecationWarning("test"), stacklevel=1)
|
||||
12 |
|
||||
13 | warnings.warn(
|
||||
| ^^^^^^^^^^^^^ B028
|
||||
14 | DeprecationWarning("test"),
|
||||
15 | # some comments here
|
||||
|
|
||||
= help: Set `stacklevel=2`
|
||||
|
||||
ℹ Unsafe fix
|
||||
13 13 | warnings.warn(
|
||||
14 14 | DeprecationWarning("test"),
|
||||
15 15 | # some comments here
|
||||
16 |- source = None # no trailing comma
|
||||
16 |+ source = None, stacklevel=2 # no trailing comma
|
||||
17 17 | )
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue