mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-27 04:19:43 +00:00
Implement B014 from flake8-bugbear (#392)
This commit is contained in:
parent
c384fa513b
commit
35f593846e
12 changed files with 226 additions and 166 deletions
|
@ -216,7 +216,7 @@ ruff also implements some of the most popular Flake8 plugins natively, including
|
||||||
- [`flake8-super`](https://pypi.org/project/flake8-super/)
|
- [`flake8-super`](https://pypi.org/project/flake8-super/)
|
||||||
- [`flake8-print`](https://pypi.org/project/flake8-print/)
|
- [`flake8-print`](https://pypi.org/project/flake8-print/)
|
||||||
- [`flake8-comprehensions`](https://pypi.org/project/flake8-comprehensions/) (11/16)
|
- [`flake8-comprehensions`](https://pypi.org/project/flake8-comprehensions/) (11/16)
|
||||||
- [`flake8-bugbear`](https://pypi.org/project/flake8-bugbear/) (2/32)
|
- [`flake8-bugbear`](https://pypi.org/project/flake8-bugbear/) (3/32)
|
||||||
- [`pyupgrade`](https://pypi.org/project/pyupgrade/) (partial)
|
- [`pyupgrade`](https://pypi.org/project/pyupgrade/) (partial)
|
||||||
|
|
||||||
Beyond rule-set parity, ruff suffers from the following limitations vis-à-vis Flake8:
|
Beyond rule-set parity, ruff suffers from the following limitations vis-à-vis Flake8:
|
||||||
|
@ -280,7 +280,8 @@ The 🛠 emoji indicates that a rule is automatically fixable by the `--fix` com
|
||||||
| A002 | BuiltinArgumentShadowing | Argument `...` is shadowing a python builtin | | |
|
| A002 | BuiltinArgumentShadowing | Argument `...` is shadowing a python builtin | | |
|
||||||
| A003 | BuiltinAttributeShadowing | Class attribute `...` is shadowing a python builtin | | |
|
| A003 | BuiltinAttributeShadowing | Class attribute `...` is shadowing a python builtin | | |
|
||||||
| B011 | DoNotAssertFalse | Do not `assert False` (`python -O` removes these calls), raise `AssertionError()` | | 🛠 |
|
| B011 | DoNotAssertFalse | Do not `assert False` (`python -O` removes these calls), raise `AssertionError()` | | 🛠 |
|
||||||
| B025 | DuplicateExceptions | try-except block with duplicate exception `Exception` | | |
|
| B014 | DuplicateHandlerException | Exception handler with duplicate exception `Exception` | | |
|
||||||
|
| B025 | DuplicateTryBlockException | try-except block with duplicate exception `Exception` | | |
|
||||||
| C400 | UnnecessaryGeneratorList | Unnecessary generator - rewrite as a list comprehension | | |
|
| C400 | UnnecessaryGeneratorList | Unnecessary generator - rewrite as a list comprehension | | |
|
||||||
| C401 | UnnecessaryGeneratorSet | Unnecessary generator - rewrite as a set comprehension | | |
|
| C401 | UnnecessaryGeneratorSet | Unnecessary generator - rewrite as a set comprehension | | |
|
||||||
| C402 | UnnecessaryGeneratorDict | Unnecessary generator - rewrite as a dict comprehension | | |
|
| C402 | UnnecessaryGeneratorDict | Unnecessary generator - rewrite as a dict comprehension | | |
|
||||||
|
|
76
resources/test/fixtures/B014.py
vendored
Normal file
76
resources/test/fixtures/B014.py
vendored
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
"""
|
||||||
|
Should emit:
|
||||||
|
B014 - on lines 11, 17, 28, 42, 49, 56, and 74.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import binascii
|
||||||
|
import re
|
||||||
|
|
||||||
|
try:
|
||||||
|
pass
|
||||||
|
except (Exception, TypeError):
|
||||||
|
# TypeError is a subclass of Exception, so it doesn't add anything
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
pass
|
||||||
|
except (OSError, OSError) as err:
|
||||||
|
# Duplicate exception types are useless
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class MyError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
pass
|
||||||
|
except (MyError, MyError):
|
||||||
|
# Detect duplicate non-builtin errors
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
pass
|
||||||
|
except (MyError, Exception) as e:
|
||||||
|
# Don't assume that we're all subclasses of Exception
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
pass
|
||||||
|
except (MyError, BaseException) as e:
|
||||||
|
# But we *can* assume that everything is a subclass of BaseException
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
pass
|
||||||
|
except (re.error, re.error):
|
||||||
|
# Duplicate exception types as attributes
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
pass
|
||||||
|
except (IOError, EnvironmentError, OSError):
|
||||||
|
# Detect if a primary exception and any its aliases are present.
|
||||||
|
#
|
||||||
|
# Since Python 3.3, IOError, EnvironmentError, WindowsError, mmap.error,
|
||||||
|
# socket.error and select.error are aliases of OSError. See PEP 3151 for
|
||||||
|
# more info.
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
pass
|
||||||
|
except (MyException, NotImplemented):
|
||||||
|
# NotImplemented is not an exception, let's not crash on it.
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
pass
|
||||||
|
except (ValueError, binascii.Error):
|
||||||
|
# binascii.Error is a subclass of ValueError.
|
||||||
|
pass
|
|
@ -1,7 +1,6 @@
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
|
|
||||||
use crate::ast::helpers;
|
use itertools::izip;
|
||||||
use itertools::{izip, Itertools};
|
|
||||||
use num_bigint::BigInt;
|
use num_bigint::BigInt;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use rustpython_parser::ast::{
|
use rustpython_parser::ast::{
|
||||||
|
@ -10,6 +9,7 @@ use rustpython_parser::ast::{
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::ast::helpers;
|
||||||
use crate::ast::types::{
|
use crate::ast::types::{
|
||||||
Binding, BindingKind, CheckLocator, FunctionScope, Range, Scope, ScopeKind,
|
Binding, BindingKind, CheckLocator, FunctionScope, Range, Scope, ScopeKind,
|
||||||
};
|
};
|
||||||
|
@ -748,57 +748,6 @@ pub fn check_builtin_shadowing(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// flake8-bugbear
|
|
||||||
/// Check DuplicateExceptions compliance.
|
|
||||||
pub fn duplicate_exceptions(handlers: &[Excepthandler], location: Range) -> Vec<Check> {
|
|
||||||
let mut checks: Vec<Check> = vec![];
|
|
||||||
|
|
||||||
let mut seen: BTreeSet<String> = Default::default();
|
|
||||||
let mut duplicates: BTreeSet<String> = Default::default();
|
|
||||||
for handler in handlers {
|
|
||||||
match &handler.node {
|
|
||||||
ExcepthandlerKind::ExceptHandler { type_, .. } => {
|
|
||||||
if let Some(type_) = type_ {
|
|
||||||
match &type_.node {
|
|
||||||
ExprKind::Attribute { .. } | ExprKind::Name { .. } => {
|
|
||||||
if let Some(name) = helpers::compose_call_path(type_) {
|
|
||||||
if seen.contains(&name) {
|
|
||||||
duplicates.insert(name);
|
|
||||||
} else {
|
|
||||||
seen.insert(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ExprKind::Tuple { elts, .. } => {
|
|
||||||
// TODO(charlie): If we have duplicates within a single handler, that
|
|
||||||
// should be handled by B014 (as yet unimplemented).
|
|
||||||
for type_ in elts {
|
|
||||||
if let Some(name) = helpers::compose_call_path(type_) {
|
|
||||||
if seen.contains(&name) {
|
|
||||||
duplicates.insert(name);
|
|
||||||
} else {
|
|
||||||
seen.insert(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for duplicate in duplicates.into_iter().sorted() {
|
|
||||||
checks.push(Check::new(
|
|
||||||
CheckKind::DuplicateExceptions(duplicate),
|
|
||||||
location,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
checks
|
|
||||||
}
|
|
||||||
|
|
||||||
// flake8-comprehensions
|
// flake8-comprehensions
|
||||||
/// Check `list(generator)` compliance.
|
/// Check `list(generator)` compliance.
|
||||||
pub fn unnecessary_generator_list(expr: &Expr, func: &Expr, args: &Vec<Expr>) -> Option<Check> {
|
pub fn unnecessary_generator_list(expr: &Expr, func: &Expr, args: &Vec<Expr>) -> Option<Check> {
|
||||||
|
|
|
@ -562,11 +562,10 @@ where
|
||||||
self.checks.push(check);
|
self.checks.push(check);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if self.settings.enabled.contains(&CheckCode::B025) {
|
if self.settings.enabled.contains(&CheckCode::B014)
|
||||||
self.checks.extend(checks::duplicate_exceptions(
|
|| self.settings.enabled.contains(&CheckCode::B025)
|
||||||
handlers,
|
{
|
||||||
self.locate_check(Range::from_located(stmt)),
|
plugins::duplicate_exceptions(self, stmt, handlers);
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StmtKind::Assign { targets, value, .. } => {
|
StmtKind::Assign { targets, value, .. } => {
|
||||||
|
|
|
@ -123,6 +123,7 @@ pub enum CheckCode {
|
||||||
A003,
|
A003,
|
||||||
// flake8-bugbear
|
// flake8-bugbear
|
||||||
B011,
|
B011,
|
||||||
|
B014,
|
||||||
B025,
|
B025,
|
||||||
// flake8-comprehensions
|
// flake8-comprehensions
|
||||||
C400,
|
C400,
|
||||||
|
@ -218,7 +219,8 @@ pub enum CheckKind {
|
||||||
BuiltinAttributeShadowing(String),
|
BuiltinAttributeShadowing(String),
|
||||||
// flake8-bugbear
|
// flake8-bugbear
|
||||||
DoNotAssertFalse,
|
DoNotAssertFalse,
|
||||||
DuplicateExceptions(String),
|
DuplicateHandlerException(String),
|
||||||
|
DuplicateTryBlockException(String),
|
||||||
// flake8-comprehensions
|
// flake8-comprehensions
|
||||||
UnnecessaryGeneratorList,
|
UnnecessaryGeneratorList,
|
||||||
UnnecessaryGeneratorSet,
|
UnnecessaryGeneratorSet,
|
||||||
|
@ -314,7 +316,8 @@ impl CheckCode {
|
||||||
CheckCode::A003 => CheckKind::BuiltinAttributeShadowing("...".to_string()),
|
CheckCode::A003 => CheckKind::BuiltinAttributeShadowing("...".to_string()),
|
||||||
// flake8-bugbear
|
// flake8-bugbear
|
||||||
CheckCode::B011 => CheckKind::DoNotAssertFalse,
|
CheckCode::B011 => CheckKind::DoNotAssertFalse,
|
||||||
CheckCode::B025 => CheckKind::DuplicateExceptions("Exception".to_string()),
|
CheckCode::B014 => CheckKind::DuplicateHandlerException("Exception".to_string()),
|
||||||
|
CheckCode::B025 => CheckKind::DuplicateTryBlockException("Exception".to_string()),
|
||||||
// flake8-comprehensions
|
// flake8-comprehensions
|
||||||
CheckCode::C400 => CheckKind::UnnecessaryGeneratorList,
|
CheckCode::C400 => CheckKind::UnnecessaryGeneratorList,
|
||||||
CheckCode::C401 => CheckKind::UnnecessaryGeneratorSet,
|
CheckCode::C401 => CheckKind::UnnecessaryGeneratorSet,
|
||||||
|
@ -411,7 +414,8 @@ impl CheckKind {
|
||||||
CheckKind::BuiltinAttributeShadowing(_) => &CheckCode::A003,
|
CheckKind::BuiltinAttributeShadowing(_) => &CheckCode::A003,
|
||||||
// flake8-bugbear
|
// flake8-bugbear
|
||||||
CheckKind::DoNotAssertFalse => &CheckCode::B011,
|
CheckKind::DoNotAssertFalse => &CheckCode::B011,
|
||||||
CheckKind::DuplicateExceptions(_) => &CheckCode::B025,
|
CheckKind::DuplicateHandlerException(_) => &CheckCode::B014,
|
||||||
|
CheckKind::DuplicateTryBlockException(_) => &CheckCode::B025,
|
||||||
// flake8-comprehensions
|
// flake8-comprehensions
|
||||||
CheckKind::UnnecessaryGeneratorList => &CheckCode::C400,
|
CheckKind::UnnecessaryGeneratorList => &CheckCode::C400,
|
||||||
CheckKind::UnnecessaryGeneratorSet => &CheckCode::C401,
|
CheckKind::UnnecessaryGeneratorSet => &CheckCode::C401,
|
||||||
|
@ -589,7 +593,10 @@ impl CheckKind {
|
||||||
"Do not `assert False` (`python -O` removes these calls), raise `AssertionError()`"
|
"Do not `assert False` (`python -O` removes these calls), raise `AssertionError()`"
|
||||||
.to_string()
|
.to_string()
|
||||||
}
|
}
|
||||||
CheckKind::DuplicateExceptions(name) => {
|
CheckKind::DuplicateHandlerException(name) => {
|
||||||
|
format!("Exception handler with duplicate exception `{name}`")
|
||||||
|
}
|
||||||
|
CheckKind::DuplicateTryBlockException(name) => {
|
||||||
format!("try-except block with duplicate exception `{name}`")
|
format!("try-except block with duplicate exception `{name}`")
|
||||||
}
|
}
|
||||||
// flake8-comprehensions
|
// flake8-comprehensions
|
||||||
|
|
|
@ -822,6 +822,18 @@ mod tests {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn b014() -> Result<()> {
|
||||||
|
let mut checks = check_path(
|
||||||
|
Path::new("./resources/test/fixtures/B014.py"),
|
||||||
|
&settings::Settings::for_rule(CheckCode::B014),
|
||||||
|
&fixer::Mode::Generate,
|
||||||
|
)?;
|
||||||
|
checks.sort_by_key(|check| check.location);
|
||||||
|
insta::assert_yaml_snapshot!(checks);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn b025() -> Result<()> {
|
fn b025() -> Result<()> {
|
||||||
let mut checks = check_path(
|
let mut checks = check_path(
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
pub use assert_false::assert_false;
|
pub use assert_false::assert_false;
|
||||||
pub use assert_tuple::assert_tuple;
|
pub use assert_tuple::assert_tuple;
|
||||||
pub use deprecated_unittest_alias::deprecated_unittest_alias;
|
pub use deprecated_unittest_alias::deprecated_unittest_alias;
|
||||||
|
pub use duplicate_exceptions::duplicate_exceptions;
|
||||||
pub use if_tuple::if_tuple;
|
pub use if_tuple::if_tuple;
|
||||||
pub use invalid_print_syntax::invalid_print_syntax;
|
pub use invalid_print_syntax::invalid_print_syntax;
|
||||||
pub use print_call::print_call;
|
pub use print_call::print_call;
|
||||||
|
@ -15,6 +16,7 @@ pub use useless_object_inheritance::useless_object_inheritance;
|
||||||
mod assert_false;
|
mod assert_false;
|
||||||
mod assert_tuple;
|
mod assert_tuple;
|
||||||
mod deprecated_unittest_alias;
|
mod deprecated_unittest_alias;
|
||||||
|
mod duplicate_exceptions;
|
||||||
mod if_tuple;
|
mod if_tuple;
|
||||||
mod invalid_print_syntax;
|
mod invalid_print_syntax;
|
||||||
mod print_call;
|
mod print_call;
|
||||||
|
|
|
@ -1,61 +1,82 @@
|
||||||
use rustpython_ast::{Constant, Expr, ExprContext, ExprKind, Stmt, StmtKind};
|
use itertools::Itertools;
|
||||||
|
use std::collections::BTreeSet;
|
||||||
|
|
||||||
use crate::ast::types::Range;
|
use rustpython_ast::{Excepthandler, ExcepthandlerKind, Expr, ExprKind, Stmt};
|
||||||
use crate::autofix::fixer;
|
|
||||||
|
use crate::ast::helpers;
|
||||||
|
use crate::ast::types::{CheckLocator, Range};
|
||||||
use crate::check_ast::Checker;
|
use crate::check_ast::Checker;
|
||||||
use crate::checks::{Check, CheckKind, Fix};
|
use crate::checks::{Check, CheckCode, CheckKind};
|
||||||
use crate::code_gen::SourceGenerator;
|
|
||||||
|
|
||||||
fn assertion_error(msg: &Option<Box<Expr>>) -> Stmt {
|
pub fn duplicate_handler_exceptions(
|
||||||
Stmt::new(
|
checker: &mut Checker,
|
||||||
Default::default(),
|
stmt: &Stmt,
|
||||||
Default::default(),
|
elts: &Vec<Expr>,
|
||||||
StmtKind::Raise {
|
) -> BTreeSet<String> {
|
||||||
exc: Some(Box::new(Expr::new(
|
let mut seen: BTreeSet<String> = Default::default();
|
||||||
Default::default(),
|
let mut duplicates: BTreeSet<String> = Default::default();
|
||||||
Default::default(),
|
for type_ in elts {
|
||||||
ExprKind::Call {
|
if let Some(name) = helpers::compose_call_path(type_) {
|
||||||
func: Box::new(Expr::new(
|
if seen.contains(&name) {
|
||||||
Default::default(),
|
duplicates.insert(name);
|
||||||
Default::default(),
|
} else {
|
||||||
ExprKind::Name {
|
seen.insert(name);
|
||||||
id: "AssertionError".to_string(),
|
}
|
||||||
ctx: ExprContext::Load,
|
}
|
||||||
},
|
}
|
||||||
)),
|
|
||||||
args: if let Some(msg) = msg {
|
if checker.settings.enabled.contains(&CheckCode::B014) {
|
||||||
vec![*msg.clone()]
|
// TODO(charlie): Handle "BaseException" and redundant exception aliases.
|
||||||
} else {
|
for duplicate in duplicates.into_iter().sorted() {
|
||||||
vec![]
|
checker.add_check(Check::new(
|
||||||
},
|
CheckKind::DuplicateHandlerException(duplicate),
|
||||||
keywords: vec![],
|
checker.locate_check(Range::from_located(stmt)),
|
||||||
},
|
));
|
||||||
))),
|
}
|
||||||
cause: None,
|
}
|
||||||
},
|
|
||||||
)
|
seen
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn assert_false(checker: &mut Checker, stmt: &Stmt, test: &Expr, msg: &Option<Box<Expr>>) {
|
pub fn duplicate_exceptions(checker: &mut Checker, stmt: &Stmt, handlers: &[Excepthandler]) {
|
||||||
if let ExprKind::Constant {
|
let mut seen: BTreeSet<String> = Default::default();
|
||||||
value: Constant::Bool(false),
|
let mut duplicates: BTreeSet<String> = Default::default();
|
||||||
..
|
for handler in handlers {
|
||||||
} = &test.node
|
match &handler.node {
|
||||||
{
|
ExcepthandlerKind::ExceptHandler { type_, .. } => {
|
||||||
let mut check = Check::new(CheckKind::DoNotAssertFalse, Range::from_located(test));
|
if let Some(type_) = type_ {
|
||||||
if matches!(checker.autofix, fixer::Mode::Generate | fixer::Mode::Apply) {
|
match &type_.node {
|
||||||
let mut generator = SourceGenerator::new();
|
ExprKind::Attribute { .. } | ExprKind::Name { .. } => {
|
||||||
if let Ok(()) = generator.unparse_stmt(&assertion_error(msg)) {
|
if let Some(name) = helpers::compose_call_path(type_) {
|
||||||
if let Ok(content) = generator.generate() {
|
if seen.contains(&name) {
|
||||||
check.amend(Fix {
|
duplicates.insert(name);
|
||||||
content,
|
} else {
|
||||||
location: stmt.location,
|
seen.insert(name);
|
||||||
end_location: stmt.end_location,
|
}
|
||||||
applied: false,
|
}
|
||||||
})
|
}
|
||||||
|
ExprKind::Tuple { elts, .. } => {
|
||||||
|
for name in duplicate_handler_exceptions(checker, stmt, elts) {
|
||||||
|
if seen.contains(&name) {
|
||||||
|
duplicates.insert(name);
|
||||||
|
} else {
|
||||||
|
seen.insert(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checker.add_check(check);
|
}
|
||||||
|
|
||||||
|
if checker.settings.enabled.contains(&CheckCode::B025) {
|
||||||
|
for duplicate in duplicates.into_iter().sorted() {
|
||||||
|
checker.add_check(Check::new(
|
||||||
|
CheckKind::DuplicateTryBlockException(duplicate),
|
||||||
|
checker.locate_check(Range::from_located(stmt)),
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,34 +4,34 @@ expression: checks
|
||||||
---
|
---
|
||||||
- kind: DoNotAssertFalse
|
- kind: DoNotAssertFalse
|
||||||
location:
|
location:
|
||||||
row: 2
|
row: 8
|
||||||
column: 8
|
column: 8
|
||||||
end_location:
|
end_location:
|
||||||
row: 2
|
row: 8
|
||||||
column: 13
|
column: 13
|
||||||
fix:
|
fix:
|
||||||
content: raise AssertionError()
|
content: raise AssertionError()
|
||||||
location:
|
location:
|
||||||
row: 2
|
row: 8
|
||||||
column: 1
|
column: 1
|
||||||
end_location:
|
end_location:
|
||||||
row: 2
|
row: 8
|
||||||
column: 13
|
column: 13
|
||||||
applied: false
|
applied: false
|
||||||
- kind: DoNotAssertFalse
|
- kind: DoNotAssertFalse
|
||||||
location:
|
location:
|
||||||
row: 4
|
row: 10
|
||||||
column: 8
|
column: 8
|
||||||
end_location:
|
end_location:
|
||||||
row: 4
|
row: 10
|
||||||
column: 13
|
column: 13
|
||||||
fix:
|
fix:
|
||||||
content: "raise AssertionError(\"message\")"
|
content: "raise AssertionError(\"message\")"
|
||||||
location:
|
location:
|
||||||
row: 4
|
row: 10
|
||||||
column: 1
|
column: 1
|
||||||
end_location:
|
end_location:
|
||||||
row: 4
|
row: 10
|
||||||
column: 24
|
column: 24
|
||||||
applied: false
|
applied: false
|
||||||
|
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
---
|
|
||||||
source: src/linter.rs
|
|
||||||
assertion_line: 821
|
|
||||||
expression: checks
|
|
||||||
---
|
|
||||||
- kind: DoNotAssertFalse
|
|
||||||
location:
|
|
||||||
row: 8
|
|
||||||
column: 8
|
|
||||||
end_location:
|
|
||||||
row: 8
|
|
||||||
column: 13
|
|
||||||
fix:
|
|
||||||
content: raise AssertionError()
|
|
||||||
location:
|
|
||||||
row: 8
|
|
||||||
column: 1
|
|
||||||
end_location:
|
|
||||||
row: 8
|
|
||||||
column: 13
|
|
||||||
applied: false
|
|
||||||
- kind: DoNotAssertFalse
|
|
||||||
location:
|
|
||||||
row: 10
|
|
||||||
column: 8
|
|
||||||
end_location:
|
|
||||||
row: 10
|
|
||||||
column: 13
|
|
||||||
fix:
|
|
||||||
content: "raise AssertionError(\"message\")"
|
|
||||||
location:
|
|
||||||
row: 10
|
|
||||||
column: 1
|
|
||||||
end_location:
|
|
||||||
row: 10
|
|
||||||
column: 24
|
|
||||||
applied: false
|
|
||||||
|
|
32
src/snapshots/ruff__linter__tests__b014.snap
Normal file
32
src/snapshots/ruff__linter__tests__b014.snap
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
---
|
||||||
|
source: src/linter.rs
|
||||||
|
expression: checks
|
||||||
|
---
|
||||||
|
- kind:
|
||||||
|
DuplicateHandlerException: OSError
|
||||||
|
location:
|
||||||
|
row: 15
|
||||||
|
column: 1
|
||||||
|
end_location:
|
||||||
|
row: 22
|
||||||
|
column: 1
|
||||||
|
fix: ~
|
||||||
|
- kind:
|
||||||
|
DuplicateHandlerException: MyError
|
||||||
|
location:
|
||||||
|
row: 26
|
||||||
|
column: 1
|
||||||
|
end_location:
|
||||||
|
row: 33
|
||||||
|
column: 1
|
||||||
|
fix: ~
|
||||||
|
- kind:
|
||||||
|
DuplicateHandlerException: re.error
|
||||||
|
location:
|
||||||
|
row: 47
|
||||||
|
column: 1
|
||||||
|
end_location:
|
||||||
|
row: 54
|
||||||
|
column: 1
|
||||||
|
fix: ~
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
---
|
---
|
||||||
source: src/linter.rs
|
source: src/linter.rs
|
||||||
assertion_line: 833
|
|
||||||
expression: checks
|
expression: checks
|
||||||
---
|
---
|
||||||
- kind:
|
- kind:
|
||||||
DuplicateExceptions: ValueError
|
DuplicateTryBlockException: ValueError
|
||||||
location:
|
location:
|
||||||
row: 15
|
row: 15
|
||||||
column: 1
|
column: 1
|
||||||
|
@ -13,7 +12,7 @@ expression: checks
|
||||||
column: 1
|
column: 1
|
||||||
fix: ~
|
fix: ~
|
||||||
- kind:
|
- kind:
|
||||||
DuplicateExceptions: pickle.PickleError
|
DuplicateTryBlockException: pickle.PickleError
|
||||||
location:
|
location:
|
||||||
row: 22
|
row: 22
|
||||||
column: 1
|
column: 1
|
||||||
|
@ -22,7 +21,7 @@ expression: checks
|
||||||
column: 1
|
column: 1
|
||||||
fix: ~
|
fix: ~
|
||||||
- kind:
|
- kind:
|
||||||
DuplicateExceptions: TypeError
|
DuplicateTryBlockException: TypeError
|
||||||
location:
|
location:
|
||||||
row: 31
|
row: 31
|
||||||
column: 1
|
column: 1
|
||||||
|
@ -31,7 +30,7 @@ expression: checks
|
||||||
column: 1
|
column: 1
|
||||||
fix: ~
|
fix: ~
|
||||||
- kind:
|
- kind:
|
||||||
DuplicateExceptions: ValueError
|
DuplicateTryBlockException: ValueError
|
||||||
location:
|
location:
|
||||||
row: 31
|
row: 31
|
||||||
column: 1
|
column: 1
|
Loading…
Add table
Add a link
Reference in a new issue