From 9c64d655528f5f4ae35b3af471d6562bb73d96d5 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Mon, 3 Feb 2025 14:23:58 +0000 Subject: [PATCH] [`flake8-pyi`] Rename `PYI019` and improve its diagnostic message (#15885) --- .../src/checkers/ast/analyze/bindings.rs | 6 +- crates/ruff_linter/src/codes.rs | 2 +- .../ruff_linter/src/rules/flake8_pyi/mod.rs | 10 +- ...rn_type.rs => custom_type_var_for_self.rs} | 103 ++++++++--------- .../src/rules/flake8_pyi/rules/mod.rs | 4 +- ...flake8_pyi__tests__PYI019_PYI019_0.py.snap | 88 +++++++-------- ...lake8_pyi__tests__PYI019_PYI019_0.pyi.snap | 104 +++++++++--------- ...lake8_pyi__tests__PYI019_PYI019_1.pyi.snap | 4 +- ...i__tests__preview_PYI019_PYI019_0.pyi.snap | 104 +++++++++--------- ...i__tests__preview_PYI019_PYI019_1.pyi.snap | 4 +- 10 files changed, 207 insertions(+), 222 deletions(-) rename crates/ruff_linter/src/rules/flake8_pyi/rules/{custom_type_var_return_type.rs => custom_type_var_for_self.rs} (82%) diff --git a/crates/ruff_linter/src/checkers/ast/analyze/bindings.rs b/crates/ruff_linter/src/checkers/ast/analyze/bindings.rs index 64dc06984e776..3815ea21e30c2 100644 --- a/crates/ruff_linter/src/checkers/ast/analyze/bindings.rs +++ b/crates/ruff_linter/src/checkers/ast/analyze/bindings.rs @@ -23,7 +23,7 @@ pub(crate) fn bindings(checker: &mut Checker) { Rule::UsedDummyVariable, Rule::PytestUnittestRaisesAssertion, Rule::ForLoopWrites, - Rule::CustomTypeVarReturnType, + Rule::CustomTypeVarForSelf, ]) { return; } @@ -116,9 +116,9 @@ pub(crate) fn bindings(checker: &mut Checker) { checker.diagnostics.push(diagnostic); } } - if checker.enabled(Rule::CustomTypeVarReturnType) { + if checker.enabled(Rule::CustomTypeVarForSelf) { if let Some(diagnostic) = - flake8_pyi::rules::custom_type_var_return_type(checker, binding) + flake8_pyi::rules::custom_type_var_instead_of_self(checker, binding) { checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/codes.rs b/crates/ruff_linter/src/codes.rs index 3041fcbf8bad0..bac27d3205e81 100644 --- a/crates/ruff_linter/src/codes.rs +++ b/crates/ruff_linter/src/codes.rs @@ -765,7 +765,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { (Flake8Pyi, "016") => (RuleGroup::Stable, rules::flake8_pyi::rules::DuplicateUnionMember), (Flake8Pyi, "017") => (RuleGroup::Stable, rules::flake8_pyi::rules::ComplexAssignmentInStub), (Flake8Pyi, "018") => (RuleGroup::Stable, rules::flake8_pyi::rules::UnusedPrivateTypeVar), - (Flake8Pyi, "019") => (RuleGroup::Stable, rules::flake8_pyi::rules::CustomTypeVarReturnType), + (Flake8Pyi, "019") => (RuleGroup::Stable, rules::flake8_pyi::rules::CustomTypeVarForSelf), (Flake8Pyi, "020") => (RuleGroup::Stable, rules::flake8_pyi::rules::QuotedAnnotationInStub), (Flake8Pyi, "021") => (RuleGroup::Stable, rules::flake8_pyi::rules::DocstringInStub), (Flake8Pyi, "024") => (RuleGroup::Stable, rules::flake8_pyi::rules::CollectionsNamedTuple), diff --git a/crates/ruff_linter/src/rules/flake8_pyi/mod.rs b/crates/ruff_linter/src/rules/flake8_pyi/mod.rs index 7e5488eda5a5c..2abc11a40cdfd 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/mod.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/mod.rs @@ -136,9 +136,9 @@ mod tests { Ok(()) } - #[test_case(Rule::CustomTypeVarReturnType, Path::new("PYI019_0.py"))] - #[test_case(Rule::CustomTypeVarReturnType, Path::new("PYI019_0.pyi"))] - #[test_case(Rule::CustomTypeVarReturnType, Path::new("PYI019_1.pyi"))] + #[test_case(Rule::CustomTypeVarForSelf, Path::new("PYI019_0.py"))] + #[test_case(Rule::CustomTypeVarForSelf, Path::new("PYI019_0.pyi"))] + #[test_case(Rule::CustomTypeVarForSelf, Path::new("PYI019_1.pyi"))] fn custom_classmethod_rules(rule_code: Rule, path: &Path) -> Result<()> { let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy()); let diagnostics = test_path( @@ -155,8 +155,8 @@ mod tests { Ok(()) } - #[test_case(Rule::CustomTypeVarReturnType, Path::new("PYI019_0.pyi"))] - #[test_case(Rule::CustomTypeVarReturnType, Path::new("PYI019_1.pyi"))] + #[test_case(Rule::CustomTypeVarForSelf, Path::new("PYI019_0.pyi"))] + #[test_case(Rule::CustomTypeVarForSelf, Path::new("PYI019_1.pyi"))] fn custom_classmethod_rules_preview(rule_code: Rule, path: &Path) -> Result<()> { let snapshot = format!( "preview_{}_{}", diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/custom_type_var_return_type.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/custom_type_var_for_self.rs similarity index 82% rename from crates/ruff_linter/src/rules/flake8_pyi/rules/custom_type_var_return_type.rs rename to crates/ruff_linter/src/rules/flake8_pyi/rules/custom_type_var_for_self.rs index 40d535d04596d..f7d7bfced3d06 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/custom_type_var_return_type.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/custom_type_var_for_self.rs @@ -14,8 +14,8 @@ use crate::importer::{ImportRequest, ResolutionError}; use crate::settings::types::PythonVersion; /// ## What it does -/// Checks for methods that define a custom `TypeVar` for their return type -/// annotation instead of using `Self`. +/// Checks for methods that use custom `TypeVar`s in their annotations +/// when they could use `Self` instead. /// /// ## Why is this bad? /// While the semantics are often identical, using `Self` is more intuitive @@ -24,7 +24,8 @@ use crate::settings::types::PythonVersion; /// on the `self` and `cls` arguments. /// /// This check currently applies to instance methods that return `self`, -/// class methods that return an instance of `cls`, and `__new__` methods. +/// class methods that return an instance of `cls`, class methods that return +/// `cls`, and `__new__` methods. /// /// ## Example /// @@ -59,26 +60,31 @@ use crate::settings::types::PythonVersion; /// [PEP 673]: https://peps.python.org/pep-0673/#motivation /// [PEP 695]: https://peps.python.org/pep-0695/ #[derive(ViolationMetadata)] -pub(crate) struct CustomTypeVarReturnType { - method_name: String, +pub(crate) struct CustomTypeVarForSelf { + typevar_name: String, } -impl Violation for CustomTypeVarReturnType { +impl Violation for CustomTypeVarForSelf { const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { - let method_name = &self.method_name; - format!("Methods like `{method_name}` should return `Self` instead of a custom `TypeVar`") + format!( + "Use `Self` instead of custom TypeVar `{}`", + &self.typevar_name + ) } fn fix_title(&self) -> Option { - Some("Replace with `Self`".to_string()) + Some(format!( + "Replace TypeVar `{}` with `Self`", + &self.typevar_name + )) } } /// PYI019 -pub(crate) fn custom_type_var_return_type( +pub(crate) fn custom_type_var_instead_of_self( checker: &Checker, binding: &Binding, ) -> Option { @@ -133,13 +139,11 @@ pub(crate) fn custom_type_var_return_type( }), }; - if !method.uses_custom_var(semantic, binding.scope) { - return None; - } + let custom_typevar_name = method.custom_typevar(semantic, binding.scope)?; let mut diagnostic = Diagnostic::new( - CustomTypeVarReturnType { - method_name: function_name.to_string(), + CustomTypeVarForSelf { + typevar_name: custom_typevar_name.to_string(), }, returns.range(), ); @@ -164,10 +168,10 @@ enum Method<'a> { } impl Method<'_> { - fn uses_custom_var(&self, semantic: &SemanticModel, scope: ScopeId) -> bool { + fn custom_typevar(&self, semantic: &SemanticModel, scope: ScopeId) -> Option<&str> { match self { - Self::Class(class_method) => class_method.uses_custom_var(semantic, scope), - Self::Instance(instance_method) => instance_method.uses_custom_var(), + Self::Class(class_method) => class_method.custom_typevar(semantic, scope), + Self::Instance(instance_method) => instance_method.custom_typevar(), } } } @@ -180,58 +184,45 @@ struct ClassMethod<'a> { } impl ClassMethod<'_> { - /// Returns `true` if the class method is annotated with + /// Returns `Some(typevar_name)` if the class method is annotated with /// a custom `TypeVar` that is likely private. - fn uses_custom_var(&self, semantic: &SemanticModel, scope: ScopeId) -> bool { - let ast::Expr::Subscript(ast::ExprSubscript { + fn custom_typevar(&self, semantic: &SemanticModel, scope: ScopeId) -> Option<&str> { + let ast::ExprSubscript { value: cls_annotation_value, slice: cls_annotation_typevar, .. - }) = self.cls_annotation - else { - return false; - }; - - let ast::Expr::Name(cls_annotation_typevar) = &**cls_annotation_typevar else { - return false; - }; - - let cls_annotation_typevar = &cls_annotation_typevar.id; + } = self.cls_annotation.as_subscript_expr()?; - let ast::Expr::Name(ast::ExprName { id, .. }) = &**cls_annotation_value else { - return false; - }; + let cls_annotation_typevar = &cls_annotation_typevar.as_name_expr()?.id; + let ast::ExprName { id, .. } = cls_annotation_value.as_name_expr()?; if id != "type" { - return false; + return None; } if !semantic.has_builtin_binding_in_scope("type", scope) { - return false; + return None; } let return_annotation_typevar = match self.returns { ast::Expr::Name(ast::ExprName { id, .. }) => id, ast::Expr::Subscript(ast::ExprSubscript { value, slice, .. }) => { - let ast::Expr::Name(return_annotation_typevar) = &**slice else { - return false; - }; - let ast::Expr::Name(ast::ExprName { id, .. }) = &**value else { - return false; - }; + let return_annotation_typevar = slice.as_name_expr()?; + let ast::ExprName { id, .. } = value.as_name_expr()?; if id != "type" { - return false; + return None; } &return_annotation_typevar.id } - _ => return false, + _ => return None, }; if cls_annotation_typevar != return_annotation_typevar { - return false; + return None; } is_likely_private_typevar(cls_annotation_typevar, self.type_params) + .then_some(cls_annotation_typevar) } } @@ -243,28 +234,22 @@ struct InstanceMethod<'a> { } impl InstanceMethod<'_> { - /// Returns `true` if the instance method is annotated with + /// Returns `Some(typevar_name)` if the instance method is annotated with /// a custom `TypeVar` that is likely private. - fn uses_custom_var(&self) -> bool { - let ast::Expr::Name(ast::ExprName { + fn custom_typevar(&self) -> Option<&str> { + let ast::ExprName { id: first_arg_type, .. - }) = self.self_annotation - else { - return false; - }; + } = self.self_annotation.as_name_expr()?; - let ast::Expr::Name(ast::ExprName { + let ast::ExprName { id: return_type, .. - }) = self.returns - else { - return false; - }; + } = self.returns.as_name_expr()?; if first_arg_type != return_type { - return false; + return None; } - is_likely_private_typevar(first_arg_type, self.type_params) + is_likely_private_typevar(first_arg_type, self.type_params).then_some(first_arg_type) } } diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/mod.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/mod.rs index 0c50c6abbb108..25be942f197c6 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/mod.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/mod.rs @@ -7,7 +7,7 @@ pub(crate) use bytestring_usage::*; pub(crate) use collections_named_tuple::*; pub(crate) use complex_assignment_in_stub::*; pub(crate) use complex_if_statement_in_stub::*; -pub(crate) use custom_type_var_return_type::*; +pub(crate) use custom_type_var_for_self::*; pub(crate) use docstring_in_stubs::*; pub(crate) use duplicate_literal_member::*; pub(crate) use duplicate_union_member::*; @@ -50,7 +50,7 @@ mod bytestring_usage; mod collections_named_tuple; mod complex_assignment_in_stub; mod complex_if_statement_in_stub; -mod custom_type_var_return_type; +mod custom_type_var_for_self; mod docstring_in_stubs; mod duplicate_literal_member; mod duplicate_union_member; diff --git a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI019_PYI019_0.py.snap b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI019_PYI019_0.py.snap index 33491f69592ea..334acdd4f9911 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI019_PYI019_0.py.snap +++ b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI019_PYI019_0.py.snap @@ -1,63 +1,63 @@ --- source: crates/ruff_linter/src/rules/flake8_pyi/mod.rs --- -PYI019_0.py:7:62: PYI019 Methods like `__new__` should return `Self` instead of a custom `TypeVar` +PYI019_0.py:7:62: PYI019 Use `Self` instead of custom TypeVar `_S` | 6 | class BadClass: 7 | def __new__(cls: type[_S], *args: str, **kwargs: int) -> _S: ... # PYI019 | ^^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `_S` with `Self` -PYI019_0.py:10:54: PYI019 Methods like `bad_instance_method` should return `Self` instead of a custom `TypeVar` +PYI019_0.py:10:54: PYI019 Use `Self` instead of custom TypeVar `_S` | 10 | def bad_instance_method(self: _S, arg: bytes) -> _S: ... # PYI019 | ^^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `_S` with `Self` -PYI019_0.py:14:54: PYI019 Methods like `bad_class_method` should return `Self` instead of a custom `TypeVar` +PYI019_0.py:14:54: PYI019 Use `Self` instead of custom TypeVar `_S` | 13 | @classmethod 14 | def bad_class_method(cls: type[_S], arg: int) -> _S: ... # PYI019 | ^^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `_S` with `Self` -PYI019_0.py:18:55: PYI019 Methods like `bad_posonly_class_method` should return `Self` instead of a custom `TypeVar` +PYI019_0.py:18:55: PYI019 Use `Self` instead of custom TypeVar `_S` | 17 | @classmethod 18 | def bad_posonly_class_method(cls: type[_S], /) -> _S: ... # PYI019 | ^^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `_S` with `Self` -PYI019_0.py:39:63: PYI019 Methods like `__new__` should return `Self` instead of a custom `TypeVar` +PYI019_0.py:39:63: PYI019 Use `Self` instead of custom TypeVar `S` | 37 | # Python > 3.12 38 | class PEP695BadDunderNew[T]: 39 | def __new__[S](cls: type[S], *args: Any, ** kwargs: Any) -> S: ... # PYI019 | ^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.py:42:46: PYI019 Methods like `generic_instance_method` should return `Self` instead of a custom `TypeVar` +PYI019_0.py:42:46: PYI019 Use `Self` instead of custom TypeVar `S` | 42 | def generic_instance_method[S](self: S) -> S: ... # PYI019 | ^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.py:54:32: PYI019 Methods like `foo` should return `Self` instead of a custom `TypeVar` +PYI019_0.py:54:32: PYI019 Use `Self` instead of custom TypeVar `S` | 52 | # in the settings for this test: 53 | @foo_classmethod 54 | def foo[S](cls: type[S]) -> S: ... # PYI019 | ^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.py:61:48: PYI019 Methods like `__new__` should return `Self` instead of a custom `TypeVar` +PYI019_0.py:61:48: PYI019 Use `Self` instead of custom TypeVar `S` | 59 | # Only .pyi gets fixes, no fixes for .py 60 | class PEP695Fix: @@ -66,9 +66,9 @@ PYI019_0.py:61:48: PYI019 Methods like `__new__` should return `Self` instead of 62 | 63 | def __init_subclass__[S](cls: type[S]) -> S: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.py:63:47: PYI019 Methods like `__init_subclass__` should return `Self` instead of a custom `TypeVar` +PYI019_0.py:63:47: PYI019 Use `Self` instead of custom TypeVar `S` | 61 | def __new__[S: PEP695Fix](cls: type[S]) -> S: ... 62 | @@ -77,9 +77,9 @@ PYI019_0.py:63:47: PYI019 Methods like `__init_subclass__` should return `Self` 64 | 65 | def __neg__[S: PEP695Fix](self: S) -> S: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.py:65:43: PYI019 Methods like `__neg__` should return `Self` instead of a custom `TypeVar` +PYI019_0.py:65:43: PYI019 Use `Self` instead of custom TypeVar `S` | 63 | def __init_subclass__[S](cls: type[S]) -> S: ... 64 | @@ -88,9 +88,9 @@ PYI019_0.py:65:43: PYI019 Methods like `__neg__` should return `Self` instead of 66 | 67 | def __pos__[S](self: S) -> S: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.py:67:32: PYI019 Methods like `__pos__` should return `Self` instead of a custom `TypeVar` +PYI019_0.py:67:32: PYI019 Use `Self` instead of custom TypeVar `S` | 65 | def __neg__[S: PEP695Fix](self: S) -> S: ... 66 | @@ -99,9 +99,9 @@ PYI019_0.py:67:32: PYI019 Methods like `__pos__` should return `Self` instead of 68 | 69 | def __add__[S: PEP695Fix](self: S, other: S) -> S: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.py:69:53: PYI019 Methods like `__add__` should return `Self` instead of a custom `TypeVar` +PYI019_0.py:69:53: PYI019 Use `Self` instead of custom TypeVar `S` | 67 | def __pos__[S](self: S) -> S: ... 68 | @@ -110,9 +110,9 @@ PYI019_0.py:69:53: PYI019 Methods like `__add__` should return `Self` instead of 70 | 71 | def __sub__[S](self: S, other: S) -> S: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.py:71:42: PYI019 Methods like `__sub__` should return `Self` instead of a custom `TypeVar` +PYI019_0.py:71:42: PYI019 Use `Self` instead of custom TypeVar `S` | 69 | def __add__[S: PEP695Fix](self: S, other: S) -> S: ... 70 | @@ -121,9 +121,9 @@ PYI019_0.py:71:42: PYI019 Methods like `__sub__` should return `Self` instead of 72 | 73 | @classmethod | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.py:74:59: PYI019 Methods like `class_method_bound` should return `Self` instead of a custom `TypeVar` +PYI019_0.py:74:59: PYI019 Use `Self` instead of custom TypeVar `S` | 73 | @classmethod 74 | def class_method_bound[S: PEP695Fix](cls: type[S]) -> S: ... @@ -131,9 +131,9 @@ PYI019_0.py:74:59: PYI019 Methods like `class_method_bound` should return `Self` 75 | 76 | @classmethod | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.py:77:50: PYI019 Methods like `class_method_unbound` should return `Self` instead of a custom `TypeVar` +PYI019_0.py:77:50: PYI019 Use `Self` instead of custom TypeVar `S` | 76 | @classmethod 77 | def class_method_unbound[S](cls: type[S]) -> S: ... @@ -141,9 +141,9 @@ PYI019_0.py:77:50: PYI019 Methods like `class_method_unbound` should return `Sel 78 | 79 | def instance_method_bound[S: PEP695Fix](self: S) -> S: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.py:79:57: PYI019 Methods like `instance_method_bound` should return `Self` instead of a custom `TypeVar` +PYI019_0.py:79:57: PYI019 Use `Self` instead of custom TypeVar `S` | 77 | def class_method_unbound[S](cls: type[S]) -> S: ... 78 | @@ -152,9 +152,9 @@ PYI019_0.py:79:57: PYI019 Methods like `instance_method_bound` should return `Se 80 | 81 | def instance_method_unbound[S](self: S) -> S: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.py:81:48: PYI019 Methods like `instance_method_unbound` should return `Self` instead of a custom `TypeVar` +PYI019_0.py:81:48: PYI019 Use `Self` instead of custom TypeVar `S` | 79 | def instance_method_bound[S: PEP695Fix](self: S) -> S: ... 80 | @@ -163,9 +163,9 @@ PYI019_0.py:81:48: PYI019 Methods like `instance_method_unbound` should return ` 82 | 83 | def instance_method_bound_with_another_parameter[S: PEP695Fix](self: S, other: S) -> S: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.py:83:90: PYI019 Methods like `instance_method_bound_with_another_parameter` should return `Self` instead of a custom `TypeVar` +PYI019_0.py:83:90: PYI019 Use `Self` instead of custom TypeVar `S` | 81 | def instance_method_unbound[S](self: S) -> S: ... 82 | @@ -174,9 +174,9 @@ PYI019_0.py:83:90: PYI019 Methods like `instance_method_bound_with_another_param 84 | 85 | def instance_method_unbound_with_another_parameter[S](self: S, other: S) -> S: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.py:85:81: PYI019 Methods like `instance_method_unbound_with_another_parameter` should return `Self` instead of a custom `TypeVar` +PYI019_0.py:85:81: PYI019 Use `Self` instead of custom TypeVar `S` | 83 | def instance_method_bound_with_another_parameter[S: PEP695Fix](self: S, other: S) -> S: ... 84 | @@ -185,9 +185,9 @@ PYI019_0.py:85:81: PYI019 Methods like `instance_method_unbound_with_another_par 86 | 87 | def multiple_type_vars[S, *Ts, T](self: S, other: S, /, *args: *Ts, a: T, b: list[T]) -> S: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.py:87:94: PYI019 Methods like `multiple_type_vars` should return `Self` instead of a custom `TypeVar` +PYI019_0.py:87:94: PYI019 Use `Self` instead of custom TypeVar `S` | 85 | def instance_method_unbound_with_another_parameter[S](self: S, other: S) -> S: ... 86 | @@ -196,22 +196,22 @@ PYI019_0.py:87:94: PYI019 Methods like `multiple_type_vars` should return `Self` 88 | 89 | def mixing_old_and_new_style_type_vars[T](self: _S695, a: T, b: T) -> _S695: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.py:89:75: PYI019 Methods like `mixing_old_and_new_style_type_vars` should return `Self` instead of a custom `TypeVar` +PYI019_0.py:89:75: PYI019 Use `Self` instead of custom TypeVar `_S695` | 87 | def multiple_type_vars[S, *Ts, T](self: S, other: S, /, *args: *Ts, a: T, b: list[T]) -> S: ... 88 | 89 | def mixing_old_and_new_style_type_vars[T](self: _S695, a: T, b: T) -> _S695: ... | ^^^^^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `_S695` with `Self` -PYI019_0.py:114:31: PYI019 Methods like `m` should return `Self` instead of a custom `TypeVar` +PYI019_0.py:114:31: PYI019 Use `Self` instead of custom TypeVar `S` | 112 | class SubscriptReturnType: 113 | @classmethod 114 | def m[S](cls: type[S]) -> type[S]: ... # PYI019, but no autofix (yet) | ^^^^^^^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` diff --git a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI019_PYI019_0.pyi.snap b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI019_PYI019_0.pyi.snap index 7ec7c02093378..97490fe7b9bf8 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI019_PYI019_0.pyi.snap +++ b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI019_PYI019_0.pyi.snap @@ -1,63 +1,63 @@ --- source: crates/ruff_linter/src/rules/flake8_pyi/mod.rs --- -PYI019_0.pyi:7:62: PYI019 Methods like `__new__` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:7:62: PYI019 Use `Self` instead of custom TypeVar `_S` | 6 | class BadClass: 7 | def __new__(cls: type[_S], *args: str, **kwargs: int) -> _S: ... # PYI019 | ^^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `_S` with `Self` -PYI019_0.pyi:10:54: PYI019 Methods like `bad_instance_method` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:10:54: PYI019 Use `Self` instead of custom TypeVar `_S` | 10 | def bad_instance_method(self: _S, arg: bytes) -> _S: ... # PYI019 | ^^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `_S` with `Self` -PYI019_0.pyi:14:54: PYI019 Methods like `bad_class_method` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:14:54: PYI019 Use `Self` instead of custom TypeVar `_S` | 13 | @classmethod 14 | def bad_class_method(cls: type[_S], arg: int) -> _S: ... # PYI019 | ^^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `_S` with `Self` -PYI019_0.pyi:18:55: PYI019 Methods like `bad_posonly_class_method` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:18:55: PYI019 Use `Self` instead of custom TypeVar `_S` | 17 | @classmethod 18 | def bad_posonly_class_method(cls: type[_S], /) -> _S: ... # PYI019 | ^^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `_S` with `Self` -PYI019_0.pyi:39:63: PYI019 Methods like `__new__` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:39:63: PYI019 Use `Self` instead of custom TypeVar `S` | 37 | # Python > 3.12 38 | class PEP695BadDunderNew[T]: 39 | def __new__[S](cls: type[S], *args: Any, ** kwargs: Any) -> S: ... # PYI019 | ^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.pyi:42:46: PYI019 Methods like `generic_instance_method` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:42:46: PYI019 Use `Self` instead of custom TypeVar `S` | 42 | def generic_instance_method[S](self: S) -> S: ... # PYI019 | ^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.pyi:54:32: PYI019 Methods like `foo` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:54:32: PYI019 Use `Self` instead of custom TypeVar `S` | 52 | # in the settings for this test: 53 | @foo_classmethod 54 | def foo[S](cls: type[S]) -> S: ... # PYI019 | ^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.pyi:61:48: PYI019 Methods like `__new__` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:61:48: PYI019 Use `Self` instead of custom TypeVar `S` | 59 | # Only .pyi gets fixes, no fixes for .py 60 | class PEP695Fix: @@ -66,9 +66,9 @@ PYI019_0.pyi:61:48: PYI019 Methods like `__new__` should return `Self` instead o 62 | 63 | def __init_subclass__[S](cls: type[S]) -> S: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.pyi:63:47: PYI019 Methods like `__init_subclass__` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:63:47: PYI019 Use `Self` instead of custom TypeVar `S` | 61 | def __new__[S: PEP695Fix](cls: type[S]) -> S: ... 62 | @@ -77,9 +77,9 @@ PYI019_0.pyi:63:47: PYI019 Methods like `__init_subclass__` should return `Self` 64 | 65 | def __neg__[S: PEP695Fix](self: S) -> S: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.pyi:65:43: PYI019 Methods like `__neg__` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:65:43: PYI019 Use `Self` instead of custom TypeVar `S` | 63 | def __init_subclass__[S](cls: type[S]) -> S: ... 64 | @@ -88,9 +88,9 @@ PYI019_0.pyi:65:43: PYI019 Methods like `__neg__` should return `Self` instead o 66 | 67 | def __pos__[S](self: S) -> S: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.pyi:67:32: PYI019 Methods like `__pos__` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:67:32: PYI019 Use `Self` instead of custom TypeVar `S` | 65 | def __neg__[S: PEP695Fix](self: S) -> S: ... 66 | @@ -99,9 +99,9 @@ PYI019_0.pyi:67:32: PYI019 Methods like `__pos__` should return `Self` instead o 68 | 69 | def __add__[S: PEP695Fix](self: S, other: S) -> S: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.pyi:69:53: PYI019 Methods like `__add__` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:69:53: PYI019 Use `Self` instead of custom TypeVar `S` | 67 | def __pos__[S](self: S) -> S: ... 68 | @@ -110,9 +110,9 @@ PYI019_0.pyi:69:53: PYI019 Methods like `__add__` should return `Self` instead o 70 | 71 | def __sub__[S](self: S, other: S) -> S: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.pyi:71:42: PYI019 Methods like `__sub__` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:71:42: PYI019 Use `Self` instead of custom TypeVar `S` | 69 | def __add__[S: PEP695Fix](self: S, other: S) -> S: ... 70 | @@ -121,9 +121,9 @@ PYI019_0.pyi:71:42: PYI019 Methods like `__sub__` should return `Self` instead o 72 | 73 | @classmethod | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.pyi:74:59: PYI019 Methods like `class_method_bound` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:74:59: PYI019 Use `Self` instead of custom TypeVar `S` | 73 | @classmethod 74 | def class_method_bound[S: PEP695Fix](cls: type[S]) -> S: ... @@ -131,9 +131,9 @@ PYI019_0.pyi:74:59: PYI019 Methods like `class_method_bound` should return `Self 75 | 76 | @classmethod | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.pyi:77:50: PYI019 Methods like `class_method_unbound` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:77:50: PYI019 Use `Self` instead of custom TypeVar `S` | 76 | @classmethod 77 | def class_method_unbound[S](cls: type[S]) -> S: ... @@ -141,9 +141,9 @@ PYI019_0.pyi:77:50: PYI019 Methods like `class_method_unbound` should return `Se 78 | 79 | def instance_method_bound[S: PEP695Fix](self: S) -> S: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.pyi:79:57: PYI019 Methods like `instance_method_bound` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:79:57: PYI019 Use `Self` instead of custom TypeVar `S` | 77 | def class_method_unbound[S](cls: type[S]) -> S: ... 78 | @@ -152,9 +152,9 @@ PYI019_0.pyi:79:57: PYI019 Methods like `instance_method_bound` should return `S 80 | 81 | def instance_method_unbound[S](self: S) -> S: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.pyi:81:48: PYI019 Methods like `instance_method_unbound` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:81:48: PYI019 Use `Self` instead of custom TypeVar `S` | 79 | def instance_method_bound[S: PEP695Fix](self: S) -> S: ... 80 | @@ -163,9 +163,9 @@ PYI019_0.pyi:81:48: PYI019 Methods like `instance_method_unbound` should return 82 | 83 | def instance_method_bound_with_another_parameter[S: PEP695Fix](self: S, other: S) -> S: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.pyi:83:90: PYI019 Methods like `instance_method_bound_with_another_parameter` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:83:90: PYI019 Use `Self` instead of custom TypeVar `S` | 81 | def instance_method_unbound[S](self: S) -> S: ... 82 | @@ -174,9 +174,9 @@ PYI019_0.pyi:83:90: PYI019 Methods like `instance_method_bound_with_another_para 84 | 85 | def instance_method_unbound_with_another_parameter[S](self: S, other: S) -> S: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.pyi:85:81: PYI019 Methods like `instance_method_unbound_with_another_parameter` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:85:81: PYI019 Use `Self` instead of custom TypeVar `S` | 83 | def instance_method_bound_with_another_parameter[S: PEP695Fix](self: S, other: S) -> S: ... 84 | @@ -185,9 +185,9 @@ PYI019_0.pyi:85:81: PYI019 Methods like `instance_method_unbound_with_another_pa 86 | 87 | def multiple_type_vars[S, *Ts, T](self: S, other: S, /, *args: *Ts, a: T, b: list[T]) -> S: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.pyi:87:94: PYI019 Methods like `multiple_type_vars` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:87:94: PYI019 Use `Self` instead of custom TypeVar `S` | 85 | def instance_method_unbound_with_another_parameter[S](self: S, other: S) -> S: ... 86 | @@ -196,44 +196,44 @@ PYI019_0.pyi:87:94: PYI019 Methods like `multiple_type_vars` should return `Self 88 | 89 | def mixing_old_and_new_style_type_vars[T](self: _S695, a: T, b: T) -> _S695: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.pyi:89:75: PYI019 Methods like `mixing_old_and_new_style_type_vars` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:89:75: PYI019 Use `Self` instead of custom TypeVar `_S695` | 87 | def multiple_type_vars[S, *Ts, T](self: S, other: S, /, *args: *Ts, a: T, b: list[T]) -> S: ... 88 | 89 | def mixing_old_and_new_style_type_vars[T](self: _S695, a: T, b: T) -> _S695: ... | ^^^^^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `_S695` with `Self` -PYI019_0.pyi:114:31: PYI019 Methods like `m` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:114:31: PYI019 Use `Self` instead of custom TypeVar `S` | 112 | class SubscriptReturnType: 113 | @classmethod 114 | def m[S](cls: type[S]) -> type[S]: ... # PYI019, but no autofix (yet) | ^^^^^^^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.pyi:118:29: PYI019 Methods like `f` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:118:29: PYI019 Use `Self` instead of custom TypeVar `S` | 117 | class PEP695TypeParameterAtTheVeryEndOfTheList: 118 | def f[T, S](self: S) -> S: ... | ^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.pyi:122:100: PYI019 Methods like `mixing_and_nested` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:122:100: PYI019 Use `Self` instead of custom TypeVar `_S695` | 121 | class PEP695Again: 122 | def mixing_and_nested[T](self: _S695, a: list[_S695], b: dict[_S695, str | T | set[_S695]]) -> _S695: ... | ^^^^^ PYI019 123 | def also_uses_s695_but_should_not_be_edited(self, v: set[tuple[_S695]]) -> _S695: ... | - = help: Replace with `Self` + = help: Replace TypeVar `_S695` with `Self` -PYI019_0.pyi:132:10: PYI019 Methods like `comment_in_fix_range` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:132:10: PYI019 Use `Self` instead of custom TypeVar `S` | 130 | a: T, 131 | b: tuple[S, T] @@ -242,13 +242,13 @@ PYI019_0.pyi:132:10: PYI019 Methods like `comment_in_fix_range` should return `S 133 | 134 | def comment_outside_fix_range[T, S]( | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.pyi:141:10: PYI019 Methods like `comment_outside_fix_range` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:141:10: PYI019 Use `Self` instead of custom TypeVar `S` | 139 | S, T 140 | ] 141 | ) -> S: ... | ^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` diff --git a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI019_PYI019_1.pyi.snap b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI019_PYI019_1.pyi.snap index 2bc52a066640e..0e29a0c93f36e 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI019_PYI019_1.pyi.snap +++ b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI019_PYI019_1.pyi.snap @@ -1,10 +1,10 @@ --- source: crates/ruff_linter/src/rules/flake8_pyi/mod.rs --- -PYI019_1.pyi:4:26: PYI019 Methods like `m` should return `Self` instead of a custom `TypeVar` +PYI019_1.pyi:4:26: PYI019 Use `Self` instead of custom TypeVar `S` | 3 | class F: 4 | def m[S](self: S) -> S: ... | ^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` diff --git a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__preview_PYI019_PYI019_0.pyi.snap b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__preview_PYI019_PYI019_0.pyi.snap index ed1d12eede0c6..4189b5b71aaeb 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__preview_PYI019_PYI019_0.pyi.snap +++ b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__preview_PYI019_PYI019_0.pyi.snap @@ -1,13 +1,13 @@ --- source: crates/ruff_linter/src/rules/flake8_pyi/mod.rs --- -PYI019_0.pyi:7:62: PYI019 [*] Methods like `__new__` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:7:62: PYI019 [*] Use `Self` instead of custom TypeVar `_S` | 6 | class BadClass: 7 | def __new__(cls: type[_S], *args: str, **kwargs: int) -> _S: ... # PYI019 | ^^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `_S` with `Self` ℹ Safe fix 4 4 | _S2 = TypeVar("_S2", BadClass, GoodClass) @@ -19,12 +19,12 @@ PYI019_0.pyi:7:62: PYI019 [*] Methods like `__new__` should return `Self` instea 9 9 | 10 10 | def bad_instance_method(self: _S, arg: bytes) -> _S: ... # PYI019 -PYI019_0.pyi:10:54: PYI019 [*] Methods like `bad_instance_method` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:10:54: PYI019 [*] Use `Self` instead of custom TypeVar `_S` | 10 | def bad_instance_method(self: _S, arg: bytes) -> _S: ... # PYI019 | ^^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `_S` with `Self` ℹ Safe fix 7 7 | def __new__(cls: type[_S], *args: str, **kwargs: int) -> _S: ... # PYI019 @@ -36,13 +36,13 @@ PYI019_0.pyi:10:54: PYI019 [*] Methods like `bad_instance_method` should return 12 12 | 13 13 | @classmethod -PYI019_0.pyi:14:54: PYI019 [*] Methods like `bad_class_method` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:14:54: PYI019 [*] Use `Self` instead of custom TypeVar `_S` | 13 | @classmethod 14 | def bad_class_method(cls: type[_S], arg: int) -> _S: ... # PYI019 | ^^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `_S` with `Self` ℹ Safe fix 11 11 | @@ -54,13 +54,13 @@ PYI019_0.pyi:14:54: PYI019 [*] Methods like `bad_class_method` should return `Se 16 16 | 17 17 | @classmethod -PYI019_0.pyi:18:55: PYI019 [*] Methods like `bad_posonly_class_method` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:18:55: PYI019 [*] Use `Self` instead of custom TypeVar `_S` | 17 | @classmethod 18 | def bad_posonly_class_method(cls: type[_S], /) -> _S: ... # PYI019 | ^^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `_S` with `Self` ℹ Safe fix 15 15 | @@ -72,14 +72,14 @@ PYI019_0.pyi:18:55: PYI019 [*] Methods like `bad_posonly_class_method` should re 20 20 | 21 21 | @classmethod -PYI019_0.pyi:39:63: PYI019 [*] Methods like `__new__` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:39:63: PYI019 [*] Use `Self` instead of custom TypeVar `S` | 37 | # Python > 3.12 38 | class PEP695BadDunderNew[T]: 39 | def __new__[S](cls: type[S], *args: Any, ** kwargs: Any) -> S: ... # PYI019 | ^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` ℹ Safe fix 36 36 | @@ -91,12 +91,12 @@ PYI019_0.pyi:39:63: PYI019 [*] Methods like `__new__` should return `Self` inste 41 41 | 42 42 | def generic_instance_method[S](self: S) -> S: ... # PYI019 -PYI019_0.pyi:42:46: PYI019 [*] Methods like `generic_instance_method` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:42:46: PYI019 [*] Use `Self` instead of custom TypeVar `S` | 42 | def generic_instance_method[S](self: S) -> S: ... # PYI019 | ^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` ℹ Safe fix 39 39 | def __new__[S](cls: type[S], *args: Any, ** kwargs: Any) -> S: ... # PYI019 @@ -108,14 +108,14 @@ PYI019_0.pyi:42:46: PYI019 [*] Methods like `generic_instance_method` should ret 44 44 | 45 45 | class PEP695GoodDunderNew[T]: -PYI019_0.pyi:54:32: PYI019 [*] Methods like `foo` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:54:32: PYI019 [*] Use `Self` instead of custom TypeVar `S` | 52 | # in the settings for this test: 53 | @foo_classmethod 54 | def foo[S](cls: type[S]) -> S: ... # PYI019 | ^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` ℹ Safe fix 51 51 | # due to `foo_classmethod being listed in `pep8_naming.classmethod-decorators` @@ -127,7 +127,7 @@ PYI019_0.pyi:54:32: PYI019 [*] Methods like `foo` should return `Self` instead o 56 56 | 57 57 | _S695 = TypeVar("_S695", bound="PEP695Fix") -PYI019_0.pyi:61:48: PYI019 [*] Methods like `__new__` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:61:48: PYI019 [*] Use `Self` instead of custom TypeVar `S` | 59 | # Only .pyi gets fixes, no fixes for .py 60 | class PEP695Fix: @@ -136,7 +136,7 @@ PYI019_0.pyi:61:48: PYI019 [*] Methods like `__new__` should return `Self` inste 62 | 63 | def __init_subclass__[S](cls: type[S]) -> S: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` ℹ Safe fix 58 58 | @@ -148,7 +148,7 @@ PYI019_0.pyi:61:48: PYI019 [*] Methods like `__new__` should return `Self` inste 63 63 | def __init_subclass__[S](cls: type[S]) -> S: ... 64 64 | -PYI019_0.pyi:63:47: PYI019 [*] Methods like `__init_subclass__` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:63:47: PYI019 [*] Use `Self` instead of custom TypeVar `S` | 61 | def __new__[S: PEP695Fix](cls: type[S]) -> S: ... 62 | @@ -157,7 +157,7 @@ PYI019_0.pyi:63:47: PYI019 [*] Methods like `__init_subclass__` should return `S 64 | 65 | def __neg__[S: PEP695Fix](self: S) -> S: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` ℹ Safe fix 60 60 | class PEP695Fix: @@ -169,7 +169,7 @@ PYI019_0.pyi:63:47: PYI019 [*] Methods like `__init_subclass__` should return `S 65 65 | def __neg__[S: PEP695Fix](self: S) -> S: ... 66 66 | -PYI019_0.pyi:65:43: PYI019 [*] Methods like `__neg__` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:65:43: PYI019 [*] Use `Self` instead of custom TypeVar `S` | 63 | def __init_subclass__[S](cls: type[S]) -> S: ... 64 | @@ -178,7 +178,7 @@ PYI019_0.pyi:65:43: PYI019 [*] Methods like `__neg__` should return `Self` inste 66 | 67 | def __pos__[S](self: S) -> S: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` ℹ Safe fix 62 62 | @@ -190,7 +190,7 @@ PYI019_0.pyi:65:43: PYI019 [*] Methods like `__neg__` should return `Self` inste 67 67 | def __pos__[S](self: S) -> S: ... 68 68 | -PYI019_0.pyi:67:32: PYI019 [*] Methods like `__pos__` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:67:32: PYI019 [*] Use `Self` instead of custom TypeVar `S` | 65 | def __neg__[S: PEP695Fix](self: S) -> S: ... 66 | @@ -199,7 +199,7 @@ PYI019_0.pyi:67:32: PYI019 [*] Methods like `__pos__` should return `Self` inste 68 | 69 | def __add__[S: PEP695Fix](self: S, other: S) -> S: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` ℹ Safe fix 64 64 | @@ -211,7 +211,7 @@ PYI019_0.pyi:67:32: PYI019 [*] Methods like `__pos__` should return `Self` inste 69 69 | def __add__[S: PEP695Fix](self: S, other: S) -> S: ... 70 70 | -PYI019_0.pyi:69:53: PYI019 [*] Methods like `__add__` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:69:53: PYI019 [*] Use `Self` instead of custom TypeVar `S` | 67 | def __pos__[S](self: S) -> S: ... 68 | @@ -220,7 +220,7 @@ PYI019_0.pyi:69:53: PYI019 [*] Methods like `__add__` should return `Self` inste 70 | 71 | def __sub__[S](self: S, other: S) -> S: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` ℹ Safe fix 66 66 | @@ -232,7 +232,7 @@ PYI019_0.pyi:69:53: PYI019 [*] Methods like `__add__` should return `Self` inste 71 71 | def __sub__[S](self: S, other: S) -> S: ... 72 72 | -PYI019_0.pyi:71:42: PYI019 [*] Methods like `__sub__` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:71:42: PYI019 [*] Use `Self` instead of custom TypeVar `S` | 69 | def __add__[S: PEP695Fix](self: S, other: S) -> S: ... 70 | @@ -241,7 +241,7 @@ PYI019_0.pyi:71:42: PYI019 [*] Methods like `__sub__` should return `Self` inste 72 | 73 | @classmethod | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` ℹ Safe fix 68 68 | @@ -253,7 +253,7 @@ PYI019_0.pyi:71:42: PYI019 [*] Methods like `__sub__` should return `Self` inste 73 73 | @classmethod 74 74 | def class_method_bound[S: PEP695Fix](cls: type[S]) -> S: ... -PYI019_0.pyi:74:59: PYI019 [*] Methods like `class_method_bound` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:74:59: PYI019 [*] Use `Self` instead of custom TypeVar `S` | 73 | @classmethod 74 | def class_method_bound[S: PEP695Fix](cls: type[S]) -> S: ... @@ -261,7 +261,7 @@ PYI019_0.pyi:74:59: PYI019 [*] Methods like `class_method_bound` should return ` 75 | 76 | @classmethod | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` ℹ Safe fix 71 71 | def __sub__[S](self: S, other: S) -> S: ... @@ -273,7 +273,7 @@ PYI019_0.pyi:74:59: PYI019 [*] Methods like `class_method_bound` should return ` 76 76 | @classmethod 77 77 | def class_method_unbound[S](cls: type[S]) -> S: ... -PYI019_0.pyi:77:50: PYI019 [*] Methods like `class_method_unbound` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:77:50: PYI019 [*] Use `Self` instead of custom TypeVar `S` | 76 | @classmethod 77 | def class_method_unbound[S](cls: type[S]) -> S: ... @@ -281,7 +281,7 @@ PYI019_0.pyi:77:50: PYI019 [*] Methods like `class_method_unbound` should return 78 | 79 | def instance_method_bound[S: PEP695Fix](self: S) -> S: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` ℹ Safe fix 74 74 | def class_method_bound[S: PEP695Fix](cls: type[S]) -> S: ... @@ -293,7 +293,7 @@ PYI019_0.pyi:77:50: PYI019 [*] Methods like `class_method_unbound` should return 79 79 | def instance_method_bound[S: PEP695Fix](self: S) -> S: ... 80 80 | -PYI019_0.pyi:79:57: PYI019 [*] Methods like `instance_method_bound` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:79:57: PYI019 [*] Use `Self` instead of custom TypeVar `S` | 77 | def class_method_unbound[S](cls: type[S]) -> S: ... 78 | @@ -302,7 +302,7 @@ PYI019_0.pyi:79:57: PYI019 [*] Methods like `instance_method_bound` should retur 80 | 81 | def instance_method_unbound[S](self: S) -> S: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` ℹ Safe fix 76 76 | @classmethod @@ -314,7 +314,7 @@ PYI019_0.pyi:79:57: PYI019 [*] Methods like `instance_method_bound` should retur 81 81 | def instance_method_unbound[S](self: S) -> S: ... 82 82 | -PYI019_0.pyi:81:48: PYI019 [*] Methods like `instance_method_unbound` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:81:48: PYI019 [*] Use `Self` instead of custom TypeVar `S` | 79 | def instance_method_bound[S: PEP695Fix](self: S) -> S: ... 80 | @@ -323,7 +323,7 @@ PYI019_0.pyi:81:48: PYI019 [*] Methods like `instance_method_unbound` should ret 82 | 83 | def instance_method_bound_with_another_parameter[S: PEP695Fix](self: S, other: S) -> S: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` ℹ Safe fix 78 78 | @@ -335,7 +335,7 @@ PYI019_0.pyi:81:48: PYI019 [*] Methods like `instance_method_unbound` should ret 83 83 | def instance_method_bound_with_another_parameter[S: PEP695Fix](self: S, other: S) -> S: ... 84 84 | -PYI019_0.pyi:83:90: PYI019 [*] Methods like `instance_method_bound_with_another_parameter` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:83:90: PYI019 [*] Use `Self` instead of custom TypeVar `S` | 81 | def instance_method_unbound[S](self: S) -> S: ... 82 | @@ -344,7 +344,7 @@ PYI019_0.pyi:83:90: PYI019 [*] Methods like `instance_method_bound_with_another_ 84 | 85 | def instance_method_unbound_with_another_parameter[S](self: S, other: S) -> S: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` ℹ Safe fix 80 80 | @@ -356,7 +356,7 @@ PYI019_0.pyi:83:90: PYI019 [*] Methods like `instance_method_bound_with_another_ 85 85 | def instance_method_unbound_with_another_parameter[S](self: S, other: S) -> S: ... 86 86 | -PYI019_0.pyi:85:81: PYI019 [*] Methods like `instance_method_unbound_with_another_parameter` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:85:81: PYI019 [*] Use `Self` instead of custom TypeVar `S` | 83 | def instance_method_bound_with_another_parameter[S: PEP695Fix](self: S, other: S) -> S: ... 84 | @@ -365,7 +365,7 @@ PYI019_0.pyi:85:81: PYI019 [*] Methods like `instance_method_unbound_with_anothe 86 | 87 | def multiple_type_vars[S, *Ts, T](self: S, other: S, /, *args: *Ts, a: T, b: list[T]) -> S: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` ℹ Safe fix 82 82 | @@ -377,7 +377,7 @@ PYI019_0.pyi:85:81: PYI019 [*] Methods like `instance_method_unbound_with_anothe 87 87 | def multiple_type_vars[S, *Ts, T](self: S, other: S, /, *args: *Ts, a: T, b: list[T]) -> S: ... 88 88 | -PYI019_0.pyi:87:94: PYI019 [*] Methods like `multiple_type_vars` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:87:94: PYI019 [*] Use `Self` instead of custom TypeVar `S` | 85 | def instance_method_unbound_with_another_parameter[S](self: S, other: S) -> S: ... 86 | @@ -386,7 +386,7 @@ PYI019_0.pyi:87:94: PYI019 [*] Methods like `multiple_type_vars` should return ` 88 | 89 | def mixing_old_and_new_style_type_vars[T](self: _S695, a: T, b: T) -> _S695: ... | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` ℹ Safe fix 84 84 | @@ -398,14 +398,14 @@ PYI019_0.pyi:87:94: PYI019 [*] Methods like `multiple_type_vars` should return ` 89 89 | def mixing_old_and_new_style_type_vars[T](self: _S695, a: T, b: T) -> _S695: ... 90 90 | -PYI019_0.pyi:89:75: PYI019 [*] Methods like `mixing_old_and_new_style_type_vars` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:89:75: PYI019 [*] Use `Self` instead of custom TypeVar `_S695` | 87 | def multiple_type_vars[S, *Ts, T](self: S, other: S, /, *args: *Ts, a: T, b: list[T]) -> S: ... 88 | 89 | def mixing_old_and_new_style_type_vars[T](self: _S695, a: T, b: T) -> _S695: ... | ^^^^^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `_S695` with `Self` ℹ Safe fix 86 86 | @@ -417,22 +417,22 @@ PYI019_0.pyi:89:75: PYI019 [*] Methods like `mixing_old_and_new_style_type_vars` 91 91 | 92 92 | class InvalidButWeDoNotPanic: -PYI019_0.pyi:114:31: PYI019 Methods like `m` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:114:31: PYI019 Use `Self` instead of custom TypeVar `S` | 112 | class SubscriptReturnType: 113 | @classmethod 114 | def m[S](cls: type[S]) -> type[S]: ... # PYI019, but no autofix (yet) | ^^^^^^^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` -PYI019_0.pyi:118:29: PYI019 [*] Methods like `f` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:118:29: PYI019 [*] Use `Self` instead of custom TypeVar `S` | 117 | class PEP695TypeParameterAtTheVeryEndOfTheList: 118 | def f[T, S](self: S) -> S: ... | ^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` ℹ Safe fix 115 115 | @@ -444,14 +444,14 @@ PYI019_0.pyi:118:29: PYI019 [*] Methods like `f` should return `Self` instead of 120 120 | 121 121 | class PEP695Again: -PYI019_0.pyi:122:100: PYI019 [*] Methods like `mixing_and_nested` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:122:100: PYI019 [*] Use `Self` instead of custom TypeVar `_S695` | 121 | class PEP695Again: 122 | def mixing_and_nested[T](self: _S695, a: list[_S695], b: dict[_S695, str | T | set[_S695]]) -> _S695: ... | ^^^^^ PYI019 123 | def also_uses_s695_but_should_not_be_edited(self, v: set[tuple[_S695]]) -> _S695: ... | - = help: Replace with `Self` + = help: Replace TypeVar `_S695` with `Self` ℹ Safe fix 119 119 | @@ -463,7 +463,7 @@ PYI019_0.pyi:122:100: PYI019 [*] Methods like `mixing_and_nested` should return 124 124 | 125 125 | @classmethod -PYI019_0.pyi:132:10: PYI019 [*] Methods like `comment_in_fix_range` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:132:10: PYI019 [*] Use `Self` instead of custom TypeVar `S` | 130 | a: T, 131 | b: tuple[S, T] @@ -472,7 +472,7 @@ PYI019_0.pyi:132:10: PYI019 [*] Methods like `comment_in_fix_range` should retur 133 | 134 | def comment_outside_fix_range[T, S]( | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` ℹ Unsafe fix 123 123 | def also_uses_s695_but_should_not_be_edited(self, v: set[tuple[_S695]]) -> _S695: ... @@ -493,14 +493,14 @@ PYI019_0.pyi:132:10: PYI019 [*] Methods like `comment_in_fix_range` should retur 134 132 | def comment_outside_fix_range[T, S]( 135 133 | self: S, -PYI019_0.pyi:141:10: PYI019 [*] Methods like `comment_outside_fix_range` should return `Self` instead of a custom `TypeVar` +PYI019_0.pyi:141:10: PYI019 [*] Use `Self` instead of custom TypeVar `S` | 139 | S, T 140 | ] 141 | ) -> S: ... | ^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` ℹ Safe fix 131 131 | b: tuple[S, T] diff --git a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__preview_PYI019_PYI019_1.pyi.snap b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__preview_PYI019_PYI019_1.pyi.snap index 7ab8f24ddf758..ab82c7b5385ca 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__preview_PYI019_PYI019_1.pyi.snap +++ b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__preview_PYI019_PYI019_1.pyi.snap @@ -1,13 +1,13 @@ --- source: crates/ruff_linter/src/rules/flake8_pyi/mod.rs --- -PYI019_1.pyi:4:26: PYI019 [*] Methods like `m` should return `Self` instead of a custom `TypeVar` +PYI019_1.pyi:4:26: PYI019 [*] Use `Self` instead of custom TypeVar `S` | 3 | class F: 4 | def m[S](self: S) -> S: ... | ^ PYI019 | - = help: Replace with `Self` + = help: Replace TypeVar `S` with `Self` ℹ Safe fix 1 1 | import typing