mirror of https://github.com/astral-sh/ruff
Implement F901
This commit is contained in:
parent
8d0d0bed0d
commit
ac0eeee2a3
|
|
@ -0,0 +1,6 @@
|
||||||
|
def f() -> None:
|
||||||
|
raise NotImplemented()
|
||||||
|
|
||||||
|
|
||||||
|
def g() -> None:
|
||||||
|
raise NotImplemented
|
||||||
|
|
@ -50,6 +50,37 @@ impl Visitor for Checker<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
StmtKind::Raise { exc, .. } => {
|
||||||
|
if self
|
||||||
|
.settings
|
||||||
|
.select
|
||||||
|
.contains(CheckKind::RaiseNotImplemented.code())
|
||||||
|
{
|
||||||
|
if let Some(expr) = exc {
|
||||||
|
match &expr.node {
|
||||||
|
ExprKind::Call { func, .. } => {
|
||||||
|
if let ExprKind::Name { id, .. } = &func.node {
|
||||||
|
if id == "NotImplemented" {
|
||||||
|
self.checks.push(Check {
|
||||||
|
kind: CheckKind::RaiseNotImplemented,
|
||||||
|
location: stmt.location,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ExprKind::Name { id, .. } => {
|
||||||
|
if id == "NotImplemented" {
|
||||||
|
self.checks.push(Check {
|
||||||
|
kind: CheckKind::RaiseNotImplemented,
|
||||||
|
location: stmt.location,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ pub enum CheckCode {
|
||||||
F541,
|
F541,
|
||||||
F634,
|
F634,
|
||||||
F403,
|
F403,
|
||||||
|
F901,
|
||||||
E501,
|
E501,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -17,6 +18,7 @@ impl CheckCode {
|
||||||
CheckCode::F541 => "F541",
|
CheckCode::F541 => "F541",
|
||||||
CheckCode::F634 => "F634",
|
CheckCode::F634 => "F634",
|
||||||
CheckCode::F403 => "F403",
|
CheckCode::F403 => "F403",
|
||||||
|
CheckCode::F901 => "F901",
|
||||||
CheckCode::E501 => "E501",
|
CheckCode::E501 => "E501",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -34,6 +36,7 @@ pub enum CheckKind {
|
||||||
FStringMissingPlaceholders,
|
FStringMissingPlaceholders,
|
||||||
IfTuple,
|
IfTuple,
|
||||||
ImportStarUsage,
|
ImportStarUsage,
|
||||||
|
RaiseNotImplemented,
|
||||||
LineTooLong,
|
LineTooLong,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -45,6 +48,7 @@ impl CheckKind {
|
||||||
CheckCode::F541 => CheckKind::FStringMissingPlaceholders,
|
CheckCode::F541 => CheckKind::FStringMissingPlaceholders,
|
||||||
CheckCode::F634 => CheckKind::IfTuple,
|
CheckCode::F634 => CheckKind::IfTuple,
|
||||||
CheckCode::F403 => CheckKind::ImportStarUsage,
|
CheckCode::F403 => CheckKind::ImportStarUsage,
|
||||||
|
CheckCode::F901 => CheckKind::RaiseNotImplemented,
|
||||||
CheckCode::E501 => CheckKind::LineTooLong,
|
CheckCode::E501 => CheckKind::LineTooLong,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -56,6 +60,7 @@ impl CheckKind {
|
||||||
CheckKind::FStringMissingPlaceholders => &CheckCode::F541,
|
CheckKind::FStringMissingPlaceholders => &CheckCode::F541,
|
||||||
CheckKind::IfTuple => &CheckCode::F634,
|
CheckKind::IfTuple => &CheckCode::F634,
|
||||||
CheckKind::ImportStarUsage => &CheckCode::F403,
|
CheckKind::ImportStarUsage => &CheckCode::F403,
|
||||||
|
CheckKind::RaiseNotImplemented => &CheckCode::F901,
|
||||||
CheckKind::LineTooLong => &CheckCode::E501,
|
CheckKind::LineTooLong => &CheckCode::E501,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -67,6 +72,9 @@ impl CheckKind {
|
||||||
CheckKind::FStringMissingPlaceholders => "f-string without any placeholders",
|
CheckKind::FStringMissingPlaceholders => "f-string without any placeholders",
|
||||||
CheckKind::IfTuple => "If test is a tuple, which is always `True`",
|
CheckKind::IfTuple => "If test is a tuple, which is always `True`",
|
||||||
CheckKind::ImportStarUsage => "Unable to detect undefined names",
|
CheckKind::ImportStarUsage => "Unable to detect undefined names",
|
||||||
|
CheckKind::RaiseNotImplemented => {
|
||||||
|
"'raise NotImplemented' should be 'raise NotImplementedError"
|
||||||
|
}
|
||||||
CheckKind::LineTooLong => "Line too long",
|
CheckKind::LineTooLong => "Line too long",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -78,6 +86,7 @@ impl CheckKind {
|
||||||
CheckKind::FStringMissingPlaceholders => &LintSource::AST,
|
CheckKind::FStringMissingPlaceholders => &LintSource::AST,
|
||||||
CheckKind::IfTuple => &LintSource::AST,
|
CheckKind::IfTuple => &LintSource::AST,
|
||||||
CheckKind::ImportStarUsage => &LintSource::AST,
|
CheckKind::ImportStarUsage => &LintSource::AST,
|
||||||
|
CheckKind::RaiseNotImplemented => &LintSource::AST,
|
||||||
CheckKind::LineTooLong => &LintSource::Lines,
|
CheckKind::LineTooLong => &LintSource::Lines,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,10 +66,7 @@ mod tests {
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use rustpython_parser::ast::Location;
|
use rustpython_parser::ast::Location;
|
||||||
|
|
||||||
use crate::checks::CheckCode;
|
use crate::checks::{CheckCode, CheckKind};
|
||||||
use crate::checks::CheckKind::{
|
|
||||||
DuplicateArgumentName, FStringMissingPlaceholders, IfTuple, ImportStarUsage, LineTooLong,
|
|
||||||
};
|
|
||||||
use crate::linter::check_path;
|
use crate::linter::check_path;
|
||||||
use crate::message::Message;
|
use crate::message::Message;
|
||||||
use crate::{cache, settings};
|
use crate::{cache, settings};
|
||||||
|
|
@ -87,17 +84,17 @@ mod tests {
|
||||||
)?;
|
)?;
|
||||||
let expected = vec![
|
let expected = vec![
|
||||||
Message {
|
Message {
|
||||||
kind: DuplicateArgumentName,
|
kind: CheckKind::DuplicateArgumentName,
|
||||||
location: Location::new(1, 25),
|
location: Location::new(1, 25),
|
||||||
filename: "./resources/test/src/duplicate_argument_name.py".to_string(),
|
filename: "./resources/test/src/duplicate_argument_name.py".to_string(),
|
||||||
},
|
},
|
||||||
Message {
|
Message {
|
||||||
kind: DuplicateArgumentName,
|
kind: CheckKind::DuplicateArgumentName,
|
||||||
location: Location::new(5, 28),
|
location: Location::new(5, 28),
|
||||||
filename: "./resources/test/src/duplicate_argument_name.py".to_string(),
|
filename: "./resources/test/src/duplicate_argument_name.py".to_string(),
|
||||||
},
|
},
|
||||||
Message {
|
Message {
|
||||||
kind: DuplicateArgumentName,
|
kind: CheckKind::DuplicateArgumentName,
|
||||||
location: Location::new(9, 27),
|
location: Location::new(9, 27),
|
||||||
filename: "./resources/test/src/duplicate_argument_name.py".to_string(),
|
filename: "./resources/test/src/duplicate_argument_name.py".to_string(),
|
||||||
},
|
},
|
||||||
|
|
@ -123,17 +120,17 @@ mod tests {
|
||||||
)?;
|
)?;
|
||||||
let expected = vec![
|
let expected = vec![
|
||||||
Message {
|
Message {
|
||||||
kind: FStringMissingPlaceholders,
|
kind: CheckKind::FStringMissingPlaceholders,
|
||||||
location: Location::new(4, 7),
|
location: Location::new(4, 7),
|
||||||
filename: "./resources/test/src/f_string_missing_placeholders.py".to_string(),
|
filename: "./resources/test/src/f_string_missing_placeholders.py".to_string(),
|
||||||
},
|
},
|
||||||
Message {
|
Message {
|
||||||
kind: FStringMissingPlaceholders,
|
kind: CheckKind::FStringMissingPlaceholders,
|
||||||
location: Location::new(5, 7),
|
location: Location::new(5, 7),
|
||||||
filename: "./resources/test/src/f_string_missing_placeholders.py".to_string(),
|
filename: "./resources/test/src/f_string_missing_placeholders.py".to_string(),
|
||||||
},
|
},
|
||||||
Message {
|
Message {
|
||||||
kind: FStringMissingPlaceholders,
|
kind: CheckKind::FStringMissingPlaceholders,
|
||||||
location: Location::new(7, 7),
|
location: Location::new(7, 7),
|
||||||
filename: "./resources/test/src/f_string_missing_placeholders.py".to_string(),
|
filename: "./resources/test/src/f_string_missing_placeholders.py".to_string(),
|
||||||
},
|
},
|
||||||
|
|
@ -159,12 +156,12 @@ mod tests {
|
||||||
)?;
|
)?;
|
||||||
let expected = vec![
|
let expected = vec![
|
||||||
Message {
|
Message {
|
||||||
kind: IfTuple,
|
kind: CheckKind::IfTuple,
|
||||||
location: Location::new(1, 1),
|
location: Location::new(1, 1),
|
||||||
filename: "./resources/test/src/if_tuple.py".to_string(),
|
filename: "./resources/test/src/if_tuple.py".to_string(),
|
||||||
},
|
},
|
||||||
Message {
|
Message {
|
||||||
kind: IfTuple,
|
kind: CheckKind::IfTuple,
|
||||||
location: Location::new(7, 5),
|
location: Location::new(7, 5),
|
||||||
filename: "./resources/test/src/if_tuple.py".to_string(),
|
filename: "./resources/test/src/if_tuple.py".to_string(),
|
||||||
},
|
},
|
||||||
|
|
@ -190,12 +187,12 @@ mod tests {
|
||||||
)?;
|
)?;
|
||||||
let expected = vec![
|
let expected = vec![
|
||||||
Message {
|
Message {
|
||||||
kind: ImportStarUsage,
|
kind: CheckKind::ImportStarUsage,
|
||||||
location: Location::new(1, 1),
|
location: Location::new(1, 1),
|
||||||
filename: "./resources/test/src/import_star_usage.py".to_string(),
|
filename: "./resources/test/src/import_star_usage.py".to_string(),
|
||||||
},
|
},
|
||||||
Message {
|
Message {
|
||||||
kind: ImportStarUsage,
|
kind: CheckKind::ImportStarUsage,
|
||||||
location: Location::new(2, 1),
|
location: Location::new(2, 1),
|
||||||
filename: "./resources/test/src/import_star_usage.py".to_string(),
|
filename: "./resources/test/src/import_star_usage.py".to_string(),
|
||||||
},
|
},
|
||||||
|
|
@ -208,6 +205,37 @@ mod tests {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn raise_not_implemented() -> Result<()> {
|
||||||
|
let actual = check_path(
|
||||||
|
&Path::new("./resources/test/src/raise_not_implemented.py"),
|
||||||
|
&settings::Settings {
|
||||||
|
line_length: 88,
|
||||||
|
exclude: vec![],
|
||||||
|
select: BTreeSet::from([CheckCode::F901]),
|
||||||
|
},
|
||||||
|
&cache::Mode::None,
|
||||||
|
)?;
|
||||||
|
let expected = vec![
|
||||||
|
Message {
|
||||||
|
kind: CheckKind::RaiseNotImplemented,
|
||||||
|
location: Location::new(2, 5),
|
||||||
|
filename: "./resources/test/src/raise_not_implemented.py".to_string(),
|
||||||
|
},
|
||||||
|
Message {
|
||||||
|
kind: CheckKind::RaiseNotImplemented,
|
||||||
|
location: Location::new(6, 5),
|
||||||
|
filename: "./resources/test/src/raise_not_implemented.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 line_too_long() -> Result<()> {
|
fn line_too_long() -> Result<()> {
|
||||||
let actual = check_path(
|
let actual = check_path(
|
||||||
|
|
@ -220,7 +248,7 @@ mod tests {
|
||||||
&cache::Mode::None,
|
&cache::Mode::None,
|
||||||
)?;
|
)?;
|
||||||
let expected = vec![Message {
|
let expected = vec![Message {
|
||||||
kind: LineTooLong,
|
kind: CheckKind::LineTooLong,
|
||||||
location: Location::new(5, 89),
|
location: Location::new(5, 89),
|
||||||
filename: "./resources/test/src/line_too_long.py".to_string(),
|
filename: "./resources/test/src/line_too_long.py".to_string(),
|
||||||
}];
|
}];
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ impl Settings {
|
||||||
CheckCode::F541,
|
CheckCode::F541,
|
||||||
CheckCode::F634,
|
CheckCode::F634,
|
||||||
CheckCode::F403,
|
CheckCode::F403,
|
||||||
|
CheckCode::F901,
|
||||||
CheckCode::E501,
|
CheckCode::E501,
|
||||||
])
|
])
|
||||||
}),
|
}),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue