Implement F631 (AssertTuple) (#99)

This commit is contained in:
Harutaka Kawamura 2022-09-04 21:39:49 +09:00 committed by GitHub
parent e2f46537fd
commit 312bfd8d2b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 61 additions and 0 deletions

View file

@ -114,6 +114,7 @@ OPTIONS:
| F401 | UnusedImport | `...` imported but unused | | F401 | UnusedImport | `...` imported but unused |
| F403 | ImportStarUsage | Unable to detect undefined names | | F403 | ImportStarUsage | Unable to detect undefined names |
| F541 | FStringMissingPlaceholders | f-string without any placeholders | | F541 | FStringMissingPlaceholders | f-string without any placeholders |
| F631 | AssertTuple | Assert test is a non-empty tuple, which is always `True` |
| F634 | IfTuple | If test is a tuple, which is always `True` | | F634 | IfTuple | If test is a tuple, which is always `True` |
| F704 | YieldOutsideFunction | a `yield` or `yield from` statement outside of a function/method | | F704 | YieldOutsideFunction | a `yield` or `yield from` statement outside of a function/method |
| F706 | ReturnOutsideFunction | a `return` statement outside of a function/method | | F706 | ReturnOutsideFunction | a `return` statement outside of a function/method |

4
resources/test/fixtures/F631.py vendored Normal file
View file

@ -0,0 +1,4 @@
assert (False, "x")
assert (False,)
assert ()
assert True

View file

@ -6,6 +6,7 @@ select = [
"F401", "F401",
"F403", "F403",
"F541", "F541",
"F631",
"F634", "F634",
"F704", "F704",
"F706", "F706",

View file

@ -283,6 +283,18 @@ impl Visitor for Checker<'_> {
} }
} }
StmtKind::AugAssign { target, .. } => self.handle_node_load(target), StmtKind::AugAssign { target, .. } => self.handle_node_load(target),
StmtKind::Assert { test, .. } => {
if self.settings.select.contains(CheckKind::AssertTuple.code()) {
if let ExprKind::Tuple { elts, .. } = &test.node {
if !elts.is_empty() {
self.checks.push(Check {
kind: CheckKind::AssertTuple,
location: stmt.location,
});
}
}
}
}
_ => {} _ => {}
} }

View file

@ -12,6 +12,7 @@ pub enum CheckCode {
F401, F401,
F403, F403,
F541, F541,
F631,
F634, F634,
F704, F704,
F706, F706,
@ -33,6 +34,7 @@ impl FromStr for CheckCode {
"F401" => Ok(CheckCode::F401), "F401" => Ok(CheckCode::F401),
"F403" => Ok(CheckCode::F403), "F403" => Ok(CheckCode::F403),
"F541" => Ok(CheckCode::F541), "F541" => Ok(CheckCode::F541),
"F631" => Ok(CheckCode::F631),
"F634" => Ok(CheckCode::F634), "F634" => Ok(CheckCode::F634),
"F704" => Ok(CheckCode::F704), "F704" => Ok(CheckCode::F704),
"F706" => Ok(CheckCode::F706), "F706" => Ok(CheckCode::F706),
@ -55,6 +57,7 @@ impl CheckCode {
CheckCode::F401 => "F401", CheckCode::F401 => "F401",
CheckCode::F403 => "F403", CheckCode::F403 => "F403",
CheckCode::F541 => "F541", CheckCode::F541 => "F541",
CheckCode::F631 => "F631",
CheckCode::F634 => "F634", CheckCode::F634 => "F634",
CheckCode::F704 => "F704", CheckCode::F704 => "F704",
CheckCode::F706 => "F706", CheckCode::F706 => "F706",
@ -75,6 +78,7 @@ impl CheckCode {
CheckCode::F401 => &LintSource::AST, CheckCode::F401 => &LintSource::AST,
CheckCode::F403 => &LintSource::AST, CheckCode::F403 => &LintSource::AST,
CheckCode::F541 => &LintSource::AST, CheckCode::F541 => &LintSource::AST,
CheckCode::F631 => &LintSource::AST,
CheckCode::F634 => &LintSource::AST, CheckCode::F634 => &LintSource::AST,
CheckCode::F704 => &LintSource::AST, CheckCode::F704 => &LintSource::AST,
CheckCode::F706 => &LintSource::AST, CheckCode::F706 => &LintSource::AST,
@ -99,6 +103,7 @@ pub enum LintSource {
pub enum CheckKind { pub enum CheckKind {
DuplicateArgumentName, DuplicateArgumentName,
FStringMissingPlaceholders, FStringMissingPlaceholders,
AssertTuple,
IfTuple, IfTuple,
ImportStarUsage, ImportStarUsage,
LineTooLong, LineTooLong,
@ -119,6 +124,7 @@ impl CheckKind {
match self { match self {
CheckKind::DuplicateArgumentName => "DuplicateArgumentName", CheckKind::DuplicateArgumentName => "DuplicateArgumentName",
CheckKind::FStringMissingPlaceholders => "FStringMissingPlaceholders", CheckKind::FStringMissingPlaceholders => "FStringMissingPlaceholders",
CheckKind::AssertTuple => "AssertTuple",
CheckKind::IfTuple => "IfTuple", CheckKind::IfTuple => "IfTuple",
CheckKind::ImportStarUsage => "ImportStarUsage", CheckKind::ImportStarUsage => "ImportStarUsage",
CheckKind::LineTooLong => "LineTooLong", CheckKind::LineTooLong => "LineTooLong",
@ -139,6 +145,7 @@ impl CheckKind {
match self { match self {
CheckKind::DuplicateArgumentName => &CheckCode::F831, CheckKind::DuplicateArgumentName => &CheckCode::F831,
CheckKind::FStringMissingPlaceholders => &CheckCode::F541, CheckKind::FStringMissingPlaceholders => &CheckCode::F541,
CheckKind::AssertTuple => &CheckCode::F631,
CheckKind::IfTuple => &CheckCode::F634, CheckKind::IfTuple => &CheckCode::F634,
CheckKind::ImportStarUsage => &CheckCode::F403, CheckKind::ImportStarUsage => &CheckCode::F403,
CheckKind::LineTooLong => &CheckCode::E501, CheckKind::LineTooLong => &CheckCode::E501,
@ -163,6 +170,9 @@ impl CheckKind {
CheckKind::FStringMissingPlaceholders => { CheckKind::FStringMissingPlaceholders => {
"f-string without any placeholders".to_string() "f-string without any placeholders".to_string()
} }
CheckKind::AssertTuple => {
"Assert test is a non-empty tuple, which is always `True`".to_string()
}
CheckKind::IfTuple => "If test is a tuple, which is always `True`".to_string(), CheckKind::IfTuple => "If test is a tuple, which is always `True`".to_string(),
CheckKind::ImportStarUsage => "Unable to detect undefined names".to_string(), CheckKind::ImportStarUsage => "Unable to detect undefined names".to_string(),
CheckKind::LineTooLong => "Line too long".to_string(), CheckKind::LineTooLong => "Line too long".to_string(),

View file

@ -191,6 +191,37 @@ mod tests {
Ok(()) Ok(())
} }
#[test]
fn f631() -> Result<()> {
let actual = check_path(
Path::new("./resources/test/fixtures/F631.py"),
&settings::Settings {
line_length: 88,
exclude: vec![],
select: BTreeSet::from([CheckCode::F631]),
},
&cache::Mode::None,
)?;
let expected = vec![
Message {
kind: CheckKind::AssertTuple,
location: Location::new(1, 1),
filename: "./resources/test/fixtures/F631.py".to_string(),
},
Message {
kind: CheckKind::AssertTuple,
location: Location::new(2, 1),
filename: "./resources/test/fixtures/F631.py".to_string(),
},
];
assert_eq!(actual.len(), expected.len());
for i in 0..actual.len() {
assert_eq!(actual[i], expected[i]);
}
Ok(())
}
#[test] #[test]
fn f634() -> Result<()> { fn f634() -> Result<()> {
let actual = check_path( let actual = check_path(

View file

@ -241,6 +241,7 @@ other-attribute = 1
CheckCode::F401, CheckCode::F401,
CheckCode::F403, CheckCode::F403,
CheckCode::F541, CheckCode::F541,
CheckCode::F631,
CheckCode::F634, CheckCode::F634,
CheckCode::F704, CheckCode::F704,
CheckCode::F706, CheckCode::F706,

View file

@ -48,6 +48,7 @@ impl Settings {
CheckCode::F401, CheckCode::F401,
CheckCode::F403, CheckCode::F403,
CheckCode::F541, CheckCode::F541,
CheckCode::F631,
CheckCode::F634, CheckCode::F634,
CheckCode::F706, CheckCode::F706,
CheckCode::F831, CheckCode::F831,