diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI016.py b/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI016.py index a4ff51f5de..75633e423b 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI016.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI016.py @@ -111,3 +111,12 @@ field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error # Test case for mixed union type field34: typing.Union[list[int], str] | typing.Union[bytes, list[int]] # Error + +field35: "int | str | int" # Error + + + +# Technically, this falls into the domain of the rule but it is an unlikely edge case, +# only works if you have from `__future__ import annotations` at the top of the file, +# and stringified annotations are discouraged in stub files. +field36: "int | str" | int # Ok \ No newline at end of file diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/duplicate_union_member.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/duplicate_union_member.rs index a41f839537..633af40eca 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/duplicate_union_member.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/duplicate_union_member.rs @@ -93,40 +93,38 @@ pub(crate) fn duplicate_union_member<'a>(checker: &mut Checker, expr: &'a Expr) return; } - if checker.settings.preview.is_enabled() { - // Mark [`Fix`] as unsafe when comments are in range. - let applicability = if checker.comment_ranges().intersects(expr.range()) { - Applicability::Unsafe - } else { - Applicability::Safe - }; + // Mark [`Fix`] as unsafe when comments are in range. + let applicability = if checker.comment_ranges().intersects(expr.range()) { + Applicability::Unsafe + } else { + Applicability::Safe + }; - // Generate the flattened fix once. - let fix = if let &[edit_expr] = unique_nodes.as_slice() { - // Generate a [`Fix`] for a single type expression, e.g. `int`. - Some(Fix::applicable_edit( - Edit::range_replacement(checker.generator().expr(edit_expr), expr.range()), + // Generate the flattened fix once. + let fix = if let &[edit_expr] = unique_nodes.as_slice() { + // Generate a [`Fix`] for a single type expression, e.g. `int`. + Some(Fix::applicable_edit( + Edit::range_replacement(checker.generator().expr(edit_expr), expr.range()), + applicability, + )) + } else { + match union_type { + // See redundant numeric union + UnionKind::PEP604 => Some(generate_pep604_fix( + checker, + unique_nodes, + expr, applicability, - )) - } else { - match union_type { - // See redundant numeric union - UnionKind::PEP604 => Some(generate_pep604_fix( - checker, - unique_nodes, - expr, - applicability, - )), - UnionKind::TypingUnion => { - generate_union_fix(checker, unique_nodes, expr, applicability).ok() - } + )), + UnionKind::TypingUnion => { + generate_union_fix(checker, unique_nodes, expr, applicability).ok() } - }; + } + }; - if let Some(fix) = fix { - for diagnostic in &mut diagnostics { - diagnostic.set_fix(fix.clone()); - } + if let Some(fix) = fix { + for diagnostic in &mut diagnostics { + diagnostic.set_fix(fix.clone()); } } diff --git a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI016_PYI016.py.snap b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI016_PYI016.py.snap index b95e7475b4..0310bb7b2c 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI016_PYI016.py.snap +++ b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI016_PYI016.py.snap @@ -1,7 +1,8 @@ --- source: crates/ruff_linter/src/rules/flake8_pyi/mod.rs +snapshot_kind: text --- -PYI016.py:7:15: PYI016 Duplicate union member `str` +PYI016.py:7:15: PYI016 [*] Duplicate union member `str` | 6 | # Should emit for duplicate field types. 7 | field2: str | str # PYI016: Duplicate union member `str` @@ -11,7 +12,17 @@ PYI016.py:7:15: PYI016 Duplicate union member `str` | = help: Remove duplicate union member `str` -PYI016.py:10:23: PYI016 Duplicate union member `int` +ℹ Safe fix +4 4 | field1: str +5 5 | +6 6 | # Should emit for duplicate field types. +7 |-field2: str | str # PYI016: Duplicate union member `str` + 7 |+field2: str # PYI016: Duplicate union member `str` +8 8 | +9 9 | # Should emit for union types in arguments. +10 10 | def func1(arg1: int | int): # PYI016: Duplicate union member `int` + +PYI016.py:10:23: PYI016 [*] Duplicate union member `int` | 9 | # Should emit for union types in arguments. 10 | def func1(arg1: int | int): # PYI016: Duplicate union member `int` @@ -20,7 +31,17 @@ PYI016.py:10:23: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:14:22: PYI016 Duplicate union member `str` +ℹ Safe fix +7 7 | field2: str | str # PYI016: Duplicate union member `str` +8 8 | +9 9 | # Should emit for union types in arguments. +10 |-def func1(arg1: int | int): # PYI016: Duplicate union member `int` + 10 |+def func1(arg1: int): # PYI016: Duplicate union member `int` +11 11 | print(arg1) +12 12 | +13 13 | # Should emit for unions in return types. + +PYI016.py:14:22: PYI016 [*] Duplicate union member `str` | 13 | # Should emit for unions in return types. 14 | def func2() -> str | str: # PYI016: Duplicate union member `str` @@ -29,7 +50,17 @@ PYI016.py:14:22: PYI016 Duplicate union member `str` | = help: Remove duplicate union member `str` -PYI016.py:18:15: PYI016 Duplicate union member `str` +ℹ Safe fix +11 11 | print(arg1) +12 12 | +13 13 | # Should emit for unions in return types. +14 |-def func2() -> str | str: # PYI016: Duplicate union member `str` + 14 |+def func2() -> str: # PYI016: Duplicate union member `str` +15 15 | return "my string" +16 16 | +17 17 | # Should emit in longer unions, even if not directly adjacent. + +PYI016.py:18:15: PYI016 [*] Duplicate union member `str` | 17 | # Should emit in longer unions, even if not directly adjacent. 18 | field3: str | str | int # PYI016: Duplicate union member `str` @@ -39,7 +70,17 @@ PYI016.py:18:15: PYI016 Duplicate union member `str` | = help: Remove duplicate union member `str` -PYI016.py:19:15: PYI016 Duplicate union member `int` +ℹ Safe fix +15 15 | return "my string" +16 16 | +17 17 | # Should emit in longer unions, even if not directly adjacent. +18 |-field3: str | str | int # PYI016: Duplicate union member `str` + 18 |+field3: str | int # PYI016: Duplicate union member `str` +19 19 | field4: int | int | str # PYI016: Duplicate union member `int` +20 20 | field5: str | int | str # PYI016: Duplicate union member `str` +21 21 | field6: int | bool | str | int # PYI016: Duplicate union member `int` + +PYI016.py:19:15: PYI016 [*] Duplicate union member `int` | 17 | # Should emit in longer unions, even if not directly adjacent. 18 | field3: str | str | int # PYI016: Duplicate union member `str` @@ -50,7 +91,17 @@ PYI016.py:19:15: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:20:21: PYI016 Duplicate union member `str` +ℹ Safe fix +16 16 | +17 17 | # Should emit in longer unions, even if not directly adjacent. +18 18 | field3: str | str | int # PYI016: Duplicate union member `str` +19 |-field4: int | int | str # PYI016: Duplicate union member `int` + 19 |+field4: int | str # PYI016: Duplicate union member `int` +20 20 | field5: str | int | str # PYI016: Duplicate union member `str` +21 21 | field6: int | bool | str | int # PYI016: Duplicate union member `int` +22 22 | + +PYI016.py:20:21: PYI016 [*] Duplicate union member `str` | 18 | field3: str | str | int # PYI016: Duplicate union member `str` 19 | field4: int | int | str # PYI016: Duplicate union member `int` @@ -60,7 +111,17 @@ PYI016.py:20:21: PYI016 Duplicate union member `str` | = help: Remove duplicate union member `str` -PYI016.py:21:28: PYI016 Duplicate union member `int` +ℹ Safe fix +17 17 | # Should emit in longer unions, even if not directly adjacent. +18 18 | field3: str | str | int # PYI016: Duplicate union member `str` +19 19 | field4: int | int | str # PYI016: Duplicate union member `int` +20 |-field5: str | int | str # PYI016: Duplicate union member `str` + 20 |+field5: str | int # PYI016: Duplicate union member `str` +21 21 | field6: int | bool | str | int # PYI016: Duplicate union member `int` +22 22 | +23 23 | # Shouldn't emit for non-type unions. + +PYI016.py:21:28: PYI016 [*] Duplicate union member `int` | 19 | field4: int | int | str # PYI016: Duplicate union member `int` 20 | field5: str | int | str # PYI016: Duplicate union member `str` @@ -71,7 +132,17 @@ PYI016.py:21:28: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:27:22: PYI016 Duplicate union member `int` +ℹ Safe fix +18 18 | field3: str | str | int # PYI016: Duplicate union member `str` +19 19 | field4: int | int | str # PYI016: Duplicate union member `int` +20 20 | field5: str | int | str # PYI016: Duplicate union member `str` +21 |-field6: int | bool | str | int # PYI016: Duplicate union member `int` + 21 |+field6: int | bool | str # PYI016: Duplicate union member `int` +22 22 | +23 23 | # Shouldn't emit for non-type unions. +24 24 | field7 = str | str + +PYI016.py:27:22: PYI016 [*] Duplicate union member `int` | 26 | # Should emit for strangely-bracketed unions. 27 | field8: int | (str | int) # PYI016: Duplicate union member `int` @@ -81,7 +152,17 @@ PYI016.py:27:22: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:30:16: PYI016 Duplicate union member `int` +ℹ Safe fix +24 24 | field7 = str | str +25 25 | +26 26 | # Should emit for strangely-bracketed unions. +27 |-field8: int | (str | int) # PYI016: Duplicate union member `int` + 27 |+field8: int | str # PYI016: Duplicate union member `int` +28 28 | +29 29 | # Should handle user brackets when fixing. +30 30 | field9: int | (int | str) # PYI016: Duplicate union member `int` + +PYI016.py:30:16: PYI016 [*] Duplicate union member `int` | 29 | # Should handle user brackets when fixing. 30 | field9: int | (int | str) # PYI016: Duplicate union member `int` @@ -90,7 +171,17 @@ PYI016.py:30:16: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:31:24: PYI016 Duplicate union member `str` +ℹ Safe fix +27 27 | field8: int | (str | int) # PYI016: Duplicate union member `int` +28 28 | +29 29 | # Should handle user brackets when fixing. +30 |-field9: int | (int | str) # PYI016: Duplicate union member `int` + 30 |+field9: int | str # PYI016: Duplicate union member `int` +31 31 | field10: (str | int) | str # PYI016: Duplicate union member `str` +32 32 | +33 33 | # Should emit for nested unions. + +PYI016.py:31:24: PYI016 [*] Duplicate union member `str` | 29 | # Should handle user brackets when fixing. 30 | field9: int | (int | str) # PYI016: Duplicate union member `int` @@ -101,7 +192,17 @@ PYI016.py:31:24: PYI016 Duplicate union member `str` | = help: Remove duplicate union member `str` -PYI016.py:34:21: PYI016 Duplicate union member `int` +ℹ Safe fix +28 28 | +29 29 | # Should handle user brackets when fixing. +30 30 | field9: int | (int | str) # PYI016: Duplicate union member `int` +31 |-field10: (str | int) | str # PYI016: Duplicate union member `str` + 31 |+field10: str | int # PYI016: Duplicate union member `str` +32 32 | +33 33 | # Should emit for nested unions. +34 34 | field11: dict[int | int, str] + +PYI016.py:34:21: PYI016 [*] Duplicate union member `int` | 33 | # Should emit for nested unions. 34 | field11: dict[int | int, str] @@ -111,7 +212,17 @@ PYI016.py:34:21: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:37:16: PYI016 Duplicate union member `int` +ℹ Safe fix +31 31 | field10: (str | int) | str # PYI016: Duplicate union member `str` +32 32 | +33 33 | # Should emit for nested unions. +34 |-field11: dict[int | int, str] + 34 |+field11: dict[int, str] +35 35 | +36 36 | # Should emit for unions with more than two cases +37 37 | field12: int | int | int # Error + +PYI016.py:37:16: PYI016 [*] Duplicate union member `int` | 36 | # Should emit for unions with more than two cases 37 | field12: int | int | int # Error @@ -120,7 +231,17 @@ PYI016.py:37:16: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:37:22: PYI016 Duplicate union member `int` +ℹ Safe fix +34 34 | field11: dict[int | int, str] +35 35 | +36 36 | # Should emit for unions with more than two cases +37 |-field12: int | int | int # Error + 37 |+field12: int # Error +38 38 | field13: int | int | int | int # Error +39 39 | +40 40 | # Should emit for unions with more than two cases, even if not directly adjacent + +PYI016.py:37:22: PYI016 [*] Duplicate union member `int` | 36 | # Should emit for unions with more than two cases 37 | field12: int | int | int # Error @@ -129,7 +250,17 @@ PYI016.py:37:22: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:38:16: PYI016 Duplicate union member `int` +ℹ Safe fix +34 34 | field11: dict[int | int, str] +35 35 | +36 36 | # Should emit for unions with more than two cases +37 |-field12: int | int | int # Error + 37 |+field12: int # Error +38 38 | field13: int | int | int | int # Error +39 39 | +40 40 | # Should emit for unions with more than two cases, even if not directly adjacent + +PYI016.py:38:16: PYI016 [*] Duplicate union member `int` | 36 | # Should emit for unions with more than two cases 37 | field12: int | int | int # Error @@ -140,7 +271,17 @@ PYI016.py:38:16: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:38:22: PYI016 Duplicate union member `int` +ℹ Safe fix +35 35 | +36 36 | # Should emit for unions with more than two cases +37 37 | field12: int | int | int # Error +38 |-field13: int | int | int | int # Error + 38 |+field13: int # Error +39 39 | +40 40 | # Should emit for unions with more than two cases, even if not directly adjacent +41 41 | field14: int | int | str | int # Error + +PYI016.py:38:22: PYI016 [*] Duplicate union member `int` | 36 | # Should emit for unions with more than two cases 37 | field12: int | int | int # Error @@ -151,7 +292,17 @@ PYI016.py:38:22: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:38:28: PYI016 Duplicate union member `int` +ℹ Safe fix +35 35 | +36 36 | # Should emit for unions with more than two cases +37 37 | field12: int | int | int # Error +38 |-field13: int | int | int | int # Error + 38 |+field13: int # Error +39 39 | +40 40 | # Should emit for unions with more than two cases, even if not directly adjacent +41 41 | field14: int | int | str | int # Error + +PYI016.py:38:28: PYI016 [*] Duplicate union member `int` | 36 | # Should emit for unions with more than two cases 37 | field12: int | int | int # Error @@ -162,7 +313,17 @@ PYI016.py:38:28: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:41:16: PYI016 Duplicate union member `int` +ℹ Safe fix +35 35 | +36 36 | # Should emit for unions with more than two cases +37 37 | field12: int | int | int # Error +38 |-field13: int | int | int | int # Error + 38 |+field13: int # Error +39 39 | +40 40 | # Should emit for unions with more than two cases, even if not directly adjacent +41 41 | field14: int | int | str | int # Error + +PYI016.py:41:16: PYI016 [*] Duplicate union member `int` | 40 | # Should emit for unions with more than two cases, even if not directly adjacent 41 | field14: int | int | str | int # Error @@ -172,7 +333,17 @@ PYI016.py:41:16: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:41:28: PYI016 Duplicate union member `int` +ℹ Safe fix +38 38 | field13: int | int | int | int # Error +39 39 | +40 40 | # Should emit for unions with more than two cases, even if not directly adjacent +41 |-field14: int | int | str | int # Error + 41 |+field14: int | str # Error +42 42 | +43 43 | # Should emit for duplicate literal types; also covered by PYI030 +44 44 | field15: typing.Literal[1] | typing.Literal[1] # Error + +PYI016.py:41:28: PYI016 [*] Duplicate union member `int` | 40 | # Should emit for unions with more than two cases, even if not directly adjacent 41 | field14: int | int | str | int # Error @@ -182,7 +353,17 @@ PYI016.py:41:28: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:44:30: PYI016 Duplicate union member `typing.Literal[1]` +ℹ Safe fix +38 38 | field13: int | int | int | int # Error +39 39 | +40 40 | # Should emit for unions with more than two cases, even if not directly adjacent +41 |-field14: int | int | str | int # Error + 41 |+field14: int | str # Error +42 42 | +43 43 | # Should emit for duplicate literal types; also covered by PYI030 +44 44 | field15: typing.Literal[1] | typing.Literal[1] # Error + +PYI016.py:44:30: PYI016 [*] Duplicate union member `typing.Literal[1]` | 43 | # Should emit for duplicate literal types; also covered by PYI030 44 | field15: typing.Literal[1] | typing.Literal[1] # Error @@ -192,7 +373,17 @@ PYI016.py:44:30: PYI016 Duplicate union member `typing.Literal[1]` | = help: Remove duplicate union member `typing.Literal[1]` -PYI016.py:57:5: PYI016 Duplicate union member `set[int]` +ℹ Safe fix +41 41 | field14: int | int | str | int # Error +42 42 | +43 43 | # Should emit for duplicate literal types; also covered by PYI030 +44 |-field15: typing.Literal[1] | typing.Literal[1] # Error + 44 |+field15: typing.Literal[1] # Error +45 45 | +46 46 | # Shouldn't emit if in new parent type +47 47 | field16: int | dict[int, str] # OK + +PYI016.py:57:5: PYI016 [*] Duplicate union member `set[int]` | 55 | int # foo 56 | ], @@ -205,7 +396,24 @@ PYI016.py:57:5: PYI016 Duplicate union member `set[int]` | = help: Remove duplicate union member `set[int]` -PYI016.py:63:28: PYI016 Duplicate union member `int` +ℹ Unsafe fix +50 50 | field17: dict[int, int] # OK +51 51 | +52 52 | # Should emit in cases with newlines +53 |-field18: typing.Union[ +54 |- set[ +55 |- int # foo +56 |- ], +57 |- set[ +58 |- int # bar +59 |- ], +60 |-] # Error, newline and comment will not be emitted in message + 53 |+field18: set[int] # Error, newline and comment will not be emitted in message +61 54 | +62 55 | # Should emit in cases with `typing.Union` instead of `|` +63 56 | field19: typing.Union[int, int] # Error + +PYI016.py:63:28: PYI016 [*] Duplicate union member `int` | 62 | # Should emit in cases with `typing.Union` instead of `|` 63 | field19: typing.Union[int, int] # Error @@ -215,7 +423,17 @@ PYI016.py:63:28: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:66:41: PYI016 Duplicate union member `int` +ℹ Safe fix +60 60 | ] # Error, newline and comment will not be emitted in message +61 61 | +62 62 | # Should emit in cases with `typing.Union` instead of `|` +63 |-field19: typing.Union[int, int] # Error + 63 |+field19: int # Error +64 64 | +65 65 | # Should emit in cases with nested `typing.Union` +66 66 | field20: typing.Union[int, typing.Union[int, str]] # Error + +PYI016.py:66:41: PYI016 [*] Duplicate union member `int` | 65 | # Should emit in cases with nested `typing.Union` 66 | field20: typing.Union[int, typing.Union[int, str]] # Error @@ -225,7 +443,17 @@ PYI016.py:66:41: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:69:28: PYI016 Duplicate union member `int` +ℹ Safe fix +63 63 | field19: typing.Union[int, int] # Error +64 64 | +65 65 | # Should emit in cases with nested `typing.Union` +66 |-field20: typing.Union[int, typing.Union[int, str]] # Error + 66 |+field20: typing.Union[int, str] # Error +67 67 | +68 68 | # Should emit in cases with mixed `typing.Union` and `|` +69 69 | field21: typing.Union[int, int | str] # Error + +PYI016.py:69:28: PYI016 [*] Duplicate union member `int` | 68 | # Should emit in cases with mixed `typing.Union` and `|` 69 | field21: typing.Union[int, int | str] # Error @@ -235,7 +463,17 @@ PYI016.py:69:28: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:72:41: PYI016 Duplicate union member `int` +ℹ Safe fix +66 66 | field20: typing.Union[int, typing.Union[int, str]] # Error +67 67 | +68 68 | # Should emit in cases with mixed `typing.Union` and `|` +69 |-field21: typing.Union[int, int | str] # Error + 69 |+field21: int | str # Error +70 70 | +71 71 | # Should emit only once in cases with multiple nested `typing.Union` +72 72 | field22: typing.Union[int, typing.Union[int, typing.Union[int, int]]] # Error + +PYI016.py:72:41: PYI016 [*] Duplicate union member `int` | 71 | # Should emit only once in cases with multiple nested `typing.Union` 72 | field22: typing.Union[int, typing.Union[int, typing.Union[int, int]]] # Error @@ -245,7 +483,17 @@ PYI016.py:72:41: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:72:59: PYI016 Duplicate union member `int` +ℹ Safe fix +69 69 | field21: typing.Union[int, int | str] # Error +70 70 | +71 71 | # Should emit only once in cases with multiple nested `typing.Union` +72 |-field22: typing.Union[int, typing.Union[int, typing.Union[int, int]]] # Error + 72 |+field22: int # Error +73 73 | +74 74 | # Should emit in cases with newlines +75 75 | field23: set[ # foo + +PYI016.py:72:59: PYI016 [*] Duplicate union member `int` | 71 | # Should emit only once in cases with multiple nested `typing.Union` 72 | field22: typing.Union[int, typing.Union[int, typing.Union[int, int]]] # Error @@ -255,7 +503,17 @@ PYI016.py:72:59: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:72:64: PYI016 Duplicate union member `int` +ℹ Safe fix +69 69 | field21: typing.Union[int, int | str] # Error +70 70 | +71 71 | # Should emit only once in cases with multiple nested `typing.Union` +72 |-field22: typing.Union[int, typing.Union[int, typing.Union[int, int]]] # Error + 72 |+field22: int # Error +73 73 | +74 74 | # Should emit in cases with newlines +75 75 | field23: set[ # foo + +PYI016.py:72:64: PYI016 [*] Duplicate union member `int` | 71 | # Should emit only once in cases with multiple nested `typing.Union` 72 | field22: typing.Union[int, typing.Union[int, typing.Union[int, int]]] # Error @@ -265,7 +523,17 @@ PYI016.py:72:64: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:76:12: PYI016 Duplicate union member `set[int]` +ℹ Safe fix +69 69 | field21: typing.Union[int, int | str] # Error +70 70 | +71 71 | # Should emit only once in cases with multiple nested `typing.Union` +72 |-field22: typing.Union[int, typing.Union[int, typing.Union[int, int]]] # Error + 72 |+field22: int # Error +73 73 | +74 74 | # Should emit in cases with newlines +75 75 | field23: set[ # foo + +PYI016.py:76:12: PYI016 [*] Duplicate union member `set[int]` | 74 | # Should emit in cases with newlines 75 | field23: set[ # foo @@ -276,7 +544,18 @@ PYI016.py:76:12: PYI016 Duplicate union member `set[int]` | = help: Remove duplicate union member `set[int]` -PYI016.py:81:41: PYI016 Duplicate union member `int` +ℹ Unsafe fix +72 72 | field22: typing.Union[int, typing.Union[int, typing.Union[int, int]]] # Error +73 73 | +74 74 | # Should emit in cases with newlines +75 |-field23: set[ # foo +76 |- int] | set[int] + 75 |+field23: set[int] +77 76 | +78 77 | # Should emit twice (once for each `int` in the nested union, both of which are +79 78 | # duplicates of the outer `int`), but not three times (which would indicate that + +PYI016.py:81:41: PYI016 [*] Duplicate union member `int` | 79 | # duplicates of the outer `int`), but not three times (which would indicate that 80 | # we incorrectly re-checked the nested union). @@ -287,7 +566,17 @@ PYI016.py:81:41: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:81:46: PYI016 Duplicate union member `int` +ℹ Safe fix +78 78 | # Should emit twice (once for each `int` in the nested union, both of which are +79 79 | # duplicates of the outer `int`), but not three times (which would indicate that +80 80 | # we incorrectly re-checked the nested union). +81 |-field24: typing.Union[int, typing.Union[int, int]] # PYI016: Duplicate union member `int` + 81 |+field24: int # PYI016: Duplicate union member `int` +82 82 | +83 83 | # Should emit twice (once for each `int` in the nested union, both of which are +84 84 | # duplicates of the outer `int`), but not three times (which would indicate that + +PYI016.py:81:46: PYI016 [*] Duplicate union member `int` | 79 | # duplicates of the outer `int`), but not three times (which would indicate that 80 | # we incorrectly re-checked the nested union). @@ -298,7 +587,17 @@ PYI016.py:81:46: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:86:28: PYI016 Duplicate union member `int` +ℹ Safe fix +78 78 | # Should emit twice (once for each `int` in the nested union, both of which are +79 79 | # duplicates of the outer `int`), but not three times (which would indicate that +80 80 | # we incorrectly re-checked the nested union). +81 |-field24: typing.Union[int, typing.Union[int, int]] # PYI016: Duplicate union member `int` + 81 |+field24: int # PYI016: Duplicate union member `int` +82 82 | +83 83 | # Should emit twice (once for each `int` in the nested union, both of which are +84 84 | # duplicates of the outer `int`), but not three times (which would indicate that + +PYI016.py:86:28: PYI016 [*] Duplicate union member `int` | 84 | # duplicates of the outer `int`), but not three times (which would indicate that 85 | # we incorrectly re-checked the nested union). @@ -309,7 +608,17 @@ PYI016.py:86:28: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:86:34: PYI016 Duplicate union member `int` +ℹ Safe fix +83 83 | # Should emit twice (once for each `int` in the nested union, both of which are +84 84 | # duplicates of the outer `int`), but not three times (which would indicate that +85 85 | # we incorrectly re-checked the nested union). +86 |-field25: typing.Union[int, int | int] # PYI016: Duplicate union member `int` + 86 |+field25: int # PYI016: Duplicate union member `int` +87 87 | +88 88 | # Should emit in cases with nested `typing.Union` +89 89 | field26: typing.Union[typing.Union[int, int]] # PYI016: Duplicate union member `int` + +PYI016.py:86:34: PYI016 [*] Duplicate union member `int` | 84 | # duplicates of the outer `int`), but not three times (which would indicate that 85 | # we incorrectly re-checked the nested union). @@ -320,7 +629,17 @@ PYI016.py:86:34: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:89:41: PYI016 Duplicate union member `int` +ℹ Safe fix +83 83 | # Should emit twice (once for each `int` in the nested union, both of which are +84 84 | # duplicates of the outer `int`), but not three times (which would indicate that +85 85 | # we incorrectly re-checked the nested union). +86 |-field25: typing.Union[int, int | int] # PYI016: Duplicate union member `int` + 86 |+field25: int # PYI016: Duplicate union member `int` +87 87 | +88 88 | # Should emit in cases with nested `typing.Union` +89 89 | field26: typing.Union[typing.Union[int, int]] # PYI016: Duplicate union member `int` + +PYI016.py:89:41: PYI016 [*] Duplicate union member `int` | 88 | # Should emit in cases with nested `typing.Union` 89 | field26: typing.Union[typing.Union[int, int]] # PYI016: Duplicate union member `int` @@ -330,7 +649,17 @@ PYI016.py:89:41: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:92:54: PYI016 Duplicate union member `int` +ℹ Safe fix +86 86 | field25: typing.Union[int, int | int] # PYI016: Duplicate union member `int` +87 87 | +88 88 | # Should emit in cases with nested `typing.Union` +89 |-field26: typing.Union[typing.Union[int, int]] # PYI016: Duplicate union member `int` + 89 |+field26: int # PYI016: Duplicate union member `int` +90 90 | +91 91 | # Should emit in cases with nested `typing.Union` +92 92 | field27: typing.Union[typing.Union[typing.Union[int, int]]] # PYI016: Duplicate union member `int` + +PYI016.py:92:54: PYI016 [*] Duplicate union member `int` | 91 | # Should emit in cases with nested `typing.Union` 92 | field27: typing.Union[typing.Union[typing.Union[int, int]]] # PYI016: Duplicate union member `int` @@ -340,7 +669,17 @@ PYI016.py:92:54: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:95:29: PYI016 Duplicate union member `int` +ℹ Safe fix +89 89 | field26: typing.Union[typing.Union[int, int]] # PYI016: Duplicate union member `int` +90 90 | +91 91 | # Should emit in cases with nested `typing.Union` +92 |-field27: typing.Union[typing.Union[typing.Union[int, int]]] # PYI016: Duplicate union member `int` + 92 |+field27: int # PYI016: Duplicate union member `int` +93 93 | +94 94 | # Should emit in cases with mixed `typing.Union` and `|` +95 95 | field28: typing.Union[int | int] # Error + +PYI016.py:95:29: PYI016 [*] Duplicate union member `int` | 94 | # Should emit in cases with mixed `typing.Union` and `|` 95 | field28: typing.Union[int | int] # Error @@ -350,7 +689,17 @@ PYI016.py:95:29: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:98:54: PYI016 Duplicate union member `int` +ℹ Safe fix +92 92 | field27: typing.Union[typing.Union[typing.Union[int, int]]] # PYI016: Duplicate union member `int` +93 93 | +94 94 | # Should emit in cases with mixed `typing.Union` and `|` +95 |-field28: typing.Union[int | int] # Error + 95 |+field28: int # Error +96 96 | +97 97 | # Should emit twice in cases with multiple nested `typing.Union` +98 98 | field29: typing.Union[int, typing.Union[typing.Union[int, int]]] # Error + +PYI016.py:98:54: PYI016 [*] Duplicate union member `int` | 97 | # Should emit twice in cases with multiple nested `typing.Union` 98 | field29: typing.Union[int, typing.Union[typing.Union[int, int]]] # Error @@ -360,7 +709,17 @@ PYI016.py:98:54: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:98:59: PYI016 Duplicate union member `int` +ℹ Safe fix +95 95 | field28: typing.Union[int | int] # Error +96 96 | +97 97 | # Should emit twice in cases with multiple nested `typing.Union` +98 |-field29: typing.Union[int, typing.Union[typing.Union[int, int]]] # Error + 98 |+field29: int # Error +99 99 | +100 100 | # Should emit once in cases with multiple nested `typing.Union` +101 101 | field30: typing.Union[int, typing.Union[typing.Union[int, str]]] # Error + +PYI016.py:98:59: PYI016 [*] Duplicate union member `int` | 97 | # Should emit twice in cases with multiple nested `typing.Union` 98 | field29: typing.Union[int, typing.Union[typing.Union[int, int]]] # Error @@ -370,7 +729,17 @@ PYI016.py:98:59: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:101:54: PYI016 Duplicate union member `int` +ℹ Safe fix +95 95 | field28: typing.Union[int | int] # Error +96 96 | +97 97 | # Should emit twice in cases with multiple nested `typing.Union` +98 |-field29: typing.Union[int, typing.Union[typing.Union[int, int]]] # Error + 98 |+field29: int # Error +99 99 | +100 100 | # Should emit once in cases with multiple nested `typing.Union` +101 101 | field30: typing.Union[int, typing.Union[typing.Union[int, str]]] # Error + +PYI016.py:101:54: PYI016 [*] Duplicate union member `int` | 100 | # Should emit once in cases with multiple nested `typing.Union` 101 | field30: typing.Union[int, typing.Union[typing.Union[int, str]]] # Error @@ -380,7 +749,17 @@ PYI016.py:101:54: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:104:49: PYI016 Duplicate union member `int` +ℹ Safe fix +98 98 | field29: typing.Union[int, typing.Union[typing.Union[int, int]]] # Error +99 99 | +100 100 | # Should emit once in cases with multiple nested `typing.Union` +101 |-field30: typing.Union[int, typing.Union[typing.Union[int, str]]] # Error + 101 |+field30: typing.Union[int, str] # Error +102 102 | +103 103 | # Should emit once, and fix to `typing.Union[float, int]` +104 104 | field31: typing.Union[float, typing.Union[int | int]] # Error + +PYI016.py:104:49: PYI016 [*] Duplicate union member `int` | 103 | # Should emit once, and fix to `typing.Union[float, int]` 104 | field31: typing.Union[float, typing.Union[int | int]] # Error @@ -390,7 +769,17 @@ PYI016.py:104:49: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:107:49: PYI016 Duplicate union member `int` +ℹ Safe fix +101 101 | field30: typing.Union[int, typing.Union[typing.Union[int, str]]] # Error +102 102 | +103 103 | # Should emit once, and fix to `typing.Union[float, int]` +104 |-field31: typing.Union[float, typing.Union[int | int]] # Error + 104 |+field31: float | int # Error +105 105 | +106 106 | # Should emit once, and fix to `typing.Union[float, int]` +107 107 | field32: typing.Union[float, typing.Union[int | int | int]] # Error + +PYI016.py:107:49: PYI016 [*] Duplicate union member `int` | 106 | # Should emit once, and fix to `typing.Union[float, int]` 107 | field32: typing.Union[float, typing.Union[int | int | int]] # Error @@ -400,7 +789,17 @@ PYI016.py:107:49: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:107:55: PYI016 Duplicate union member `int` +ℹ Safe fix +104 104 | field31: typing.Union[float, typing.Union[int | int]] # Error +105 105 | +106 106 | # Should emit once, and fix to `typing.Union[float, int]` +107 |-field32: typing.Union[float, typing.Union[int | int | int]] # Error + 107 |+field32: float | int # Error +108 108 | +109 109 | # Test case for mixed union type fix +110 110 | field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error + +PYI016.py:107:55: PYI016 [*] Duplicate union member `int` | 106 | # Should emit once, and fix to `typing.Union[float, int]` 107 | field32: typing.Union[float, typing.Union[int | int | int]] # Error @@ -410,7 +809,17 @@ PYI016.py:107:55: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:110:42: PYI016 Duplicate union member `int` +ℹ Safe fix +104 104 | field31: typing.Union[float, typing.Union[int | int]] # Error +105 105 | +106 106 | # Should emit once, and fix to `typing.Union[float, int]` +107 |-field32: typing.Union[float, typing.Union[int | int | int]] # Error + 107 |+field32: float | int # Error +108 108 | +109 109 | # Test case for mixed union type fix +110 110 | field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error + +PYI016.py:110:42: PYI016 [*] Duplicate union member `int` | 109 | # Test case for mixed union type fix 110 | field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error @@ -420,7 +829,17 @@ PYI016.py:110:42: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:110:62: PYI016 Duplicate union member `int` +ℹ Safe fix +107 107 | field32: typing.Union[float, typing.Union[int | int | int]] # Error +108 108 | +109 109 | # Test case for mixed union type fix +110 |-field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error + 110 |+field33: int # Error +111 111 | +112 112 | # Test case for mixed union type +113 113 | field34: typing.Union[list[int], str] | typing.Union[bytes, list[int]] # Error + +PYI016.py:110:62: PYI016 [*] Duplicate union member `int` | 109 | # Test case for mixed union type fix 110 | field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error @@ -430,7 +849,17 @@ PYI016.py:110:62: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:110:68: PYI016 Duplicate union member `int` +ℹ Safe fix +107 107 | field32: typing.Union[float, typing.Union[int | int | int]] # Error +108 108 | +109 109 | # Test case for mixed union type fix +110 |-field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error + 110 |+field33: int # Error +111 111 | +112 112 | # Test case for mixed union type +113 113 | field34: typing.Union[list[int], str] | typing.Union[bytes, list[int]] # Error + +PYI016.py:110:68: PYI016 [*] Duplicate union member `int` | 109 | # Test case for mixed union type fix 110 | field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error @@ -440,10 +869,51 @@ PYI016.py:110:68: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.py:113:61: PYI016 Duplicate union member `list[int]` +ℹ Safe fix +107 107 | field32: typing.Union[float, typing.Union[int | int | int]] # Error +108 108 | +109 109 | # Test case for mixed union type fix +110 |-field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error + 110 |+field33: int # Error +111 111 | +112 112 | # Test case for mixed union type +113 113 | field34: typing.Union[list[int], str] | typing.Union[bytes, list[int]] # Error + +PYI016.py:113:61: PYI016 [*] Duplicate union member `list[int]` | 112 | # Test case for mixed union type 113 | field34: typing.Union[list[int], str] | typing.Union[bytes, list[int]] # Error | ^^^^^^^^^ PYI016 +114 | +115 | field35: "int | str | int" # Error | = help: Remove duplicate union member `list[int]` + +ℹ Safe fix +110 110 | field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error +111 111 | +112 112 | # Test case for mixed union type +113 |-field34: typing.Union[list[int], str] | typing.Union[bytes, list[int]] # Error + 113 |+field34: typing.Union[list[int], str, bytes] # Error +114 114 | +115 115 | field35: "int | str | int" # Error +116 116 | + +PYI016.py:115:23: PYI016 [*] Duplicate union member `int` + | +113 | field34: typing.Union[list[int], str] | typing.Union[bytes, list[int]] # Error +114 | +115 | field35: "int | str | int" # Error + | ^^^ PYI016 + | + = help: Remove duplicate union member `int` + +ℹ Safe fix +112 112 | # Test case for mixed union type +113 113 | field34: typing.Union[list[int], str] | typing.Union[bytes, list[int]] # Error +114 114 | +115 |-field35: "int | str | int" # Error + 115 |+field35: "int | str" # Error +116 116 | +117 117 | +118 118 | diff --git a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI016_PYI016.pyi.snap b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI016_PYI016.pyi.snap index b49b909b04..1cdbef03b7 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI016_PYI016.pyi.snap +++ b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI016_PYI016.pyi.snap @@ -1,7 +1,8 @@ --- source: crates/ruff_linter/src/rules/flake8_pyi/mod.rs +snapshot_kind: text --- -PYI016.pyi:7:15: PYI016 Duplicate union member `str` +PYI016.pyi:7:15: PYI016 [*] Duplicate union member `str` | 6 | # Should emit for duplicate field types. 7 | field2: str | str # PYI016: Duplicate union member `str` @@ -11,7 +12,17 @@ PYI016.pyi:7:15: PYI016 Duplicate union member `str` | = help: Remove duplicate union member `str` -PYI016.pyi:10:23: PYI016 Duplicate union member `int` +ℹ Safe fix +4 4 | field1: str +5 5 | +6 6 | # Should emit for duplicate field types. +7 |-field2: str | str # PYI016: Duplicate union member `str` + 7 |+field2: str # PYI016: Duplicate union member `str` +8 8 | +9 9 | # Should emit for union types in arguments. +10 10 | def func1(arg1: int | int): # PYI016: Duplicate union member `int` + +PYI016.pyi:10:23: PYI016 [*] Duplicate union member `int` | 9 | # Should emit for union types in arguments. 10 | def func1(arg1: int | int): # PYI016: Duplicate union member `int` @@ -20,7 +31,17 @@ PYI016.pyi:10:23: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:14:22: PYI016 Duplicate union member `str` +ℹ Safe fix +7 7 | field2: str | str # PYI016: Duplicate union member `str` +8 8 | +9 9 | # Should emit for union types in arguments. +10 |-def func1(arg1: int | int): # PYI016: Duplicate union member `int` + 10 |+def func1(arg1: int): # PYI016: Duplicate union member `int` +11 11 | print(arg1) +12 12 | +13 13 | # Should emit for unions in return types. + +PYI016.pyi:14:22: PYI016 [*] Duplicate union member `str` | 13 | # Should emit for unions in return types. 14 | def func2() -> str | str: # PYI016: Duplicate union member `str` @@ -29,7 +50,17 @@ PYI016.pyi:14:22: PYI016 Duplicate union member `str` | = help: Remove duplicate union member `str` -PYI016.pyi:18:15: PYI016 Duplicate union member `str` +ℹ Safe fix +11 11 | print(arg1) +12 12 | +13 13 | # Should emit for unions in return types. +14 |-def func2() -> str | str: # PYI016: Duplicate union member `str` + 14 |+def func2() -> str: # PYI016: Duplicate union member `str` +15 15 | return "my string" +16 16 | +17 17 | # Should emit in longer unions, even if not directly adjacent. + +PYI016.pyi:18:15: PYI016 [*] Duplicate union member `str` | 17 | # Should emit in longer unions, even if not directly adjacent. 18 | field3: str | str | int # PYI016: Duplicate union member `str` @@ -39,7 +70,17 @@ PYI016.pyi:18:15: PYI016 Duplicate union member `str` | = help: Remove duplicate union member `str` -PYI016.pyi:19:15: PYI016 Duplicate union member `int` +ℹ Safe fix +15 15 | return "my string" +16 16 | +17 17 | # Should emit in longer unions, even if not directly adjacent. +18 |-field3: str | str | int # PYI016: Duplicate union member `str` + 18 |+field3: str | int # PYI016: Duplicate union member `str` +19 19 | field4: int | int | str # PYI016: Duplicate union member `int` +20 20 | field5: str | int | str # PYI016: Duplicate union member `str` +21 21 | field6: int | bool | str | int # PYI016: Duplicate union member `int` + +PYI016.pyi:19:15: PYI016 [*] Duplicate union member `int` | 17 | # Should emit in longer unions, even if not directly adjacent. 18 | field3: str | str | int # PYI016: Duplicate union member `str` @@ -50,7 +91,17 @@ PYI016.pyi:19:15: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:20:21: PYI016 Duplicate union member `str` +ℹ Safe fix +16 16 | +17 17 | # Should emit in longer unions, even if not directly adjacent. +18 18 | field3: str | str | int # PYI016: Duplicate union member `str` +19 |-field4: int | int | str # PYI016: Duplicate union member `int` + 19 |+field4: int | str # PYI016: Duplicate union member `int` +20 20 | field5: str | int | str # PYI016: Duplicate union member `str` +21 21 | field6: int | bool | str | int # PYI016: Duplicate union member `int` +22 22 | + +PYI016.pyi:20:21: PYI016 [*] Duplicate union member `str` | 18 | field3: str | str | int # PYI016: Duplicate union member `str` 19 | field4: int | int | str # PYI016: Duplicate union member `int` @@ -60,7 +111,17 @@ PYI016.pyi:20:21: PYI016 Duplicate union member `str` | = help: Remove duplicate union member `str` -PYI016.pyi:21:28: PYI016 Duplicate union member `int` +ℹ Safe fix +17 17 | # Should emit in longer unions, even if not directly adjacent. +18 18 | field3: str | str | int # PYI016: Duplicate union member `str` +19 19 | field4: int | int | str # PYI016: Duplicate union member `int` +20 |-field5: str | int | str # PYI016: Duplicate union member `str` + 20 |+field5: str | int # PYI016: Duplicate union member `str` +21 21 | field6: int | bool | str | int # PYI016: Duplicate union member `int` +22 22 | +23 23 | # Shouldn't emit for non-type unions. + +PYI016.pyi:21:28: PYI016 [*] Duplicate union member `int` | 19 | field4: int | int | str # PYI016: Duplicate union member `int` 20 | field5: str | int | str # PYI016: Duplicate union member `str` @@ -71,7 +132,17 @@ PYI016.pyi:21:28: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:27:22: PYI016 Duplicate union member `int` +ℹ Safe fix +18 18 | field3: str | str | int # PYI016: Duplicate union member `str` +19 19 | field4: int | int | str # PYI016: Duplicate union member `int` +20 20 | field5: str | int | str # PYI016: Duplicate union member `str` +21 |-field6: int | bool | str | int # PYI016: Duplicate union member `int` + 21 |+field6: int | bool | str # PYI016: Duplicate union member `int` +22 22 | +23 23 | # Shouldn't emit for non-type unions. +24 24 | field7 = str | str + +PYI016.pyi:27:22: PYI016 [*] Duplicate union member `int` | 26 | # Should emit for strangely-bracketed unions. 27 | field8: int | (str | int) # PYI016: Duplicate union member `int` @@ -81,7 +152,17 @@ PYI016.pyi:27:22: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:30:16: PYI016 Duplicate union member `int` +ℹ Safe fix +24 24 | field7 = str | str +25 25 | +26 26 | # Should emit for strangely-bracketed unions. +27 |-field8: int | (str | int) # PYI016: Duplicate union member `int` + 27 |+field8: int | str # PYI016: Duplicate union member `int` +28 28 | +29 29 | # Should handle user brackets when fixing. +30 30 | field9: int | (int | str) # PYI016: Duplicate union member `int` + +PYI016.pyi:30:16: PYI016 [*] Duplicate union member `int` | 29 | # Should handle user brackets when fixing. 30 | field9: int | (int | str) # PYI016: Duplicate union member `int` @@ -90,7 +171,17 @@ PYI016.pyi:30:16: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:31:24: PYI016 Duplicate union member `str` +ℹ Safe fix +27 27 | field8: int | (str | int) # PYI016: Duplicate union member `int` +28 28 | +29 29 | # Should handle user brackets when fixing. +30 |-field9: int | (int | str) # PYI016: Duplicate union member `int` + 30 |+field9: int | str # PYI016: Duplicate union member `int` +31 31 | field10: (str | int) | str # PYI016: Duplicate union member `str` +32 32 | +33 33 | # Should emit for nested unions. + +PYI016.pyi:31:24: PYI016 [*] Duplicate union member `str` | 29 | # Should handle user brackets when fixing. 30 | field9: int | (int | str) # PYI016: Duplicate union member `int` @@ -101,7 +192,17 @@ PYI016.pyi:31:24: PYI016 Duplicate union member `str` | = help: Remove duplicate union member `str` -PYI016.pyi:34:21: PYI016 Duplicate union member `int` +ℹ Safe fix +28 28 | +29 29 | # Should handle user brackets when fixing. +30 30 | field9: int | (int | str) # PYI016: Duplicate union member `int` +31 |-field10: (str | int) | str # PYI016: Duplicate union member `str` + 31 |+field10: str | int # PYI016: Duplicate union member `str` +32 32 | +33 33 | # Should emit for nested unions. +34 34 | field11: dict[int | int, str] + +PYI016.pyi:34:21: PYI016 [*] Duplicate union member `int` | 33 | # Should emit for nested unions. 34 | field11: dict[int | int, str] @@ -111,7 +212,17 @@ PYI016.pyi:34:21: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:37:16: PYI016 Duplicate union member `int` +ℹ Safe fix +31 31 | field10: (str | int) | str # PYI016: Duplicate union member `str` +32 32 | +33 33 | # Should emit for nested unions. +34 |-field11: dict[int | int, str] + 34 |+field11: dict[int, str] +35 35 | +36 36 | # Should emit for unions with more than two cases +37 37 | field12: int | int | int # Error + +PYI016.pyi:37:16: PYI016 [*] Duplicate union member `int` | 36 | # Should emit for unions with more than two cases 37 | field12: int | int | int # Error @@ -120,7 +231,17 @@ PYI016.pyi:37:16: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:37:22: PYI016 Duplicate union member `int` +ℹ Safe fix +34 34 | field11: dict[int | int, str] +35 35 | +36 36 | # Should emit for unions with more than two cases +37 |-field12: int | int | int # Error + 37 |+field12: int # Error +38 38 | field13: int | int | int | int # Error +39 39 | +40 40 | # Should emit for unions with more than two cases, even if not directly adjacent + +PYI016.pyi:37:22: PYI016 [*] Duplicate union member `int` | 36 | # Should emit for unions with more than two cases 37 | field12: int | int | int # Error @@ -129,7 +250,17 @@ PYI016.pyi:37:22: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:38:16: PYI016 Duplicate union member `int` +ℹ Safe fix +34 34 | field11: dict[int | int, str] +35 35 | +36 36 | # Should emit for unions with more than two cases +37 |-field12: int | int | int # Error + 37 |+field12: int # Error +38 38 | field13: int | int | int | int # Error +39 39 | +40 40 | # Should emit for unions with more than two cases, even if not directly adjacent + +PYI016.pyi:38:16: PYI016 [*] Duplicate union member `int` | 36 | # Should emit for unions with more than two cases 37 | field12: int | int | int # Error @@ -140,7 +271,17 @@ PYI016.pyi:38:16: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:38:22: PYI016 Duplicate union member `int` +ℹ Safe fix +35 35 | +36 36 | # Should emit for unions with more than two cases +37 37 | field12: int | int | int # Error +38 |-field13: int | int | int | int # Error + 38 |+field13: int # Error +39 39 | +40 40 | # Should emit for unions with more than two cases, even if not directly adjacent +41 41 | field14: int | int | str | int # Error + +PYI016.pyi:38:22: PYI016 [*] Duplicate union member `int` | 36 | # Should emit for unions with more than two cases 37 | field12: int | int | int # Error @@ -151,7 +292,17 @@ PYI016.pyi:38:22: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:38:28: PYI016 Duplicate union member `int` +ℹ Safe fix +35 35 | +36 36 | # Should emit for unions with more than two cases +37 37 | field12: int | int | int # Error +38 |-field13: int | int | int | int # Error + 38 |+field13: int # Error +39 39 | +40 40 | # Should emit for unions with more than two cases, even if not directly adjacent +41 41 | field14: int | int | str | int # Error + +PYI016.pyi:38:28: PYI016 [*] Duplicate union member `int` | 36 | # Should emit for unions with more than two cases 37 | field12: int | int | int # Error @@ -162,7 +313,17 @@ PYI016.pyi:38:28: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:41:16: PYI016 Duplicate union member `int` +ℹ Safe fix +35 35 | +36 36 | # Should emit for unions with more than two cases +37 37 | field12: int | int | int # Error +38 |-field13: int | int | int | int # Error + 38 |+field13: int # Error +39 39 | +40 40 | # Should emit for unions with more than two cases, even if not directly adjacent +41 41 | field14: int | int | str | int # Error + +PYI016.pyi:41:16: PYI016 [*] Duplicate union member `int` | 40 | # Should emit for unions with more than two cases, even if not directly adjacent 41 | field14: int | int | str | int # Error @@ -172,7 +333,17 @@ PYI016.pyi:41:16: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:41:28: PYI016 Duplicate union member `int` +ℹ Safe fix +38 38 | field13: int | int | int | int # Error +39 39 | +40 40 | # Should emit for unions with more than two cases, even if not directly adjacent +41 |-field14: int | int | str | int # Error + 41 |+field14: int | str # Error +42 42 | +43 43 | # Should emit for duplicate literal types; also covered by PYI030 +44 44 | field15: typing.Literal[1] | typing.Literal[1] # Error + +PYI016.pyi:41:28: PYI016 [*] Duplicate union member `int` | 40 | # Should emit for unions with more than two cases, even if not directly adjacent 41 | field14: int | int | str | int # Error @@ -182,7 +353,17 @@ PYI016.pyi:41:28: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:44:30: PYI016 Duplicate union member `typing.Literal[1]` +ℹ Safe fix +38 38 | field13: int | int | int | int # Error +39 39 | +40 40 | # Should emit for unions with more than two cases, even if not directly adjacent +41 |-field14: int | int | str | int # Error + 41 |+field14: int | str # Error +42 42 | +43 43 | # Should emit for duplicate literal types; also covered by PYI030 +44 44 | field15: typing.Literal[1] | typing.Literal[1] # Error + +PYI016.pyi:44:30: PYI016 [*] Duplicate union member `typing.Literal[1]` | 43 | # Should emit for duplicate literal types; also covered by PYI030 44 | field15: typing.Literal[1] | typing.Literal[1] # Error @@ -192,7 +373,17 @@ PYI016.pyi:44:30: PYI016 Duplicate union member `typing.Literal[1]` | = help: Remove duplicate union member `typing.Literal[1]` -PYI016.pyi:57:5: PYI016 Duplicate union member `set[int]` +ℹ Safe fix +41 41 | field14: int | int | str | int # Error +42 42 | +43 43 | # Should emit for duplicate literal types; also covered by PYI030 +44 |-field15: typing.Literal[1] | typing.Literal[1] # Error + 44 |+field15: typing.Literal[1] # Error +45 45 | +46 46 | # Shouldn't emit if in new parent type +47 47 | field16: int | dict[int, str] # OK + +PYI016.pyi:57:5: PYI016 [*] Duplicate union member `set[int]` | 55 | int # foo 56 | ], @@ -205,7 +396,24 @@ PYI016.pyi:57:5: PYI016 Duplicate union member `set[int]` | = help: Remove duplicate union member `set[int]` -PYI016.pyi:63:28: PYI016 Duplicate union member `int` +ℹ Unsafe fix +50 50 | field17: dict[int, int] # OK +51 51 | +52 52 | # Should emit in cases with newlines +53 |-field18: typing.Union[ +54 |- set[ +55 |- int # foo +56 |- ], +57 |- set[ +58 |- int # bar +59 |- ], +60 |-] # Error, newline and comment will not be emitted in message + 53 |+field18: set[int] # Error, newline and comment will not be emitted in message +61 54 | +62 55 | # Should emit in cases with `typing.Union` instead of `|` +63 56 | field19: typing.Union[int, int] # Error + +PYI016.pyi:63:28: PYI016 [*] Duplicate union member `int` | 62 | # Should emit in cases with `typing.Union` instead of `|` 63 | field19: typing.Union[int, int] # Error @@ -215,7 +423,17 @@ PYI016.pyi:63:28: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:66:41: PYI016 Duplicate union member `int` +ℹ Safe fix +60 60 | ] # Error, newline and comment will not be emitted in message +61 61 | +62 62 | # Should emit in cases with `typing.Union` instead of `|` +63 |-field19: typing.Union[int, int] # Error + 63 |+field19: int # Error +64 64 | +65 65 | # Should emit in cases with nested `typing.Union` +66 66 | field20: typing.Union[int, typing.Union[int, str]] # Error + +PYI016.pyi:66:41: PYI016 [*] Duplicate union member `int` | 65 | # Should emit in cases with nested `typing.Union` 66 | field20: typing.Union[int, typing.Union[int, str]] # Error @@ -225,7 +443,17 @@ PYI016.pyi:66:41: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:69:28: PYI016 Duplicate union member `int` +ℹ Safe fix +63 63 | field19: typing.Union[int, int] # Error +64 64 | +65 65 | # Should emit in cases with nested `typing.Union` +66 |-field20: typing.Union[int, typing.Union[int, str]] # Error + 66 |+field20: typing.Union[int, str] # Error +67 67 | +68 68 | # Should emit in cases with mixed `typing.Union` and `|` +69 69 | field21: typing.Union[int, int | str] # Error + +PYI016.pyi:69:28: PYI016 [*] Duplicate union member `int` | 68 | # Should emit in cases with mixed `typing.Union` and `|` 69 | field21: typing.Union[int, int | str] # Error @@ -235,7 +463,17 @@ PYI016.pyi:69:28: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:72:41: PYI016 Duplicate union member `int` +ℹ Safe fix +66 66 | field20: typing.Union[int, typing.Union[int, str]] # Error +67 67 | +68 68 | # Should emit in cases with mixed `typing.Union` and `|` +69 |-field21: typing.Union[int, int | str] # Error + 69 |+field21: int | str # Error +70 70 | +71 71 | # Should emit only once in cases with multiple nested `typing.Union` +72 72 | field22: typing.Union[int, typing.Union[int, typing.Union[int, int]]] # Error + +PYI016.pyi:72:41: PYI016 [*] Duplicate union member `int` | 71 | # Should emit only once in cases with multiple nested `typing.Union` 72 | field22: typing.Union[int, typing.Union[int, typing.Union[int, int]]] # Error @@ -245,7 +483,17 @@ PYI016.pyi:72:41: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:72:59: PYI016 Duplicate union member `int` +ℹ Safe fix +69 69 | field21: typing.Union[int, int | str] # Error +70 70 | +71 71 | # Should emit only once in cases with multiple nested `typing.Union` +72 |-field22: typing.Union[int, typing.Union[int, typing.Union[int, int]]] # Error + 72 |+field22: int # Error +73 73 | +74 74 | # Should emit in cases with newlines +75 75 | field23: set[ # foo + +PYI016.pyi:72:59: PYI016 [*] Duplicate union member `int` | 71 | # Should emit only once in cases with multiple nested `typing.Union` 72 | field22: typing.Union[int, typing.Union[int, typing.Union[int, int]]] # Error @@ -255,7 +503,17 @@ PYI016.pyi:72:59: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:72:64: PYI016 Duplicate union member `int` +ℹ Safe fix +69 69 | field21: typing.Union[int, int | str] # Error +70 70 | +71 71 | # Should emit only once in cases with multiple nested `typing.Union` +72 |-field22: typing.Union[int, typing.Union[int, typing.Union[int, int]]] # Error + 72 |+field22: int # Error +73 73 | +74 74 | # Should emit in cases with newlines +75 75 | field23: set[ # foo + +PYI016.pyi:72:64: PYI016 [*] Duplicate union member `int` | 71 | # Should emit only once in cases with multiple nested `typing.Union` 72 | field22: typing.Union[int, typing.Union[int, typing.Union[int, int]]] # Error @@ -265,7 +523,17 @@ PYI016.pyi:72:64: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:76:12: PYI016 Duplicate union member `set[int]` +ℹ Safe fix +69 69 | field21: typing.Union[int, int | str] # Error +70 70 | +71 71 | # Should emit only once in cases with multiple nested `typing.Union` +72 |-field22: typing.Union[int, typing.Union[int, typing.Union[int, int]]] # Error + 72 |+field22: int # Error +73 73 | +74 74 | # Should emit in cases with newlines +75 75 | field23: set[ # foo + +PYI016.pyi:76:12: PYI016 [*] Duplicate union member `set[int]` | 74 | # Should emit in cases with newlines 75 | field23: set[ # foo @@ -276,7 +544,18 @@ PYI016.pyi:76:12: PYI016 Duplicate union member `set[int]` | = help: Remove duplicate union member `set[int]` -PYI016.pyi:81:41: PYI016 Duplicate union member `int` +ℹ Unsafe fix +72 72 | field22: typing.Union[int, typing.Union[int, typing.Union[int, int]]] # Error +73 73 | +74 74 | # Should emit in cases with newlines +75 |-field23: set[ # foo +76 |- int] | set[int] + 75 |+field23: set[int] +77 76 | +78 77 | # Should emit twice (once for each `int` in the nested union, both of which are +79 78 | # duplicates of the outer `int`), but not three times (which would indicate that + +PYI016.pyi:81:41: PYI016 [*] Duplicate union member `int` | 79 | # duplicates of the outer `int`), but not three times (which would indicate that 80 | # we incorrectly re-checked the nested union). @@ -287,7 +566,17 @@ PYI016.pyi:81:41: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:81:46: PYI016 Duplicate union member `int` +ℹ Safe fix +78 78 | # Should emit twice (once for each `int` in the nested union, both of which are +79 79 | # duplicates of the outer `int`), but not three times (which would indicate that +80 80 | # we incorrectly re-checked the nested union). +81 |-field24: typing.Union[int, typing.Union[int, int]] # PYI016: Duplicate union member `int` + 81 |+field24: int # PYI016: Duplicate union member `int` +82 82 | +83 83 | # Should emit twice (once for each `int` in the nested union, both of which are +84 84 | # duplicates of the outer `int`), but not three times (which would indicate that + +PYI016.pyi:81:46: PYI016 [*] Duplicate union member `int` | 79 | # duplicates of the outer `int`), but not three times (which would indicate that 80 | # we incorrectly re-checked the nested union). @@ -298,7 +587,17 @@ PYI016.pyi:81:46: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:86:28: PYI016 Duplicate union member `int` +ℹ Safe fix +78 78 | # Should emit twice (once for each `int` in the nested union, both of which are +79 79 | # duplicates of the outer `int`), but not three times (which would indicate that +80 80 | # we incorrectly re-checked the nested union). +81 |-field24: typing.Union[int, typing.Union[int, int]] # PYI016: Duplicate union member `int` + 81 |+field24: int # PYI016: Duplicate union member `int` +82 82 | +83 83 | # Should emit twice (once for each `int` in the nested union, both of which are +84 84 | # duplicates of the outer `int`), but not three times (which would indicate that + +PYI016.pyi:86:28: PYI016 [*] Duplicate union member `int` | 84 | # duplicates of the outer `int`), but not three times (which would indicate that 85 | # we incorrectly re-checked the nested union). @@ -309,7 +608,17 @@ PYI016.pyi:86:28: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:86:34: PYI016 Duplicate union member `int` +ℹ Safe fix +83 83 | # Should emit twice (once for each `int` in the nested union, both of which are +84 84 | # duplicates of the outer `int`), but not three times (which would indicate that +85 85 | # we incorrectly re-checked the nested union). +86 |-field25: typing.Union[int, int | int] # PYI016: Duplicate union member `int` + 86 |+field25: int # PYI016: Duplicate union member `int` +87 87 | +88 88 | # Should emit in cases with nested `typing.Union` +89 89 | field26: typing.Union[typing.Union[int, int]] # PYI016: Duplicate union member `int` + +PYI016.pyi:86:34: PYI016 [*] Duplicate union member `int` | 84 | # duplicates of the outer `int`), but not three times (which would indicate that 85 | # we incorrectly re-checked the nested union). @@ -320,7 +629,17 @@ PYI016.pyi:86:34: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:89:41: PYI016 Duplicate union member `int` +ℹ Safe fix +83 83 | # Should emit twice (once for each `int` in the nested union, both of which are +84 84 | # duplicates of the outer `int`), but not three times (which would indicate that +85 85 | # we incorrectly re-checked the nested union). +86 |-field25: typing.Union[int, int | int] # PYI016: Duplicate union member `int` + 86 |+field25: int # PYI016: Duplicate union member `int` +87 87 | +88 88 | # Should emit in cases with nested `typing.Union` +89 89 | field26: typing.Union[typing.Union[int, int]] # PYI016: Duplicate union member `int` + +PYI016.pyi:89:41: PYI016 [*] Duplicate union member `int` | 88 | # Should emit in cases with nested `typing.Union` 89 | field26: typing.Union[typing.Union[int, int]] # PYI016: Duplicate union member `int` @@ -330,7 +649,17 @@ PYI016.pyi:89:41: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:92:54: PYI016 Duplicate union member `int` +ℹ Safe fix +86 86 | field25: typing.Union[int, int | int] # PYI016: Duplicate union member `int` +87 87 | +88 88 | # Should emit in cases with nested `typing.Union` +89 |-field26: typing.Union[typing.Union[int, int]] # PYI016: Duplicate union member `int` + 89 |+field26: int # PYI016: Duplicate union member `int` +90 90 | +91 91 | # Should emit in cases with nested `typing.Union` +92 92 | field27: typing.Union[typing.Union[typing.Union[int, int]]] # PYI016: Duplicate union member `int` + +PYI016.pyi:92:54: PYI016 [*] Duplicate union member `int` | 91 | # Should emit in cases with nested `typing.Union` 92 | field27: typing.Union[typing.Union[typing.Union[int, int]]] # PYI016: Duplicate union member `int` @@ -340,7 +669,17 @@ PYI016.pyi:92:54: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:95:29: PYI016 Duplicate union member `int` +ℹ Safe fix +89 89 | field26: typing.Union[typing.Union[int, int]] # PYI016: Duplicate union member `int` +90 90 | +91 91 | # Should emit in cases with nested `typing.Union` +92 |-field27: typing.Union[typing.Union[typing.Union[int, int]]] # PYI016: Duplicate union member `int` + 92 |+field27: int # PYI016: Duplicate union member `int` +93 93 | +94 94 | # Should emit in cases with mixed `typing.Union` and `|` +95 95 | field28: typing.Union[int | int] # Error + +PYI016.pyi:95:29: PYI016 [*] Duplicate union member `int` | 94 | # Should emit in cases with mixed `typing.Union` and `|` 95 | field28: typing.Union[int | int] # Error @@ -350,7 +689,17 @@ PYI016.pyi:95:29: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:98:54: PYI016 Duplicate union member `int` +ℹ Safe fix +92 92 | field27: typing.Union[typing.Union[typing.Union[int, int]]] # PYI016: Duplicate union member `int` +93 93 | +94 94 | # Should emit in cases with mixed `typing.Union` and `|` +95 |-field28: typing.Union[int | int] # Error + 95 |+field28: int # Error +96 96 | +97 97 | # Should emit twice in cases with multiple nested `typing.Union` +98 98 | field29: typing.Union[int, typing.Union[typing.Union[int, int]]] # Error + +PYI016.pyi:98:54: PYI016 [*] Duplicate union member `int` | 97 | # Should emit twice in cases with multiple nested `typing.Union` 98 | field29: typing.Union[int, typing.Union[typing.Union[int, int]]] # Error @@ -360,7 +709,17 @@ PYI016.pyi:98:54: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:98:59: PYI016 Duplicate union member `int` +ℹ Safe fix +95 95 | field28: typing.Union[int | int] # Error +96 96 | +97 97 | # Should emit twice in cases with multiple nested `typing.Union` +98 |-field29: typing.Union[int, typing.Union[typing.Union[int, int]]] # Error + 98 |+field29: int # Error +99 99 | +100 100 | # Should emit once in cases with multiple nested `typing.Union` +101 101 | field30: typing.Union[int, typing.Union[typing.Union[int, str]]] # Error + +PYI016.pyi:98:59: PYI016 [*] Duplicate union member `int` | 97 | # Should emit twice in cases with multiple nested `typing.Union` 98 | field29: typing.Union[int, typing.Union[typing.Union[int, int]]] # Error @@ -370,7 +729,17 @@ PYI016.pyi:98:59: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:101:54: PYI016 Duplicate union member `int` +ℹ Safe fix +95 95 | field28: typing.Union[int | int] # Error +96 96 | +97 97 | # Should emit twice in cases with multiple nested `typing.Union` +98 |-field29: typing.Union[int, typing.Union[typing.Union[int, int]]] # Error + 98 |+field29: int # Error +99 99 | +100 100 | # Should emit once in cases with multiple nested `typing.Union` +101 101 | field30: typing.Union[int, typing.Union[typing.Union[int, str]]] # Error + +PYI016.pyi:101:54: PYI016 [*] Duplicate union member `int` | 100 | # Should emit once in cases with multiple nested `typing.Union` 101 | field30: typing.Union[int, typing.Union[typing.Union[int, str]]] # Error @@ -380,7 +749,17 @@ PYI016.pyi:101:54: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:104:49: PYI016 Duplicate union member `int` +ℹ Safe fix +98 98 | field29: typing.Union[int, typing.Union[typing.Union[int, int]]] # Error +99 99 | +100 100 | # Should emit once in cases with multiple nested `typing.Union` +101 |-field30: typing.Union[int, typing.Union[typing.Union[int, str]]] # Error + 101 |+field30: typing.Union[int, str] # Error +102 102 | +103 103 | # Should emit once, and fix to `typing.Union[float, int]` +104 104 | field31: typing.Union[float, typing.Union[int | int]] # Error + +PYI016.pyi:104:49: PYI016 [*] Duplicate union member `int` | 103 | # Should emit once, and fix to `typing.Union[float, int]` 104 | field31: typing.Union[float, typing.Union[int | int]] # Error @@ -390,7 +769,17 @@ PYI016.pyi:104:49: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:107:49: PYI016 Duplicate union member `int` +ℹ Safe fix +101 101 | field30: typing.Union[int, typing.Union[typing.Union[int, str]]] # Error +102 102 | +103 103 | # Should emit once, and fix to `typing.Union[float, int]` +104 |-field31: typing.Union[float, typing.Union[int | int]] # Error + 104 |+field31: float | int # Error +105 105 | +106 106 | # Should emit once, and fix to `typing.Union[float, int]` +107 107 | field32: typing.Union[float, typing.Union[int | int | int]] # Error + +PYI016.pyi:107:49: PYI016 [*] Duplicate union member `int` | 106 | # Should emit once, and fix to `typing.Union[float, int]` 107 | field32: typing.Union[float, typing.Union[int | int | int]] # Error @@ -400,7 +789,17 @@ PYI016.pyi:107:49: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:107:55: PYI016 Duplicate union member `int` +ℹ Safe fix +104 104 | field31: typing.Union[float, typing.Union[int | int]] # Error +105 105 | +106 106 | # Should emit once, and fix to `typing.Union[float, int]` +107 |-field32: typing.Union[float, typing.Union[int | int | int]] # Error + 107 |+field32: float | int # Error +108 108 | +109 109 | # Test case for mixed union type fix +110 110 | field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error + +PYI016.pyi:107:55: PYI016 [*] Duplicate union member `int` | 106 | # Should emit once, and fix to `typing.Union[float, int]` 107 | field32: typing.Union[float, typing.Union[int | int | int]] # Error @@ -410,7 +809,17 @@ PYI016.pyi:107:55: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:110:42: PYI016 Duplicate union member `int` +ℹ Safe fix +104 104 | field31: typing.Union[float, typing.Union[int | int]] # Error +105 105 | +106 106 | # Should emit once, and fix to `typing.Union[float, int]` +107 |-field32: typing.Union[float, typing.Union[int | int | int]] # Error + 107 |+field32: float | int # Error +108 108 | +109 109 | # Test case for mixed union type fix +110 110 | field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error + +PYI016.pyi:110:42: PYI016 [*] Duplicate union member `int` | 109 | # Test case for mixed union type fix 110 | field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error @@ -420,7 +829,17 @@ PYI016.pyi:110:42: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:110:62: PYI016 Duplicate union member `int` +ℹ Safe fix +107 107 | field32: typing.Union[float, typing.Union[int | int | int]] # Error +108 108 | +109 109 | # Test case for mixed union type fix +110 |-field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error + 110 |+field33: int # Error +111 111 | +112 112 | # Test case for mixed union type +113 113 | field34: typing.Union[list[int], str] | typing.Union[bytes, list[int]] # Error + +PYI016.pyi:110:62: PYI016 [*] Duplicate union member `int` | 109 | # Test case for mixed union type fix 110 | field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error @@ -430,7 +849,17 @@ PYI016.pyi:110:62: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:110:68: PYI016 Duplicate union member `int` +ℹ Safe fix +107 107 | field32: typing.Union[float, typing.Union[int | int | int]] # Error +108 108 | +109 109 | # Test case for mixed union type fix +110 |-field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error + 110 |+field33: int # Error +111 111 | +112 112 | # Test case for mixed union type +113 113 | field34: typing.Union[list[int], str] | typing.Union[bytes, list[int]] # Error + +PYI016.pyi:110:68: PYI016 [*] Duplicate union member `int` | 109 | # Test case for mixed union type fix 110 | field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error @@ -440,10 +869,27 @@ PYI016.pyi:110:68: PYI016 Duplicate union member `int` | = help: Remove duplicate union member `int` -PYI016.pyi:113:61: PYI016 Duplicate union member `list[int]` +ℹ Safe fix +107 107 | field32: typing.Union[float, typing.Union[int | int | int]] # Error +108 108 | +109 109 | # Test case for mixed union type fix +110 |-field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error + 110 |+field33: int # Error +111 111 | +112 112 | # Test case for mixed union type +113 113 | field34: typing.Union[list[int], str] | typing.Union[bytes, list[int]] # Error + +PYI016.pyi:113:61: PYI016 [*] Duplicate union member `list[int]` | 112 | # Test case for mixed union type 113 | field34: typing.Union[list[int], str] | typing.Union[bytes, list[int]] # Error | ^^^^^^^^^ PYI016 | = help: Remove duplicate union member `list[int]` + +ℹ Safe fix +110 110 | field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error +111 111 | +112 112 | # Test case for mixed union type +113 |-field34: typing.Union[list[int], str] | typing.Union[bytes, list[int]] # Error + 113 |+field34: typing.Union[list[int], str, bytes] # Error