diff --git a/README.md b/README.md index 550277e3ea..3d5de3b00e 100644 --- a/README.md +++ b/README.md @@ -535,16 +535,16 @@ For more, see [flake8-annotations](https://pypi.org/project/flake8-annotations/2 | Code | Name | Message | Fix | | ---- | ---- | ------- | --- | -| ANN001 | MissingTypeFunctionArgument | Missing type annotation for function argument | | -| ANN002 | MissingTypeArgs | Missing type annotation for `*args` | | -| ANN003 | MissingTypeKwargs | Missing type annotation for `**kwargs` | | -| ANN101 | MissingTypeSelf | Missing type annotation for `self` in method | | -| ANN102 | MissingTypeCls | Missing type annotation for `cls` in classmethod | | -| ANN201 | MissingReturnTypePublicFunction | Missing return type annotation for public function | | -| ANN202 | MissingReturnTypePrivateFunction | Missing return type annotation for private function | | -| ANN204 | MissingReturnTypeMagicMethod | Missing return type annotation for magic method | | -| ANN205 | MissingReturnTypeStaticMethod | Missing return type annotation for staticmethod | | -| ANN206 | MissingReturnTypeClassMethod | Missing return type annotation for classmethod | | +| ANN001 | MissingTypeFunctionArgument | Missing type annotation for function argument `...` | | +| ANN002 | MissingTypeArgs | Missing type annotation for `*...` | | +| ANN003 | MissingTypeKwargs | Missing type annotation for `**...` | | +| ANN101 | MissingTypeSelf | Missing type annotation for `...` in method | | +| ANN102 | MissingTypeCls | Missing type annotation for `...` in classmethod | | +| ANN201 | MissingReturnTypePublicFunction | Missing return type annotation for public function `...` | | +| ANN202 | MissingReturnTypePrivateFunction | Missing return type annotation for private function `...` | | +| ANN204 | MissingReturnTypeMagicMethod | Missing return type annotation for magic method `...` | | +| ANN205 | MissingReturnTypeStaticMethod | Missing return type annotation for staticmethod `...` | | +| ANN206 | MissingReturnTypeClassMethod | Missing return type annotation for classmethod `...` | | ### Ruff-specific rules diff --git a/src/checks.rs b/src/checks.rs index 50b7857d97..569dfe37b2 100644 --- a/src/checks.rs +++ b/src/checks.rs @@ -378,16 +378,16 @@ pub enum CheckKind { BadQuotesDocstring(Quote), AvoidQuoteEscape, // flake8-annotations - MissingTypeFunctionArgument, - MissingTypeArgs, - MissingTypeKwargs, - MissingTypeSelf, - MissingTypeCls, - MissingReturnTypePublicFunction, - MissingReturnTypePrivateFunction, - MissingReturnTypeMagicMethod, - MissingReturnTypeStaticMethod, - MissingReturnTypeClassMethod, + MissingTypeFunctionArgument(String), + MissingTypeArgs(String), + MissingTypeKwargs(String), + MissingTypeSelf(String), + MissingTypeCls(String), + MissingReturnTypePublicFunction(String), + MissingReturnTypePrivateFunction(String), + MissingReturnTypeMagicMethod(String), + MissingReturnTypeStaticMethod(String), + MissingReturnTypeClassMethod(String), // pyupgrade TypeOfPrimitive(Primitive), UnnecessaryAbspath, @@ -599,16 +599,16 @@ impl CheckCode { CheckCode::Q002 => CheckKind::BadQuotesDocstring(Quote::Double), CheckCode::Q003 => CheckKind::AvoidQuoteEscape, // flake8-annotations - CheckCode::ANN001 => CheckKind::MissingTypeFunctionArgument, - CheckCode::ANN002 => CheckKind::MissingTypeArgs, - CheckCode::ANN003 => CheckKind::MissingTypeKwargs, - CheckCode::ANN101 => CheckKind::MissingTypeSelf, - CheckCode::ANN102 => CheckKind::MissingTypeCls, - CheckCode::ANN201 => CheckKind::MissingReturnTypePublicFunction, - CheckCode::ANN202 => CheckKind::MissingReturnTypePrivateFunction, - CheckCode::ANN204 => CheckKind::MissingReturnTypeMagicMethod, - CheckCode::ANN205 => CheckKind::MissingReturnTypeStaticMethod, - CheckCode::ANN206 => CheckKind::MissingReturnTypeClassMethod, + CheckCode::ANN001 => CheckKind::MissingTypeFunctionArgument("...".to_string()), + CheckCode::ANN002 => CheckKind::MissingTypeArgs("...".to_string()), + CheckCode::ANN003 => CheckKind::MissingTypeKwargs("...".to_string()), + CheckCode::ANN101 => CheckKind::MissingTypeSelf("...".to_string()), + CheckCode::ANN102 => CheckKind::MissingTypeCls("...".to_string()), + CheckCode::ANN201 => CheckKind::MissingReturnTypePublicFunction("...".to_string()), + CheckCode::ANN202 => CheckKind::MissingReturnTypePrivateFunction("...".to_string()), + CheckCode::ANN204 => CheckKind::MissingReturnTypeMagicMethod("...".to_string()), + CheckCode::ANN205 => CheckKind::MissingReturnTypeStaticMethod("...".to_string()), + CheckCode::ANN206 => CheckKind::MissingReturnTypeClassMethod("...".to_string()), // pyupgrade CheckCode::U001 => CheckKind::UselessMetaclassType, CheckCode::U002 => CheckKind::UnnecessaryAbspath, @@ -974,16 +974,16 @@ impl CheckKind { CheckKind::BadQuotesDocstring(_) => &CheckCode::Q002, CheckKind::AvoidQuoteEscape => &CheckCode::Q003, // flake8-annotations - CheckKind::MissingTypeFunctionArgument => &CheckCode::ANN001, - CheckKind::MissingTypeArgs => &CheckCode::ANN002, - CheckKind::MissingTypeKwargs => &CheckCode::ANN003, - CheckKind::MissingTypeSelf => &CheckCode::ANN101, - CheckKind::MissingTypeCls => &CheckCode::ANN102, - CheckKind::MissingReturnTypePublicFunction => &CheckCode::ANN201, - CheckKind::MissingReturnTypePrivateFunction => &CheckCode::ANN202, - CheckKind::MissingReturnTypeMagicMethod => &CheckCode::ANN204, - CheckKind::MissingReturnTypeStaticMethod => &CheckCode::ANN205, - CheckKind::MissingReturnTypeClassMethod => &CheckCode::ANN206, + CheckKind::MissingTypeFunctionArgument(_) => &CheckCode::ANN001, + CheckKind::MissingTypeArgs(_) => &CheckCode::ANN002, + CheckKind::MissingTypeKwargs(_) => &CheckCode::ANN003, + CheckKind::MissingTypeSelf(_) => &CheckCode::ANN101, + CheckKind::MissingTypeCls(_) => &CheckCode::ANN102, + CheckKind::MissingReturnTypePublicFunction(_) => &CheckCode::ANN201, + CheckKind::MissingReturnTypePrivateFunction(_) => &CheckCode::ANN202, + CheckKind::MissingReturnTypeMagicMethod(_) => &CheckCode::ANN204, + CheckKind::MissingReturnTypeStaticMethod(_) => &CheckCode::ANN205, + CheckKind::MissingReturnTypeClassMethod(_) => &CheckCode::ANN206, // pyupgrade CheckKind::TypeOfPrimitive(_) => &CheckCode::U003, CheckKind::UnnecessaryAbspath => &CheckCode::U002, @@ -1377,31 +1377,33 @@ impl CheckKind { "Change outer quotes to avoid escaping inner quotes".to_string() } // flake8-annotations - CheckKind::MissingTypeFunctionArgument => { - "Missing type annotation for function argument".to_string() + CheckKind::MissingTypeFunctionArgument(name) => { + format!("Missing type annotation for function argument `{name}`") } - CheckKind::MissingTypeArgs => "Missing type annotation for `*args`".to_string(), - CheckKind::MissingTypeKwargs => "Missing type annotation for `**kwargs`".to_string(), - CheckKind::MissingTypeSelf => { - "Missing type annotation for `self` in method".to_string() + CheckKind::MissingTypeArgs(name) => format!("Missing type annotation for `*{name}`"), + CheckKind::MissingTypeKwargs(name) => { + format!("Missing type annotation for `**{name}`") } - CheckKind::MissingTypeCls => { - "Missing type annotation for `cls` in classmethod".to_string() + CheckKind::MissingTypeSelf(name) => { + format!("Missing type annotation for `{name}` in method") } - CheckKind::MissingReturnTypePublicFunction => { - "Missing return type annotation for public function".to_string() + CheckKind::MissingTypeCls(name) => { + format!("Missing type annotation for `{name}` in classmethod") } - CheckKind::MissingReturnTypePrivateFunction => { - "Missing return type annotation for private function".to_string() + CheckKind::MissingReturnTypePublicFunction(name) => { + format!("Missing return type annotation for public function `{name}`") } - CheckKind::MissingReturnTypeMagicMethod => { - "Missing return type annotation for magic method".to_string() + CheckKind::MissingReturnTypePrivateFunction(name) => { + format!("Missing return type annotation for private function `{name}`") } - CheckKind::MissingReturnTypeStaticMethod => { - "Missing return type annotation for staticmethod".to_string() + CheckKind::MissingReturnTypeMagicMethod(name) => { + format!("Missing return type annotation for magic method `{name}`") } - CheckKind::MissingReturnTypeClassMethod => { - "Missing return type annotation for classmethod".to_string() + CheckKind::MissingReturnTypeStaticMethod(name) => { + format!("Missing return type annotation for staticmethod `{name}`") + } + CheckKind::MissingReturnTypeClassMethod(name) => { + format!("Missing return type annotation for classmethod `{name}`") } // pyupgrade CheckKind::TypeOfPrimitive(primitive) => { diff --git a/src/flake8_annotations/plugins.rs b/src/flake8_annotations/plugins.rs index 9455ebec2a..d6c35e0e71 100644 --- a/src/flake8_annotations/plugins.rs +++ b/src/flake8_annotations/plugins.rs @@ -29,9 +29,9 @@ where } } -fn is_none_returning(stmt: &Stmt) -> bool { +fn is_none_returning(body: &[Stmt]) -> bool { let mut visitor: ReturnStatementVisitor = Default::default(); - for stmt in match_body(stmt) { + for stmt in body { visitor.visit_stmt(stmt); } for expr in visitor.returns.into_iter().flatten() { @@ -48,26 +48,23 @@ fn is_none_returning(stmt: &Stmt) -> bool { true } -fn match_args(stmt: &Stmt) -> &Arguments { +fn match_function_def(stmt: &Stmt) -> (&str, &Arguments, &Option>, &Vec) { match &stmt.node { - StmtKind::FunctionDef { args, .. } | StmtKind::AsyncFunctionDef { args, .. } => args, - _ => panic!("Found non-FunctionDef in match_args"), - } -} - -fn match_body(stmt: &Stmt) -> &Vec { - match &stmt.node { - StmtKind::FunctionDef { body, .. } | StmtKind::AsyncFunctionDef { body, .. } => body, - _ => panic!("Found non-FunctionDef in match_body"), - } -} - -fn match_returns(stmt: &Stmt) -> &Option> { - match &stmt.node { - StmtKind::FunctionDef { returns, .. } | StmtKind::AsyncFunctionDef { returns, .. } => { - returns + StmtKind::FunctionDef { + name, + args, + returns, + body, + .. } - _ => panic!("Found non-FunctionDef in match_returns"), + | StmtKind::AsyncFunctionDef { + name, + args, + returns, + body, + .. + } => (name, args, returns, body), + _ => panic!("Found non-FunctionDef in match_name"), } } @@ -82,8 +79,7 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V DefinitionKind::Class(_) => {} DefinitionKind::NestedClass(_) => {} DefinitionKind::Function(stmt) | DefinitionKind::NestedFunction(stmt) => { - let args = match_args(stmt); - let returns = match_returns(stmt); + let (name, args, returns, body) = match_function_def(stmt); // ANN001 for arg in args @@ -98,7 +94,7 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V { if checker.settings.enabled.contains(&CheckCode::ANN001) { checker.add_check(Check::new( - CheckKind::MissingTypeFunctionArgument, + CheckKind::MissingTypeFunctionArgument(arg.node.arg.to_string()), Range::from_located(arg), )); } @@ -114,7 +110,7 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V { if checker.settings.enabled.contains(&CheckCode::ANN002) { checker.add_check(Check::new( - CheckKind::MissingTypeArgs, + CheckKind::MissingTypeArgs(arg.node.arg.to_string()), Range::from_located(arg), )); } @@ -130,7 +126,7 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V { if checker.settings.enabled.contains(&CheckCode::ANN003) { checker.add_check(Check::new( - CheckKind::MissingTypeKwargs, + CheckKind::MissingTypeKwargs(arg.node.arg.to_string()), Range::from_located(arg), )); } @@ -143,7 +139,7 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V // Allow omission of return annotation in `__init__` functions, if the function // only returns `None` (explicitly or implicitly). if checker.settings.flake8_annotations.suppress_none_returning - && is_none_returning(stmt) + && is_none_returning(body) { return; } @@ -152,7 +148,7 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V Visibility::Public => { if checker.settings.enabled.contains(&CheckCode::ANN201) { checker.add_check(Check::new( - CheckKind::MissingReturnTypePublicFunction, + CheckKind::MissingReturnTypePublicFunction(name.to_string()), Range::from_located(stmt), )); } @@ -160,7 +156,7 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V Visibility::Private => { if checker.settings.enabled.contains(&CheckCode::ANN202) { checker.add_check(Check::new( - CheckKind::MissingReturnTypePrivateFunction, + CheckKind::MissingReturnTypePrivateFunction(name.to_string()), Range::from_located(stmt), )); } @@ -169,8 +165,7 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V } } DefinitionKind::Method(stmt) => { - let args = match_args(stmt); - let returns = match_returns(stmt); + let (name, args, returns, body) = match_function_def(stmt); let mut has_any_typed_arg = false; // ANN001 @@ -190,7 +185,7 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V { if checker.settings.enabled.contains(&CheckCode::ANN001) { checker.add_check(Check::new( - CheckKind::MissingTypeFunctionArgument, + CheckKind::MissingTypeFunctionArgument(arg.node.arg.to_string()), Range::from_located(arg), )); } @@ -208,7 +203,7 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V { if checker.settings.enabled.contains(&CheckCode::ANN002) { checker.add_check(Check::new( - CheckKind::MissingTypeArgs, + CheckKind::MissingTypeArgs(arg.node.arg.to_string()), Range::from_located(arg), )); } @@ -226,7 +221,7 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V { if checker.settings.enabled.contains(&CheckCode::ANN003) { checker.add_check(Check::new( - CheckKind::MissingTypeKwargs, + CheckKind::MissingTypeKwargs(arg.node.arg.to_string()), Range::from_located(arg), )); } @@ -243,14 +238,14 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V if visibility::is_classmethod(stmt) { if checker.settings.enabled.contains(&CheckCode::ANN102) { checker.add_check(Check::new( - CheckKind::MissingTypeCls, + CheckKind::MissingTypeCls(arg.node.arg.to_string()), Range::from_located(arg), )); } } else { if checker.settings.enabled.contains(&CheckCode::ANN101) { checker.add_check(Check::new( - CheckKind::MissingTypeSelf, + CheckKind::MissingTypeSelf(arg.node.arg.to_string()), Range::from_located(arg), )); } @@ -264,7 +259,7 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V // Allow omission of return annotation in `__init__` functions, if the function // only returns `None` (explicitly or implicitly). if checker.settings.flake8_annotations.suppress_none_returning - && is_none_returning(stmt) + && is_none_returning(body) { return; } @@ -272,21 +267,21 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V if visibility::is_classmethod(stmt) { if checker.settings.enabled.contains(&CheckCode::ANN206) { checker.add_check(Check::new( - CheckKind::MissingReturnTypeClassMethod, + CheckKind::MissingReturnTypeClassMethod(name.to_string()), Range::from_located(stmt), )); } } else if visibility::is_staticmethod(stmt) { if checker.settings.enabled.contains(&CheckCode::ANN205) { checker.add_check(Check::new( - CheckKind::MissingReturnTypeStaticMethod, + CheckKind::MissingReturnTypeStaticMethod(name.to_string()), Range::from_located(stmt), )); } } else if visibility::is_magic(stmt) { if checker.settings.enabled.contains(&CheckCode::ANN204) { checker.add_check(Check::new( - CheckKind::MissingReturnTypeMagicMethod, + CheckKind::MissingReturnTypeMagicMethod(name.to_string()), Range::from_located(stmt), )); } @@ -298,7 +293,7 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V && has_any_typed_arg) { checker.add_check(Check::new( - CheckKind::MissingReturnTypeMagicMethod, + CheckKind::MissingReturnTypeMagicMethod(name.to_string()), Range::from_located(stmt), )); } @@ -308,7 +303,7 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V Visibility::Public => { if checker.settings.enabled.contains(&CheckCode::ANN201) { checker.add_check(Check::new( - CheckKind::MissingReturnTypePublicFunction, + CheckKind::MissingReturnTypePublicFunction(name.to_string()), Range::from_located(stmt), )); } @@ -316,7 +311,7 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V Visibility::Private => { if checker.settings.enabled.contains(&CheckCode::ANN202) { checker.add_check(Check::new( - CheckKind::MissingReturnTypePrivateFunction, + CheckKind::MissingReturnTypePrivateFunction(name.to_string()), Range::from_located(stmt), )); } diff --git a/src/flake8_annotations/snapshots/ruff__flake8_annotations__tests__defaults.snap b/src/flake8_annotations/snapshots/ruff__flake8_annotations__tests__defaults.snap index 82082382cd..ad9a3c5e07 100644 --- a/src/flake8_annotations/snapshots/ruff__flake8_annotations__tests__defaults.snap +++ b/src/flake8_annotations/snapshots/ruff__flake8_annotations__tests__defaults.snap @@ -2,7 +2,8 @@ source: src/flake8_annotations/mod.rs expression: checks --- -- kind: MissingReturnTypePublicFunction +- kind: + MissingReturnTypePublicFunction: foo location: row: 4 column: 0 @@ -10,7 +11,8 @@ expression: checks row: 9 column: 0 fix: ~ -- kind: MissingTypeFunctionArgument +- kind: + MissingTypeFunctionArgument: a location: row: 4 column: 8 @@ -18,7 +20,8 @@ expression: checks row: 4 column: 9 fix: ~ -- kind: MissingTypeFunctionArgument +- kind: + MissingTypeFunctionArgument: b location: row: 4 column: 11 @@ -26,7 +29,8 @@ expression: checks row: 4 column: 12 fix: ~ -- kind: MissingReturnTypePublicFunction +- kind: + MissingReturnTypePublicFunction: foo location: row: 9 column: 0 @@ -34,7 +38,8 @@ expression: checks row: 14 column: 0 fix: ~ -- kind: MissingTypeFunctionArgument +- kind: + MissingTypeFunctionArgument: b location: row: 9 column: 16 @@ -42,7 +47,8 @@ expression: checks row: 9 column: 17 fix: ~ -- kind: MissingTypeFunctionArgument +- kind: + MissingTypeFunctionArgument: b location: row: 14 column: 16 @@ -50,7 +56,8 @@ expression: checks row: 14 column: 17 fix: ~ -- kind: MissingReturnTypePublicFunction +- kind: + MissingReturnTypePublicFunction: foo location: row: 19 column: 0 @@ -58,7 +65,8 @@ expression: checks row: 24 column: 0 fix: ~ -- kind: MissingReturnTypePublicFunction +- kind: + MissingReturnTypePublicFunction: foo location: row: 24 column: 0 @@ -66,7 +74,8 @@ expression: checks row: 29 column: 0 fix: ~ -- kind: MissingTypeSelf +- kind: + MissingTypeSelf: self location: row: 44 column: 12 @@ -74,7 +83,8 @@ expression: checks row: 44 column: 16 fix: ~ -- kind: MissingTypeCls +- kind: + MissingTypeCls: cls location: row: 54 column: 12 diff --git a/src/flake8_annotations/snapshots/ruff__flake8_annotations__tests__mypy_init_return.snap b/src/flake8_annotations/snapshots/ruff__flake8_annotations__tests__mypy_init_return.snap index d2e7b8c6eb..70e6be172a 100644 --- a/src/flake8_annotations/snapshots/ruff__flake8_annotations__tests__mypy_init_return.snap +++ b/src/flake8_annotations/snapshots/ruff__flake8_annotations__tests__mypy_init_return.snap @@ -2,7 +2,8 @@ source: src/flake8_annotations/mod.rs expression: checks --- -- kind: MissingReturnTypeMagicMethod +- kind: + MissingReturnTypeMagicMethod: __init__ location: row: 5 column: 4 @@ -10,7 +11,8 @@ expression: checks row: 10 column: 0 fix: ~ -- kind: MissingReturnTypeMagicMethod +- kind: + MissingReturnTypeMagicMethod: __init__ location: row: 11 column: 4 @@ -18,7 +20,8 @@ expression: checks row: 16 column: 0 fix: ~ -- kind: MissingReturnTypePrivateFunction +- kind: + MissingReturnTypePrivateFunction: __init__ location: row: 40 column: 0 diff --git a/src/flake8_annotations/snapshots/ruff__flake8_annotations__tests__suppress_none_returning.snap b/src/flake8_annotations/snapshots/ruff__flake8_annotations__tests__suppress_none_returning.snap index b8798ea6b7..e705254d34 100644 --- a/src/flake8_annotations/snapshots/ruff__flake8_annotations__tests__suppress_none_returning.snap +++ b/src/flake8_annotations/snapshots/ruff__flake8_annotations__tests__suppress_none_returning.snap @@ -2,7 +2,8 @@ source: src/flake8_annotations/mod.rs expression: checks --- -- kind: MissingReturnTypePublicFunction +- kind: + MissingReturnTypePublicFunction: foo location: row: 45 column: 0 @@ -10,7 +11,8 @@ expression: checks row: 50 column: 0 fix: ~ -- kind: MissingReturnTypePublicFunction +- kind: + MissingReturnTypePublicFunction: foo location: row: 50 column: 0