[flake8-annotations] Correct syntax for typing.Union in suggested return type fixes for ANN20x rules (#16025)

When suggesting a return type as a union in Python <=3.9, we now avoid a
`TypeError` by correctly suggesting syntax like `Union[int,str,None]`
instead of `Union[int | str | None]`.
This commit is contained in:
Dylan 2025-02-07 17:17:20 -06:00 committed by GitHub
parent a29009e4ed
commit 3a806ecaa1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 20 additions and 32 deletions

View file

@ -1,6 +1,5 @@
--- ---
source: crates/ruff_linter/src/rules/flake8_annotations/mod.rs source: crates/ruff_linter/src/rules/flake8_annotations/mod.rs
snapshot_kind: text
--- ---
auto_return_type.py:1:5: ANN201 [*] Missing return type annotation for public function `func` auto_return_type.py:1:5: ANN201 [*] Missing return type annotation for public function `func`
| |
@ -97,7 +96,7 @@ auto_return_type.py:27:5: ANN201 [*] Missing return type annotation for public f
| ^^^^ ANN201 | ^^^^ ANN201
28 | return 1 or 2.5 if x > 0 else 1.5 or "str" 28 | return 1 or 2.5 if x > 0 else 1.5 or "str"
| |
= help: Add return type annotation: `Union[str | float]` = help: Add return type annotation: `Union[str, float]`
Unsafe fix Unsafe fix
1 |+from typing import Union 1 |+from typing import Union
@ -109,7 +108,7 @@ auto_return_type.py:27:5: ANN201 [*] Missing return type annotation for public f
25 26 | 25 26 |
26 27 | 26 27 |
27 |-def func(x: int): 27 |-def func(x: int):
28 |+def func(x: int) -> Union[str | float]: 28 |+def func(x: int) -> Union[str, float]:
28 29 | return 1 or 2.5 if x > 0 else 1.5 or "str" 28 29 | return 1 or 2.5 if x > 0 else 1.5 or "str"
29 30 | 29 30 |
30 31 | 30 31 |
@ -120,7 +119,7 @@ auto_return_type.py:31:5: ANN201 [*] Missing return type annotation for public f
| ^^^^ ANN201 | ^^^^ ANN201
32 | return 1 + 2.5 if x > 0 else 1.5 or "str" 32 | return 1 + 2.5 if x > 0 else 1.5 or "str"
| |
= help: Add return type annotation: `Union[str | float]` = help: Add return type annotation: `Union[str, float]`
Unsafe fix Unsafe fix
1 |+from typing import Union 1 |+from typing import Union
@ -132,7 +131,7 @@ auto_return_type.py:31:5: ANN201 [*] Missing return type annotation for public f
29 30 | 29 30 |
30 31 | 30 31 |
31 |-def func(x: int): 31 |-def func(x: int):
32 |+def func(x: int) -> Union[str | float]: 32 |+def func(x: int) -> Union[str, float]:
32 33 | return 1 + 2.5 if x > 0 else 1.5 or "str" 32 33 | return 1 + 2.5 if x > 0 else 1.5 or "str"
33 34 | 33 34 |
34 35 | 34 35 |
@ -204,7 +203,7 @@ auto_return_type.py:59:5: ANN201 [*] Missing return type annotation for public f
60 | if not x: 60 | if not x:
61 | return 1 61 | return 1
| |
= help: Add return type annotation: `Union[str | int | None]` = help: Add return type annotation: `Union[str, int, None]`
Unsafe fix Unsafe fix
1 |+from typing import Union 1 |+from typing import Union
@ -216,7 +215,7 @@ auto_return_type.py:59:5: ANN201 [*] Missing return type annotation for public f
57 58 | 57 58 |
58 59 | 58 59 |
59 |-def func(x: int): 59 |-def func(x: int):
60 |+def func(x: int) -> Union[str | int | None]: 60 |+def func(x: int) -> Union[str, int, None]:
60 61 | if not x: 60 61 | if not x:
61 62 | return 1 61 62 | return 1
62 63 | elif x > 5: 62 63 | elif x > 5:
@ -294,7 +293,7 @@ auto_return_type.py:82:5: ANN201 [*] Missing return type annotation for public f
83 | match x: 83 | match x:
84 | case [1, 2, 3]: 84 | case [1, 2, 3]:
| |
= help: Add return type annotation: `Union[str | int | None]` = help: Add return type annotation: `Union[str, int, None]`
Unsafe fix Unsafe fix
1 |+from typing import Union 1 |+from typing import Union
@ -306,7 +305,7 @@ auto_return_type.py:82:5: ANN201 [*] Missing return type annotation for public f
80 81 | 80 81 |
81 82 | 81 82 |
82 |-def func(x: int): 82 |-def func(x: int):
83 |+def func(x: int) -> Union[str | int | None]: 83 |+def func(x: int) -> Union[str, int, None]:
83 84 | match x: 83 84 | match x:
84 85 | case [1, 2, 3]: 84 85 | case [1, 2, 3]:
85 86 | return 1 85 86 | return 1
@ -853,7 +852,7 @@ auto_return_type.py:299:5: ANN201 [*] Missing return type annotation for public
300 | match x: 300 | match x:
301 | case [1, 2, 3]: 301 | case [1, 2, 3]:
| |
= help: Add return type annotation: `Union[str | int]` = help: Add return type annotation: `Union[str, int]`
Unsafe fix Unsafe fix
214 214 | return 1 214 214 | return 1
@ -869,7 +868,7 @@ auto_return_type.py:299:5: ANN201 [*] Missing return type annotation for public
297 297 | 297 297 |
298 298 | 298 298 |
299 |-def func(x: int): 299 |-def func(x: int):
299 |+def func(x: int) -> Union[str | int]: 299 |+def func(x: int) -> Union[str, int]:
300 300 | match x: 300 300 | match x:
301 301 | case [1, 2, 3]: 301 301 | case [1, 2, 3]:
302 302 | return 1 302 302 | return 1

View file

@ -1437,33 +1437,22 @@ pub fn typing_optional(elt: Expr, binding: Name) -> Expr {
} }
/// Format the expressions as a `typing.Union`-style union. /// Format the expressions as a `typing.Union`-style union.
///
/// Note: It is a syntax error to have `Union[]` so the caller
/// should ensure that the `elts` argument is nonempty.
pub fn typing_union(elts: &[Expr], binding: Name) -> Expr { pub fn typing_union(elts: &[Expr], binding: Name) -> Expr {
fn tuple(elts: &[Expr], binding: Name) -> Expr {
match elts {
[] => Expr::Tuple(ast::ExprTuple {
elts: vec![],
ctx: ExprContext::Load,
range: TextRange::default(),
parenthesized: true,
}),
[Expr::Tuple(ast::ExprTuple { elts, .. })] => typing_union(elts, binding),
[elt] => elt.clone(),
[rest @ .., elt] => Expr::BinOp(ast::ExprBinOp {
left: Box::new(tuple(rest, binding)),
op: Operator::BitOr,
right: Box::new(elt.clone()),
range: TextRange::default(),
}),
}
}
Expr::Subscript(ast::ExprSubscript { Expr::Subscript(ast::ExprSubscript {
value: Box::new(Expr::Name(ast::ExprName { value: Box::new(Expr::Name(ast::ExprName {
id: binding.clone(), id: binding,
range: TextRange::default(), range: TextRange::default(),
ctx: ExprContext::Load, ctx: ExprContext::Load,
})), })),
slice: Box::new(tuple(elts, binding)), slice: Box::new(Expr::Tuple(ast::ExprTuple {
range: TextRange::default(),
elts: elts.to_vec(),
ctx: ExprContext::Load,
parenthesized: false,
})),
ctx: ExprContext::Load, ctx: ExprContext::Load,
range: TextRange::default(), range: TextRange::default(),
}) })