From f64e8f3f3ee77d1b71cf40e49a7c5a37fc93162f Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Sat, 16 Nov 2024 18:30:12 +0000 Subject: [PATCH 1/2] [ruff-0.8] Remove deprecated rules ANN101 and ANN102 --- .../flake8_annotations/annotation_presence.py | 6 +- .../src/checkers/ast/analyze/definitions.rs | 2 - crates/ruff_linter/src/codes.rs | 4 +- .../src/rules/flake8_annotations/mod.rs | 8 -- .../flake8_annotations/rules/definition.rs | 92 +++++++------------ ...__flake8_annotations__tests__defaults.snap | 35 ------- ruff.schema.json | 4 - 7 files changed, 37 insertions(+), 114 deletions(-) diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_annotations/annotation_presence.py b/crates/ruff_linter/resources/test/fixtures/flake8_annotations/annotation_presence.py index b84ec16576854c..4ef4e2220bb935 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_annotations/annotation_presence.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_annotations/annotation_presence.py @@ -71,7 +71,7 @@ class Foo: def foo(self: "Foo", a: int, b: int) -> int: pass - # ANN101 + # OK def foo(self, a: int, b: int) -> int: pass @@ -125,12 +125,12 @@ def foo(self: "Foo", a: int, *params: str, **options: Any) -> int: def foo(cls: Type["Foo"], a: int, b: int) -> int: pass - # ANN102 + # OK @classmethod def foo(cls, a: int, b: int) -> int: pass - # ANN101 + # OK def foo(self, /, a: int, b: int) -> int: pass diff --git a/crates/ruff_linter/src/checkers/ast/analyze/definitions.rs b/crates/ruff_linter/src/checkers/ast/analyze/definitions.rs index 689b5c416e4e1d..4580d23a644d83 100644 --- a/crates/ruff_linter/src/checkers/ast/analyze/definitions.rs +++ b/crates/ruff_linter/src/checkers/ast/analyze/definitions.rs @@ -27,10 +27,8 @@ pub(crate) fn definitions(checker: &mut Checker) { Rule::MissingReturnTypeStaticMethod, Rule::MissingReturnTypeUndocumentedPublicFunction, Rule::MissingTypeArgs, - Rule::MissingTypeCls, Rule::MissingTypeFunctionArgument, Rule::MissingTypeKwargs, - Rule::MissingTypeSelf, ]); let enforce_stubs = checker.source_type.is_stub() && checker.enabled(Rule::DocstringInStub); let enforce_stubs_and_runtime = checker.enabled(Rule::IterMethodReturnIterable); diff --git a/crates/ruff_linter/src/codes.rs b/crates/ruff_linter/src/codes.rs index 4405757aa3b639..dc660897003d8a 100644 --- a/crates/ruff_linter/src/codes.rs +++ b/crates/ruff_linter/src/codes.rs @@ -428,8 +428,8 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { (Flake8Annotations, "001") => (RuleGroup::Stable, rules::flake8_annotations::rules::MissingTypeFunctionArgument), (Flake8Annotations, "002") => (RuleGroup::Stable, rules::flake8_annotations::rules::MissingTypeArgs), (Flake8Annotations, "003") => (RuleGroup::Stable, rules::flake8_annotations::rules::MissingTypeKwargs), - (Flake8Annotations, "101") => (RuleGroup::Deprecated, rules::flake8_annotations::rules::MissingTypeSelf), - (Flake8Annotations, "102") => (RuleGroup::Deprecated, rules::flake8_annotations::rules::MissingTypeCls), + (Flake8Annotations, "101") => (RuleGroup::Removed, rules::flake8_annotations::rules::MissingTypeSelf), + (Flake8Annotations, "102") => (RuleGroup::Removed, rules::flake8_annotations::rules::MissingTypeCls), (Flake8Annotations, "201") => (RuleGroup::Stable, rules::flake8_annotations::rules::MissingReturnTypeUndocumentedPublicFunction), (Flake8Annotations, "202") => (RuleGroup::Stable, rules::flake8_annotations::rules::MissingReturnTypePrivateFunction), (Flake8Annotations, "204") => (RuleGroup::Stable, rules::flake8_annotations::rules::MissingReturnTypeSpecialMethod), diff --git a/crates/ruff_linter/src/rules/flake8_annotations/mod.rs b/crates/ruff_linter/src/rules/flake8_annotations/mod.rs index 859f8588c5311a..57d866ec2c93cf 100644 --- a/crates/ruff_linter/src/rules/flake8_annotations/mod.rs +++ b/crates/ruff_linter/src/rules/flake8_annotations/mod.rs @@ -24,8 +24,6 @@ mod tests { Rule::MissingTypeFunctionArgument, Rule::MissingTypeArgs, Rule::MissingTypeKwargs, - Rule::MissingTypeSelf, - Rule::MissingTypeCls, Rule::MissingReturnTypeUndocumentedPublicFunction, Rule::MissingReturnTypePrivateFunction, Rule::MissingReturnTypeSpecialMethod, @@ -52,8 +50,6 @@ mod tests { Rule::MissingTypeFunctionArgument, Rule::MissingTypeArgs, Rule::MissingTypeKwargs, - Rule::MissingTypeSelf, - Rule::MissingTypeCls, Rule::MissingReturnTypeUndocumentedPublicFunction, Rule::MissingReturnTypePrivateFunction, Rule::MissingReturnTypeSpecialMethod, @@ -80,8 +76,6 @@ mod tests { Rule::MissingTypeFunctionArgument, Rule::MissingTypeArgs, Rule::MissingTypeKwargs, - Rule::MissingTypeSelf, - Rule::MissingTypeCls, ]) }, )?; @@ -161,8 +155,6 @@ mod tests { Rule::MissingTypeFunctionArgument, Rule::MissingTypeArgs, Rule::MissingTypeKwargs, - Rule::MissingTypeSelf, - Rule::MissingTypeCls, Rule::MissingReturnTypeUndocumentedPublicFunction, Rule::MissingReturnTypePrivateFunction, Rule::MissingReturnTypeSpecialMethod, diff --git a/crates/ruff_linter/src/rules/flake8_annotations/rules/definition.rs b/crates/ruff_linter/src/rules/flake8_annotations/rules/definition.rs index 9f94b29cc53cdf..ae27e73722d4d7 100644 --- a/crates/ruff_linter/src/rules/flake8_annotations/rules/definition.rs +++ b/crates/ruff_linter/src/rules/flake8_annotations/rules/definition.rs @@ -110,9 +110,8 @@ impl Violation for MissingTypeKwargs { } } -/// ## Deprecation -/// This rule is commonly disabled because type checkers can infer this type without annotation. -/// It will be removed in a future release. +/// ## Removed +/// This rule has been removed because type checkers can infer this type without annotation. /// /// ## What it does /// Checks that instance method `self` arguments have type annotations. @@ -139,21 +138,20 @@ impl Violation for MissingTypeKwargs { /// def bar(self: "Foo"): ... /// ``` #[violation] -pub struct MissingTypeSelf { - name: String, -} +pub struct MissingTypeSelf; impl Violation for MissingTypeSelf { - #[derive_message_formats] fn message(&self) -> String { - let Self { name } = self; - format!("Missing type annotation for `{name}` in method") + unreachable!("ANN101 has been removed"); + } + + fn message_formats() -> &'static [&'static str] { + &["Missing type annotation for `{name}` in method"] } } -/// ## Deprecation -/// This rule is commonly disabled because type checkers can infer this type without annotation. -/// It will be removed in a future release. +/// ## Removed +/// This rule has been removed because type checkers can infer this type without annotation. /// /// ## What it does /// Checks that class method `cls` arguments have type annotations. @@ -182,15 +180,15 @@ impl Violation for MissingTypeSelf { /// def bar(cls: Type["Foo"]): ... /// ``` #[violation] -pub struct MissingTypeCls { - name: String, -} +pub struct MissingTypeCls; impl Violation for MissingTypeCls { - #[derive_message_formats] fn message(&self) -> String { - let Self { name } = self; - format!("Missing type annotation for `{name}` in classmethod") + unreachable!("ANN102 has been removed") + } + + fn message_formats() -> &'static [&'static str] { + &["Missing type annotation for `{name}` in classmethod"] } } @@ -594,7 +592,6 @@ pub(crate) fn definition( // Keep track of whether we've seen any typed arguments or return values. let mut has_any_typed_arg = false; // Any argument has been typed? let mut has_typed_return = false; // Return value has been typed? - let mut has_typed_self_or_cls = false; // Has a typed `self` or `cls` argument? // Temporary storage for diagnostics; we emit them at the end // unless configured to suppress ANN* for declarations that are fully untyped. @@ -697,43 +694,6 @@ pub(crate) fn definition( } } - // ANN101, ANN102 - if is_method && !visibility::is_staticmethod(decorator_list, checker.semantic()) { - if let Some(ParameterWithDefault { - parameter, - default: _, - range: _, - }) = parameters - .posonlyargs - .first() - .or_else(|| parameters.args.first()) - { - if parameter.annotation.is_none() { - if visibility::is_classmethod(decorator_list, checker.semantic()) { - if checker.enabled(Rule::MissingTypeCls) { - diagnostics.push(Diagnostic::new( - MissingTypeCls { - name: parameter.name.to_string(), - }, - parameter.range(), - )); - } - } else { - if checker.enabled(Rule::MissingTypeSelf) { - diagnostics.push(Diagnostic::new( - MissingTypeSelf { - name: parameter.name.to_string(), - }, - parameter.range(), - )); - } - } - } else { - has_typed_self_or_cls = true; - } - } - } - // ANN201, ANN202, ANN401 if let Some(expr) = &returns { has_typed_return = true; @@ -927,13 +887,25 @@ pub(crate) fn definition( } } } + + if !checker.settings.flake8_annotations.ignore_fully_untyped { + return diagnostics; + } + // If settings say so, don't report any of the // diagnostics gathered here if there were no type annotations at all. - if checker.settings.flake8_annotations.ignore_fully_untyped - && !(has_any_typed_arg || has_typed_self_or_cls || has_typed_return) + if has_any_typed_arg + || has_typed_return + || (is_method + && !visibility::is_staticmethod(decorator_list, checker.semantic()) + && parameters + .posonlyargs + .first() + .or_else(|| parameters.args.first()) + .is_some_and(|first_param| first_param.parameter.annotation.is_some())) { - vec![] - } else { diagnostics + } else { + vec![] } } diff --git a/crates/ruff_linter/src/rules/flake8_annotations/snapshots/ruff_linter__rules__flake8_annotations__tests__defaults.snap b/crates/ruff_linter/src/rules/flake8_annotations/snapshots/ruff_linter__rules__flake8_annotations__tests__defaults.snap index dedf99ff7cd35d..d3837dec75837a 100644 --- a/crates/ruff_linter/src/rules/flake8_annotations/snapshots/ruff_linter__rules__flake8_annotations__tests__defaults.snap +++ b/crates/ruff_linter/src/rules/flake8_annotations/snapshots/ruff_linter__rules__flake8_annotations__tests__defaults.snap @@ -1,6 +1,5 @@ --- source: crates/ruff_linter/src/rules/flake8_annotations/mod.rs -snapshot_kind: text --- annotation_presence.py:5:5: ANN201 [*] Missing return type annotation for public function `foo` | @@ -158,14 +157,6 @@ annotation_presence.py:65:39: ANN401 Dynamically typed expressions (typing.Any) 66 | pass | -annotation_presence.py:75:13: ANN101 Missing type annotation for `self` in method - | -74 | # ANN101 -75 | def foo(self, a: int, b: int) -> int: - | ^^^^ ANN101 -76 | pass - | - annotation_presence.py:79:29: ANN401 Dynamically typed expressions (typing.Any) are disallowed in `a` | 78 | # ANN401 @@ -214,23 +205,6 @@ annotation_presence.py:95:59: ANN401 Dynamically typed expressions (typing.Any) 96 | pass | -annotation_presence.py:130:13: ANN102 Missing type annotation for `cls` in classmethod - | -128 | # ANN102 -129 | @classmethod -130 | def foo(cls, a: int, b: int) -> int: - | ^^^ ANN102 -131 | pass - | - -annotation_presence.py:134:13: ANN101 Missing type annotation for `self` in method - | -133 | # ANN101 -134 | def foo(self, /, a: int, b: int) -> int: - | ^^^^ ANN101 -135 | pass - | - annotation_presence.py:149:10: ANN401 Dynamically typed expressions (typing.Any) are disallowed in `a` | 148 | # ANN401 @@ -324,12 +298,3 @@ annotation_presence.py:165:9: ANN204 [*] Missing return type annotation for spec 165 |- def __init__(self): 165 |+ def __init__(self) -> None: 166 166 | print(f"{self.attr=}") - -annotation_presence.py:165:18: ANN101 Missing type annotation for `self` in method - | -163 | # Regression test for: https://github.com/astral-sh/ruff/issues/7711 -164 | class Class: -165 | def __init__(self): - | ^^^^ ANN101 -166 | print(f"{self.attr=}") - | diff --git a/ruff.schema.json b/ruff.schema.json index 856b434f0547a2..263ab678efac19 100644 --- a/ruff.schema.json +++ b/ruff.schema.json @@ -2798,10 +2798,6 @@ "ANN001", "ANN002", "ANN003", - "ANN1", - "ANN10", - "ANN101", - "ANN102", "ANN2", "ANN20", "ANN201", From 55554528ad0389fc2cf3bdacedd67897b139ee8d Mon Sep 17 00:00:00 2001 From: Micha Reiser Date: Tue, 19 Nov 2024 09:42:00 +0100 Subject: [PATCH 2/2] Deprecate rules --- crates/ruff_linter/src/codes.rs | 2 ++ .../src/rules/flake8_annotations/rules/definition.rs | 4 ++++ crates/ruff_macros/src/violation.rs | 4 ++++ 3 files changed, 10 insertions(+) diff --git a/crates/ruff_linter/src/codes.rs b/crates/ruff_linter/src/codes.rs index dc660897003d8a..edd6bcce4da9d4 100644 --- a/crates/ruff_linter/src/codes.rs +++ b/crates/ruff_linter/src/codes.rs @@ -428,7 +428,9 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { (Flake8Annotations, "001") => (RuleGroup::Stable, rules::flake8_annotations::rules::MissingTypeFunctionArgument), (Flake8Annotations, "002") => (RuleGroup::Stable, rules::flake8_annotations::rules::MissingTypeArgs), (Flake8Annotations, "003") => (RuleGroup::Stable, rules::flake8_annotations::rules::MissingTypeKwargs), + #[allow(deprecated)] (Flake8Annotations, "101") => (RuleGroup::Removed, rules::flake8_annotations::rules::MissingTypeSelf), + #[allow(deprecated)] (Flake8Annotations, "102") => (RuleGroup::Removed, rules::flake8_annotations::rules::MissingTypeCls), (Flake8Annotations, "201") => (RuleGroup::Stable, rules::flake8_annotations::rules::MissingReturnTypeUndocumentedPublicFunction), (Flake8Annotations, "202") => (RuleGroup::Stable, rules::flake8_annotations::rules::MissingReturnTypePrivateFunction), diff --git a/crates/ruff_linter/src/rules/flake8_annotations/rules/definition.rs b/crates/ruff_linter/src/rules/flake8_annotations/rules/definition.rs index ae27e73722d4d7..aed85eb1028327 100644 --- a/crates/ruff_linter/src/rules/flake8_annotations/rules/definition.rs +++ b/crates/ruff_linter/src/rules/flake8_annotations/rules/definition.rs @@ -138,8 +138,10 @@ impl Violation for MissingTypeKwargs { /// def bar(self: "Foo"): ... /// ``` #[violation] +#[deprecated(note = "ANN101 has been removed")] pub struct MissingTypeSelf; +#[allow(deprecated)] impl Violation for MissingTypeSelf { fn message(&self) -> String { unreachable!("ANN101 has been removed"); @@ -180,8 +182,10 @@ impl Violation for MissingTypeSelf { /// def bar(cls: Type["Foo"]): ... /// ``` #[violation] +#[deprecated(note = "ANN102 has been removed")] pub struct MissingTypeCls; +#[allow(deprecated)] impl Violation for MissingTypeCls { fn message(&self) -> String { unreachable!("ANN102 has been removed") diff --git a/crates/ruff_macros/src/violation.rs b/crates/ruff_macros/src/violation.rs index 028a5e5a413304..93a9efa5bd7be8 100644 --- a/crates/ruff_macros/src/violation.rs +++ b/crates/ruff_macros/src/violation.rs @@ -53,6 +53,7 @@ pub(crate) fn violation(violation: &ItemStruct) -> Result { #[derive(Debug, PartialEq, Eq)] #violation + #[allow(deprecated)] #[automatically_derived] impl From<#ident> for ruff_diagnostics::DiagnosticKind { fn from(value: #ident) -> Self { @@ -71,12 +72,15 @@ pub(crate) fn violation(violation: &ItemStruct) -> Result { #[derive(Debug, PartialEq, Eq)] #violation + #[automatically_derived] + #[allow(deprecated)] impl #ident { pub fn explanation() -> Option<&'static str> { Some(#explanation) } } + #[allow(deprecated)] #[automatically_derived] impl From<#ident> for ruff_diagnostics::DiagnosticKind { fn from(value: #ident) -> Self {