diff --git a/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP040.py b/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP040.py index c83266d380034..f6797167e1f18 100644 --- a/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP040.py +++ b/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP040.py @@ -113,3 +113,18 @@ class Foo: Annotated[T, Gt(0)], # preserved comment ], type_params=(T,) ) + +T: TypeAlias = ( + int + | str +) + +T: TypeAlias = ( # comment0 + # comment1 + int # comment2 + # comment3 + | # comment4 + # comment5 + str # comment6 + # comment7 +) # comment8 diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/pep695/non_pep695_type_alias.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/pep695/non_pep695_type_alias.rs index 7a5e12352354c..ff9215f962535 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/pep695/non_pep695_type_alias.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/pep695/non_pep695_type_alias.rs @@ -3,9 +3,9 @@ use itertools::Itertools; use ruff_diagnostics::{Applicability, Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, ViolationMetadata}; use ruff_python_ast::name::Name; -use ruff_python_ast::{ - visitor::Visitor, Expr, ExprCall, ExprName, Keyword, StmtAnnAssign, StmtAssign, -}; +use ruff_python_ast::parenthesize::parenthesized_range; +use ruff_python_ast::visitor::Visitor; +use ruff_python_ast::{Expr, ExprCall, ExprName, Keyword, StmtAnnAssign, StmtAssign, StmtRef}; use ruff_text_size::{Ranged, TextRange}; use crate::checkers::ast::Checker; @@ -183,8 +183,8 @@ pub(crate) fn non_pep695_type_alias_type(checker: &Checker, stmt: &StmtAssign) { }; checker.report_diagnostic(create_diagnostic( - checker.source(), - stmt.range, + checker, + stmt.into(), &target_name.id, value, &vars, @@ -243,8 +243,8 @@ pub(crate) fn non_pep695_type_alias(checker: &Checker, stmt: &StmtAnnAssign) { } checker.report_diagnostic(create_diagnostic( - checker.source(), - stmt.range(), + checker, + stmt.into(), name, value, &vars, @@ -261,26 +261,30 @@ pub(crate) fn non_pep695_type_alias(checker: &Checker, stmt: &StmtAnnAssign) { /// Generate a [`Diagnostic`] for a non-PEP 695 type alias or type alias type. fn create_diagnostic( - source: &str, - stmt_range: TextRange, + checker: &Checker, + stmt: StmtRef, name: &Name, value: &Expr, type_vars: &[TypeVar], applicability: Applicability, type_alias_kind: TypeAliasKind, ) -> Diagnostic { + let source = checker.source(); + let range_with_parentheses = + parenthesized_range(value.into(), stmt.into(), checker.comment_ranges(), source) + .unwrap_or(value.range()); let content = format!( "type {name}{type_params} = {value}", type_params = DisplayTypeVars { type_vars, source }, - value = &source[value.range()] + value = &source[range_with_parentheses] ); - let edit = Edit::range_replacement(content, stmt_range); + let edit = Edit::range_replacement(content, stmt.range()); Diagnostic::new( NonPEP695TypeAlias { name: name.to_string(), type_alias_kind, }, - stmt_range, + stmt.range(), ) .with_fix(Fix::applicable_edit(edit, applicability)) } diff --git a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP040.py.snap b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP040.py.snap index 9b6ec2d5c99ec..1c5818c218f29 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP040.py.snap +++ b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP040.py.snap @@ -417,6 +417,8 @@ UP040.py:111:1: UP040 [*] Type alias `PositiveList` uses `TypeAliasType` assignm 114 | | ], type_params=(T,) 115 | | ) | |_^ UP040 +116 | +117 | T: TypeAlias = ( | = help: Use the `type` keyword @@ -431,3 +433,57 @@ UP040.py:111:1: UP040 [*] Type alias `PositiveList` uses `TypeAliasType` assignm 114 |- ], type_params=(T,) 115 |-) 113 |+ ] +116 114 | +117 115 | T: TypeAlias = ( +118 116 | int + +UP040.py:117:1: UP040 [*] Type alias `T` uses `TypeAlias` annotation instead of the `type` keyword + | +115 | ) +116 | +117 | / T: TypeAlias = ( +118 | | int +119 | | | str +120 | | ) + | |_^ UP040 +121 | +122 | T: TypeAlias = ( # comment0 + | + = help: Use the `type` keyword + +ℹ Unsafe fix +114 114 | ], type_params=(T,) +115 115 | ) +116 116 | +117 |-T: TypeAlias = ( + 117 |+type T = ( +118 118 | int +119 119 | | str +120 120 | ) + +UP040.py:122:1: UP040 [*] Type alias `T` uses `TypeAlias` annotation instead of the `type` keyword + | +120 | ) +121 | +122 | / T: TypeAlias = ( # comment0 +123 | | # comment1 +124 | | int # comment2 +125 | | # comment3 +126 | | | # comment4 +127 | | # comment5 +128 | | str # comment6 +129 | | # comment7 +130 | | ) # comment8 + | |_^ UP040 + | + = help: Use the `type` keyword + +ℹ Unsafe fix +119 119 | | str +120 120 | ) +121 121 | +122 |-T: TypeAlias = ( # comment0 + 122 |+type T = ( # comment0 +123 123 | # comment1 +124 124 | int # comment2 +125 125 | # comment3