Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down
2 changes: 0 additions & 2 deletions crates/ruff_linter/src/checkers/ast/analyze/definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 4 additions & 2 deletions crates/ruff_linter/src/codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -428,8 +428,10 @@ 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),
#[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),
(Flake8Annotations, "204") => (RuleGroup::Stable, rules::flake8_annotations::rules::MissingReturnTypeSpecialMethod),
Expand Down
8 changes: 0 additions & 8 deletions crates/ruff_linter/src/rules/flake8_annotations/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ mod tests {
Rule::MissingTypeFunctionArgument,
Rule::MissingTypeArgs,
Rule::MissingTypeKwargs,
Rule::MissingTypeSelf,
Rule::MissingTypeCls,
Rule::MissingReturnTypeUndocumentedPublicFunction,
Rule::MissingReturnTypePrivateFunction,
Rule::MissingReturnTypeSpecialMethod,
Expand All @@ -52,8 +50,6 @@ mod tests {
Rule::MissingTypeFunctionArgument,
Rule::MissingTypeArgs,
Rule::MissingTypeKwargs,
Rule::MissingTypeSelf,
Rule::MissingTypeCls,
Rule::MissingReturnTypeUndocumentedPublicFunction,
Rule::MissingReturnTypePrivateFunction,
Rule::MissingReturnTypeSpecialMethod,
Expand All @@ -80,8 +76,6 @@ mod tests {
Rule::MissingTypeFunctionArgument,
Rule::MissingTypeArgs,
Rule::MissingTypeKwargs,
Rule::MissingTypeSelf,
Rule::MissingTypeCls,
])
},
)?;
Expand Down Expand Up @@ -161,8 +155,6 @@ mod tests {
Rule::MissingTypeFunctionArgument,
Rule::MissingTypeArgs,
Rule::MissingTypeKwargs,
Rule::MissingTypeSelf,
Rule::MissingTypeCls,
Rule::MissingReturnTypeUndocumentedPublicFunction,
Rule::MissingReturnTypePrivateFunction,
Rule::MissingReturnTypeSpecialMethod,
Expand Down
96 changes: 36 additions & 60 deletions crates/ruff_linter/src/rules/flake8_annotations/rules/definition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -139,21 +138,22 @@ impl Violation for MissingTypeKwargs {
/// def bar(self: "Foo"): ...
/// ```
#[violation]
pub struct MissingTypeSelf {
name: String,
}
#[deprecated(note = "ANN101 has been removed")]
pub struct MissingTypeSelf;

#[allow(deprecated)]
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.
Expand Down Expand Up @@ -182,15 +182,17 @@ impl Violation for MissingTypeSelf {
/// def bar(cls: Type["Foo"]): ...
/// ```
#[violation]
pub struct MissingTypeCls {
name: String,
}
#[deprecated(note = "ANN102 has been removed")]
pub struct MissingTypeCls;

#[allow(deprecated)]
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"]
}
}

Expand Down Expand Up @@ -594,7 +596,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.
Expand Down Expand Up @@ -697,43 +698,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;
Expand Down Expand Up @@ -927,13 +891,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![]
}
}
Original file line number Diff line number Diff line change
@@ -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`
|
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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=}")
|
4 changes: 4 additions & 0 deletions crates/ruff_macros/src/violation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ pub(crate) fn violation(violation: &ItemStruct) -> Result<TokenStream> {
#[derive(Debug, PartialEq, Eq)]
#violation

#[allow(deprecated)]
#[automatically_derived]
impl From<#ident> for ruff_diagnostics::DiagnosticKind {
fn from(value: #ident) -> Self {
Expand All @@ -71,12 +72,15 @@ pub(crate) fn violation(violation: &ItemStruct) -> Result<TokenStream> {
#[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 {
Expand Down
4 changes: 0 additions & 4 deletions ruff.schema.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.