---
source: crates/ruff_linter/src/rules/flake8_pyi/mod.rs
---
PYI016 [*] Duplicate union member `str`
 --> PYI016.py:7:15
  |
6 | # Should emit for duplicate field types.
7 | field2: str | str  # PYI016: Duplicate union member `str`
  |               ^^^
8 |
9 | # Should emit for union types in arguments.
  |
help: Remove duplicate union member `str`
  |
6 | # Should emit for duplicate field types.
  - field2: str | str  # PYI016: Duplicate union member `str`
7 + field2: str  # PYI016: Duplicate union member `str`
8 |
  |

PYI016 [*] Duplicate union member `int`
  --> PYI016.py:10:23
   |
 9 | # Should emit for union types in arguments.
10 | def func1(arg1: int | int):  # PYI016: Duplicate union member `int`
   |                       ^^^
11 |     print(arg1)
   |
help: Remove duplicate union member `int`
   |
9  | # Should emit for union types in arguments.
   - def func1(arg1: int | int):  # PYI016: Duplicate union member `int`
10 + def func1(arg1: int):  # PYI016: Duplicate union member `int`
11 |     print(arg1)
   |

PYI016 [*] Duplicate union member `str`
  --> PYI016.py:14:22
   |
13 | # Should emit for unions in return types.
14 | def func2() -> str | str:  # PYI016: Duplicate union member `str`
   |                      ^^^
15 |     return "my string"
   |
help: Remove duplicate union member `str`
   |
13 | # Should emit for unions in return types.
   - def func2() -> str | str:  # PYI016: Duplicate union member `str`
14 + def func2() -> str:  # PYI016: Duplicate union member `str`
15 |     return "my string"
   |

PYI016 [*] Duplicate union member `str`
  --> PYI016.py:18:15
   |
17 | # Should emit in longer unions, even if not directly adjacent.
18 | field3: str | str | int  # PYI016: Duplicate union member `str`
   |               ^^^
19 | field4: int | int | str  # PYI016: Duplicate union member `int`
20 | field5: str | int | str  # PYI016: Duplicate union member `str`
   |
help: Remove duplicate union member `str`
   |
17 | # Should emit in longer unions, even if not directly adjacent.
   - field3: str | str | int  # PYI016: Duplicate union member `str`
18 + field3: str | int  # PYI016: Duplicate union member `str`
19 | field4: int | int | str  # PYI016: Duplicate union member `int`
   |

PYI016 [*] Duplicate union member `int`
  --> PYI016.py:19:15
   |
17 | # Should emit in longer unions, even if not directly adjacent.
18 | field3: str | str | int  # PYI016: Duplicate union member `str`
19 | field4: int | int | str  # PYI016: Duplicate union member `int`
   |               ^^^
20 | field5: str | int | str  # PYI016: Duplicate union member `str`
21 | field6: int | bool | str | int  # PYI016: Duplicate union member `int`
   |
help: Remove duplicate union member `int`
   |
18 | field3: str | str | int  # PYI016: Duplicate union member `str`
   - field4: int | int | str  # PYI016: Duplicate union member `int`
19 + field4: int | str  # PYI016: Duplicate union member `int`
20 | field5: str | int | str  # PYI016: Duplicate union member `str`
   |

PYI016 [*] Duplicate union member `str`
  --> PYI016.py:20:21
   |
18 | field3: str | str | int  # PYI016: Duplicate union member `str`
19 | field4: int | int | str  # PYI016: Duplicate union member `int`
20 | field5: str | int | str  # PYI016: Duplicate union member `str`
   |                     ^^^
21 | field6: int | bool | str | int  # PYI016: Duplicate union member `int`
   |
help: Remove duplicate union member `str`
   |
19 | field4: int | int | str  # PYI016: Duplicate union member `int`
   - field5: str | int | str  # PYI016: Duplicate union member `str`
20 + field5: str | int  # PYI016: Duplicate union member `str`
21 | field6: int | bool | str | int  # PYI016: Duplicate union member `int`
   |

PYI016 [*] Duplicate union member `int`
  --> PYI016.py:21:28
   |
19 | field4: int | int | str  # PYI016: Duplicate union member `int`
20 | field5: str | int | str  # PYI016: Duplicate union member `str`
21 | field6: int | bool | str | int  # PYI016: Duplicate union member `int`
   |                            ^^^
22 |
23 | # Shouldn't emit for non-type unions.
   |
help: Remove duplicate union member `int`
   |
20 | field5: str | int | str  # PYI016: Duplicate union member `str`
   - field6: int | bool | str | int  # PYI016: Duplicate union member `int`
21 + field6: int | bool | str  # PYI016: Duplicate union member `int`
22 |
   |

PYI016 [*] Duplicate union member `int`
  --> PYI016.py:27:22
   |
26 | # Should emit for strangely-bracketed unions.
27 | field8: int | (str | int)  # PYI016: Duplicate union member `int`
   |                      ^^^
28 |
29 | # Should handle user brackets when fixing.
   |
help: Remove duplicate union member `int`
   |
26 | # Should emit for strangely-bracketed unions.
   - field8: int | (str | int)  # PYI016: Duplicate union member `int`
27 + field8: int | str  # PYI016: Duplicate union member `int`
28 |
   |

PYI016 [*] Duplicate union member `int`
  --> PYI016.py:30:16
   |
29 | # Should handle user brackets when fixing.
30 | field9: int | (int | str)  # PYI016: Duplicate union member `int`
   |                ^^^
31 | field10: (str | int) | str  # PYI016: Duplicate union member `str`
   |
help: Remove duplicate union member `int`
   |
29 | # Should handle user brackets when fixing.
   - field9: int | (int | str)  # PYI016: Duplicate union member `int`
30 + field9: int | str  # PYI016: Duplicate union member `int`
31 | field10: (str | int) | str  # PYI016: Duplicate union member `str`
   |

PYI016 [*] Duplicate union member `str`
  --> PYI016.py:31:24
   |
29 | # Should handle user brackets when fixing.
30 | field9: int | (int | str)  # PYI016: Duplicate union member `int`
31 | field10: (str | int) | str  # PYI016: Duplicate union member `str`
   |                        ^^^
32 |
33 | # Should emit for nested unions.
   |
help: Remove duplicate union member `str`
   |
30 | field9: int | (int | str)  # PYI016: Duplicate union member `int`
   - field10: (str | int) | str  # PYI016: Duplicate union member `str`
31 + field10: str | int  # PYI016: Duplicate union member `str`
32 |
   |

PYI016 [*] Duplicate union member `int`
  --> PYI016.py:34:21
   |
33 | # Should emit for nested unions.
34 | field11: dict[int | int, str]
   |                     ^^^
35 |
36 | # Should emit for unions with more than two cases
   |
help: Remove duplicate union member `int`
   |
33 | # Should emit for nested unions.
   - field11: dict[int | int, str]
34 + field11: dict[int, str]
35 |
   |

PYI016 [*] Duplicate union member `int`
  --> PYI016.py:37:16
   |
36 | # Should emit for unions with more than two cases
37 | field12: int | int | int  # Error
   |                ^^^
38 | field13: int | int | int | int  # Error
   |
help: Remove duplicate union member `int`
   |
36 | # Should emit for unions with more than two cases
   - field12: int | int | int  # Error
37 + field12: int  # Error
38 | field13: int | int | int | int  # Error
   |

PYI016 [*] Duplicate union member `int`
  --> PYI016.py:37:22
   |
36 | # Should emit for unions with more than two cases
37 | field12: int | int | int  # Error
   |                      ^^^
38 | field13: int | int | int | int  # Error
   |
help: Remove duplicate union member `int`
   |
36 | # Should emit for unions with more than two cases
   - field12: int | int | int  # Error
37 + field12: int  # Error
38 | field13: int | int | int | int  # Error
   |

PYI016 [*] Duplicate union member `int`
  --> PYI016.py:38:16
   |
36 | # Should emit for unions with more than two cases
37 | field12: int | int | int  # Error
38 | field13: int | int | int | int  # Error
   |                ^^^
39 |
40 | # Should emit for unions with more than two cases, even if not directly adjacent
   |
help: Remove duplicate union member `int`
   |
37 | field12: int | int | int  # Error
   - field13: int | int | int | int  # Error
38 + field13: int  # Error
39 |
   |

PYI016 [*] Duplicate union member `int`
  --> PYI016.py:38:22
   |
36 | # Should emit for unions with more than two cases
37 | field12: int | int | int  # Error
38 | field13: int | int | int | int  # Error
   |                      ^^^
39 |
40 | # Should emit for unions with more than two cases, even if not directly adjacent
   |
help: Remove duplicate union member `int`
   |
37 | field12: int | int | int  # Error
   - field13: int | int | int | int  # Error
38 + field13: int  # Error
39 |
   |

PYI016 [*] Duplicate union member `int`
  --> PYI016.py:38:28
   |
36 | # Should emit for unions with more than two cases
37 | field12: int | int | int  # Error
38 | field13: int | int | int | int  # Error
   |                            ^^^
39 |
40 | # Should emit for unions with more than two cases, even if not directly adjacent
   |
help: Remove duplicate union member `int`
   |
37 | field12: int | int | int  # Error
   - field13: int | int | int | int  # Error
38 + field13: int  # Error
39 |
   |

PYI016 [*] Duplicate union member `int`
  --> PYI016.py:41:16
   |
40 | # Should emit for unions with more than two cases, even if not directly adjacent
41 | field14: int | int | str | int  # Error
   |                ^^^
42 |
43 | # Should emit for duplicate literal types; also covered by PYI030
   |
help: Remove duplicate union member `int`
   |
40 | # Should emit for unions with more than two cases, even if not directly adjacent
   - field14: int | int | str | int  # Error
41 + field14: int | str  # Error
42 |
   |

PYI016 [*] Duplicate union member `int`
  --> PYI016.py:41:28
   |
40 | # Should emit for unions with more than two cases, even if not directly adjacent
41 | field14: int | int | str | int  # Error
   |                            ^^^
42 |
43 | # Should emit for duplicate literal types; also covered by PYI030
   |
help: Remove duplicate union member `int`
   |
40 | # Should emit for unions with more than two cases, even if not directly adjacent
   - field14: int | int | str | int  # Error
41 + field14: int | str  # Error
42 |
   |

PYI016 [*] Duplicate union member `typing.Literal[1]`
  --> PYI016.py:44:30
   |
43 | # Should emit for duplicate literal types; also covered by PYI030
44 | field15: typing.Literal[1] | typing.Literal[1]  # Error
   |                              ^^^^^^^^^^^^^^^^^
45 |
46 | # Shouldn't emit if in new parent type
   |
help: Remove duplicate union member `typing.Literal[1]`
   |
43 | # Should emit for duplicate literal types; also covered by PYI030
   - field15: typing.Literal[1] | typing.Literal[1]  # Error
44 + field15: typing.Literal[1]  # Error
45 |
   |

PYI016 [*] Duplicate union member `set[int]`
  --> PYI016.py:57:5
   |
55 |           int  # foo
56 |       ],
57 | /     set[
58 | |         int  # bar
59 | |     ],
   | |_____^
60 |   ]  # Error, newline and comment will not be emitted in message
   |
help: Remove duplicate union member `set[int]`
   |
52 | # Should emit in cases with newlines
   - field18: typing.Union[
   -     set[
   -         int  # foo
   -     ],
   -     set[
   -         int  # bar
   -     ],
   - ]  # Error, newline and comment will not be emitted in message
53 + field18: set[int]  # Error, newline and comment will not be emitted in message
54 |
   |
note: This is an unsafe fix and may change runtime behavior

PYI016 [*] Duplicate union member `int`
  --> PYI016.py:63:28
   |
62 | # Should emit in cases with `typing.Union` instead of `|`
63 | field19: typing.Union[int, int]  # Error
   |                            ^^^
64 |
65 | # Should emit in cases with nested `typing.Union`
   |
help: Remove duplicate union member `int`
   |
62 | # Should emit in cases with `typing.Union` instead of `|`
   - field19: typing.Union[int, int]  # Error
63 + field19: int  # Error
64 |
   |

PYI016 [*] Duplicate union member `int`
  --> PYI016.py:66:41
   |
65 | # Should emit in cases with nested `typing.Union`
66 | field20: typing.Union[int, typing.Union[int, str]]  # Error
   |                                         ^^^
67 |
68 | # Should emit in cases with mixed `typing.Union` and `|`
   |
help: Remove duplicate union member `int`
   |
65 | # Should emit in cases with nested `typing.Union`
   - field20: typing.Union[int, typing.Union[int, str]]  # Error
66 + field20: typing.Union[int, str]  # Error
67 |
   |

PYI016 [*] Duplicate union member `int`
  --> PYI016.py:69:28
   |
68 | # Should emit in cases with mixed `typing.Union` and `|`
69 | field21: typing.Union[int, int | str]  # Error
   |                            ^^^
70 |
71 | # Should emit only once in cases with multiple nested `typing.Union`
   |
help: Remove duplicate union member `int`
   |
68 | # Should emit in cases with mixed `typing.Union` and `|`
   - field21: typing.Union[int, int | str]  # Error
69 + field21: int | str  # Error
70 |
   |

PYI016 [*] Duplicate union member `int`
  --> PYI016.py:72:41
   |
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
   |                                         ^^^
73 |
74 | # Should emit in cases with newlines
   |
help: Remove duplicate union member `int`
   |
71 | # Should emit only once in cases with multiple nested `typing.Union`
   - field22: typing.Union[int, typing.Union[int, typing.Union[int, int]]]  # Error
72 + field22: int  # Error
73 |
   |

PYI016 [*] Duplicate union member `int`
  --> PYI016.py:72:59
   |
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
   |                                                           ^^^
73 |
74 | # Should emit in cases with newlines
   |
help: Remove duplicate union member `int`
   |
71 | # Should emit only once in cases with multiple nested `typing.Union`
   - field22: typing.Union[int, typing.Union[int, typing.Union[int, int]]]  # Error
72 + field22: int  # Error
73 |
   |

PYI016 [*] Duplicate union member `int`
  --> PYI016.py:72:64
   |
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
   |                                                                ^^^
73 |
74 | # Should emit in cases with newlines
   |
help: Remove duplicate union member `int`
   |
71 | # Should emit only once in cases with multiple nested `typing.Union`
   - field22: typing.Union[int, typing.Union[int, typing.Union[int, int]]]  # Error
72 + field22: int  # Error
73 |
   |

PYI016 [*] Duplicate union member `set[int]`
  --> PYI016.py:76:12
   |
74 | # Should emit in cases with newlines
75 | field23: set[  # foo
76 |     int] | set[int]
   |            ^^^^^^^^
77 |
78 | # Should emit twice (once for each `int` in the nested union, both of which are
   |
help: Remove duplicate union member `set[int]`
   |
74 | # Should emit in cases with newlines
   - field23: set[  # foo
   -     int] | set[int]
75 + field23: set[int]
76 |
   |
note: This is an unsafe fix and may change runtime behavior

PYI016 [*] Duplicate union member `int`
  --> PYI016.py:81:41
   |
79 | # duplicates of the outer `int`), but not three times (which would indicate that
80 | # we incorrectly re-checked the nested union).
81 | field24: typing.Union[int, typing.Union[int, int]]  # PYI016: Duplicate union member `int`
   |                                         ^^^
82 |
83 | # Should emit twice (once for each `int` in the nested union, both of which are
   |
help: Remove duplicate union member `int`
   |
80 | # we incorrectly re-checked the nested union).
   - field24: typing.Union[int, typing.Union[int, int]]  # PYI016: Duplicate union member `int`
81 + field24: int  # PYI016: Duplicate union member `int`
82 |
   |

PYI016 [*] Duplicate union member `int`
  --> PYI016.py:81:46
   |
79 | # duplicates of the outer `int`), but not three times (which would indicate that
80 | # we incorrectly re-checked the nested union).
81 | field24: typing.Union[int, typing.Union[int, int]]  # PYI016: Duplicate union member `int`
   |                                              ^^^
82 |
83 | # Should emit twice (once for each `int` in the nested union, both of which are
   |
help: Remove duplicate union member `int`
   |
80 | # we incorrectly re-checked the nested union).
   - field24: typing.Union[int, typing.Union[int, int]]  # PYI016: Duplicate union member `int`
81 + field24: int  # PYI016: Duplicate union member `int`
82 |
   |

PYI016 [*] Duplicate union member `int`
  --> PYI016.py:86:28
   |
84 | # duplicates of the outer `int`), but not three times (which would indicate that
85 | # we incorrectly re-checked the nested union).
86 | field25: typing.Union[int, int | int]  # PYI016: Duplicate union member `int`
   |                            ^^^
87 |
88 | # Should emit in cases with nested `typing.Union`
   |
help: Remove duplicate union member `int`
   |
85 | # we incorrectly re-checked the nested union).
   - field25: typing.Union[int, int | int]  # PYI016: Duplicate union member `int`
86 + field25: int  # PYI016: Duplicate union member `int`
87 |
   |

PYI016 [*] Duplicate union member `int`
  --> PYI016.py:86:34
   |
84 | # duplicates of the outer `int`), but not three times (which would indicate that
85 | # we incorrectly re-checked the nested union).
86 | field25: typing.Union[int, int | int]  # PYI016: Duplicate union member `int`
   |                                  ^^^
87 |
88 | # Should emit in cases with nested `typing.Union`
   |
help: Remove duplicate union member `int`
   |
85 | # we incorrectly re-checked the nested union).
   - field25: typing.Union[int, int | int]  # PYI016: Duplicate union member `int`
86 + field25: int  # PYI016: Duplicate union member `int`
87 |
   |

PYI016 [*] Duplicate union member `int`
  --> PYI016.py:89:41
   |
88 | # Should emit in cases with nested `typing.Union`
89 | field26: typing.Union[typing.Union[int, int]]  # PYI016: Duplicate union member `int`
   |                                         ^^^
90 |
91 | # Should emit in cases with nested `typing.Union`
   |
help: Remove duplicate union member `int`
   |
88 | # Should emit in cases with nested `typing.Union`
   - field26: typing.Union[typing.Union[int, int]]  # PYI016: Duplicate union member `int`
89 + field26: int  # PYI016: Duplicate union member `int`
90 |
   |

PYI016 [*] Duplicate union member `int`
  --> PYI016.py:92:54
   |
91 | # Should emit in cases with nested `typing.Union`
92 | field27: typing.Union[typing.Union[typing.Union[int, int]]]  # PYI016: Duplicate union member `int`
   |                                                      ^^^
93 |
94 | # Should emit in cases with mixed `typing.Union` and `|`
   |
help: Remove duplicate union member `int`
   |
91 | # Should emit in cases with nested `typing.Union`
   - field27: typing.Union[typing.Union[typing.Union[int, int]]]  # PYI016: Duplicate union member `int`
92 + field27: int  # PYI016: Duplicate union member `int`
93 |
   |

PYI016 [*] Duplicate union member `int`
  --> PYI016.py:95:29
   |
94 | # Should emit in cases with mixed `typing.Union` and `|`
95 | field28: typing.Union[int | int]  # Error
   |                             ^^^
96 |
97 | # Should emit twice in cases with multiple nested `typing.Union`
   |
help: Remove duplicate union member `int`
   |
94 | # Should emit in cases with mixed `typing.Union` and `|`
   - field28: typing.Union[int | int]  # Error
95 + field28: int  # Error
96 |
   |

PYI016 [*] Duplicate union member `int`
   --> PYI016.py:98:54
    |
 97 | # Should emit twice in cases with multiple nested `typing.Union`
 98 | field29: typing.Union[int, typing.Union[typing.Union[int, int]]]  # Error
    |                                                      ^^^
 99 |
100 | # Should emit once in cases with multiple nested `typing.Union`
    |
help: Remove duplicate union member `int`
   |
97 | # Should emit twice in cases with multiple nested `typing.Union`
   - field29: typing.Union[int, typing.Union[typing.Union[int, int]]]  # Error
98 + field29: int  # Error
99 |
   |

PYI016 [*] Duplicate union member `int`
   --> PYI016.py:98:59
    |
 97 | # Should emit twice in cases with multiple nested `typing.Union`
 98 | field29: typing.Union[int, typing.Union[typing.Union[int, int]]]  # Error
    |                                                           ^^^
 99 |
100 | # Should emit once in cases with multiple nested `typing.Union`
    |
help: Remove duplicate union member `int`
   |
97 | # Should emit twice in cases with multiple nested `typing.Union`
   - field29: typing.Union[int, typing.Union[typing.Union[int, int]]]  # Error
98 + field29: int  # Error
99 |
   |

PYI016 [*] Duplicate union member `int`
   --> PYI016.py:101:54
    |
100 | # Should emit once in cases with multiple nested `typing.Union`
101 | field30: typing.Union[int, typing.Union[typing.Union[int, str]]]  # Error
    |                                                      ^^^
102 |
103 | # Should emit once, and fix to `typing.Union[float, int]`
    |
help: Remove duplicate union member `int`
    |
100 | # Should emit once in cases with multiple nested `typing.Union`
    - field30: typing.Union[int, typing.Union[typing.Union[int, str]]]  # Error
101 + field30: typing.Union[int, str]  # Error
102 |
    |

PYI016 [*] Duplicate union member `int`
   --> PYI016.py:104:49
    |
103 | # Should emit once, and fix to `typing.Union[float, int]`
104 | field31: typing.Union[float, typing.Union[int | int]]  # Error
    |                                                 ^^^
105 |
106 | # Should emit once, and fix to `typing.Union[float, int]`
    |
help: Remove duplicate union member `int`
    |
103 | # Should emit once, and fix to `typing.Union[float, int]`
    - field31: typing.Union[float, typing.Union[int | int]]  # Error
104 + field31: float | int  # Error
105 |
    |

PYI016 [*] Duplicate union member `int`
   --> PYI016.py:107:49
    |
106 | # Should emit once, and fix to `typing.Union[float, int]`
107 | field32: typing.Union[float, typing.Union[int | int | int]]  # Error
    |                                                 ^^^
108 |
109 | # Test case for mixed union type fix
    |
help: Remove duplicate union member `int`
    |
106 | # Should emit once, and fix to `typing.Union[float, int]`
    - field32: typing.Union[float, typing.Union[int | int | int]]  # Error
107 + field32: float | int  # Error
108 |
    |

PYI016 [*] Duplicate union member `int`
   --> PYI016.py:107:55
    |
106 | # Should emit once, and fix to `typing.Union[float, int]`
107 | field32: typing.Union[float, typing.Union[int | int | int]]  # Error
    |                                                       ^^^
108 |
109 | # Test case for mixed union type fix
    |
help: Remove duplicate union member `int`
    |
106 | # Should emit once, and fix to `typing.Union[float, int]`
    - field32: typing.Union[float, typing.Union[int | int | int]]  # Error
107 + field32: float | int  # Error
108 |
    |

PYI016 [*] Duplicate union member `int`
   --> PYI016.py:110:42
    |
109 | # Test case for mixed union type fix
110 | field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error
    |                                          ^^^
111 |
112 | # Test case for mixed union type
    |
help: Remove duplicate union member `int`
    |
109 | # Test case for mixed union type fix
    - field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error
110 + field33: int # Error
111 |
    |

PYI016 [*] Duplicate union member `int`
   --> PYI016.py:110:62
    |
109 | # Test case for mixed union type fix
110 | field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error
    |                                                              ^^^
111 |
112 | # Test case for mixed union type
    |
help: Remove duplicate union member `int`
    |
109 | # Test case for mixed union type fix
    - field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error
110 + field33: int # Error
111 |
    |

PYI016 [*] Duplicate union member `int`
   --> PYI016.py:110:68
    |
109 | # Test case for mixed union type fix
110 | field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error
    |                                                                    ^^^
111 |
112 | # Test case for mixed union type
    |
help: Remove duplicate union member `int`
    |
109 | # Test case for mixed union type fix
    - field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error
110 + field33: int # Error
111 |
    |

PYI016 [*] Duplicate union member `list[int]`
   --> PYI016.py:113:61
    |
112 | # Test case for mixed union type
113 | field34: typing.Union[list[int], str] | typing.Union[bytes, list[int]]  # Error
    |                                                             ^^^^^^^^^
114 |
115 | field35: "int | str | int"  # Error
    |
help: Remove duplicate union member `list[int]`
    |
112 | # Test case for mixed union type
    - field34: typing.Union[list[int], str] | typing.Union[bytes, list[int]]  # Error
113 + field34: typing.Union[list[int], str, bytes]  # Error
114 |
    |

PYI016 [*] Duplicate union member `int`
   --> PYI016.py:115:23
    |
113 | field34: typing.Union[list[int], str] | typing.Union[bytes, list[int]]  # Error
114 |
115 | field35: "int | str | int"  # Error
    |                       ^^^
    |
help: Remove duplicate union member `int`
    |
114 |
    - field35: "int | str | int"  # Error
115 + field35: "int | str"  # Error
116 |
    |

PYI016 [*] Duplicate union member `None`
   --> PYI016.py:130:26
    |
128 | field38: typing.Union[int, None]
129 | # equivalent to None
130 | field39: typing.Optional[None]
    |                          ^^^^
131 | # equivalent to int | None
132 | field40: typing.Union[typing.Optional[int], None]
    |
help: Remove duplicate union member `None`
    |
129 | # equivalent to None
    - field39: typing.Optional[None]
130 + field39: None
131 | # equivalent to int | None
    |

PYI016 [*] Duplicate union member `None`
   --> PYI016.py:132:45
    |
130 | field39: typing.Optional[None]
131 | # equivalent to int | None
132 | field40: typing.Union[typing.Optional[int], None]
    |                                             ^^^^
133 | field41: typing.Optional[typing.Union[int, None]]
134 | field42: typing.Union[typing.Optional[int], typing.Optional[int]]
    |
help: Remove duplicate union member `None`
    |
131 | # equivalent to int | None
    - field40: typing.Union[typing.Optional[int], None]
132 + field40: typing.Union[None, int]
133 | field41: typing.Optional[typing.Union[int, None]]
    |

PYI016 [*] Duplicate union member `None`
   --> PYI016.py:133:44
    |
131 | # equivalent to int | None
132 | field40: typing.Union[typing.Optional[int], None]
133 | field41: typing.Optional[typing.Union[int, None]]
    |                                            ^^^^
134 | field42: typing.Union[typing.Optional[int], typing.Optional[int]]
135 | field43: typing.Optional[int] | None
    |
help: Remove duplicate union member `None`
    |
132 | field40: typing.Union[typing.Optional[int], None]
    - field41: typing.Optional[typing.Union[int, None]]
133 + field41: typing.Union[None, int]
134 | field42: typing.Union[typing.Optional[int], typing.Optional[int]]
    |

PYI016 [*] Duplicate union member `None`
   --> PYI016.py:134:45
    |
132 | field40: typing.Union[typing.Optional[int], None]
133 | field41: typing.Optional[typing.Union[int, None]]
134 | field42: typing.Union[typing.Optional[int], typing.Optional[int]]
    |                                             ^^^^^^^^^^^^^^^
135 | field43: typing.Optional[int] | None
136 | field44: typing.Optional[int | None]
    |
help: Remove duplicate union member `None`
    |
133 | field41: typing.Optional[typing.Union[int, None]]
    - field42: typing.Union[typing.Optional[int], typing.Optional[int]]
134 + field42: typing.Union[None, int]
135 | field43: typing.Optional[int] | None
    |

PYI016 [*] Duplicate union member `int`
   --> PYI016.py:134:61
    |
132 | field40: typing.Union[typing.Optional[int], None]
133 | field41: typing.Optional[typing.Union[int, None]]
134 | field42: typing.Union[typing.Optional[int], typing.Optional[int]]
    |                                                             ^^^
135 | field43: typing.Optional[int] | None
136 | field44: typing.Optional[int | None]
    |
help: Remove duplicate union member `int`
    |
133 | field41: typing.Optional[typing.Union[int, None]]
    - field42: typing.Union[typing.Optional[int], typing.Optional[int]]
134 + field42: typing.Union[None, int]
135 | field43: typing.Optional[int] | None
    |

PYI016 [*] Duplicate union member `None`
   --> PYI016.py:135:33
    |
133 | field41: typing.Optional[typing.Union[int, None]]
134 | field42: typing.Union[typing.Optional[int], typing.Optional[int]]
135 | field43: typing.Optional[int] | None
    |                                 ^^^^
136 | field44: typing.Optional[int | None]
137 | field45: typing.Optional[int] | typing.Optional[int]
    |
help: Remove duplicate union member `None`
    |
134 | field42: typing.Union[typing.Optional[int], typing.Optional[int]]
    - field43: typing.Optional[int] | None
135 + field43: None | int
136 | field44: typing.Optional[int | None]
    |

PYI016 [*] Duplicate union member `None`
   --> PYI016.py:136:32
    |
134 | field42: typing.Union[typing.Optional[int], typing.Optional[int]]
135 | field43: typing.Optional[int] | None
136 | field44: typing.Optional[int | None]
    |                                ^^^^
137 | field45: typing.Optional[int] | typing.Optional[int]
138 | # equivalent to int | dict | None
    |
help: Remove duplicate union member `None`
    |
135 | field43: typing.Optional[int] | None
    - field44: typing.Optional[int | None]
136 + field44: None | int
137 | field45: typing.Optional[int] | typing.Optional[int]
    |

PYI016 [*] Duplicate union member `None`
   --> PYI016.py:137:33
    |
135 | field43: typing.Optional[int] | None
136 | field44: typing.Optional[int | None]
137 | field45: typing.Optional[int] | typing.Optional[int]
    |                                 ^^^^^^^^^^^^^^^
138 | # equivalent to int | dict | None
139 | field46: typing.Union[typing.Optional[int], typing.Optional[dict]]
    |
help: Remove duplicate union member `None`
    |
136 | field44: typing.Optional[int | None]
    - field45: typing.Optional[int] | typing.Optional[int]
137 + field45: typing.Union[None, int]
138 | # equivalent to int | dict | None
    |

PYI016 [*] Duplicate union member `int`
   --> PYI016.py:137:49
    |
135 | field43: typing.Optional[int] | None
136 | field44: typing.Optional[int | None]
137 | field45: typing.Optional[int] | typing.Optional[int]
    |                                                 ^^^
138 | # equivalent to int | dict | None
139 | field46: typing.Union[typing.Optional[int], typing.Optional[dict]]
    |
help: Remove duplicate union member `int`
    |
136 | field44: typing.Optional[int | None]
    - field45: typing.Optional[int] | typing.Optional[int]
137 + field45: typing.Union[None, int]
138 | # equivalent to int | dict | None
    |

PYI016 [*] Duplicate union member `None`
   --> PYI016.py:139:45
    |
137 | field45: typing.Optional[int] | typing.Optional[int]
138 | # equivalent to int | dict | None
139 | field46: typing.Union[typing.Optional[int], typing.Optional[dict]]
    |                                             ^^^^^^^^^^^^^^^
140 | field47: typing.Optional[int] | typing.Optional[dict]
    |
help: Remove duplicate union member `None`
    |
138 | # equivalent to int | dict | None
    - field46: typing.Union[typing.Optional[int], typing.Optional[dict]]
139 + field46: typing.Union[None, int, dict]
140 | field47: typing.Optional[int] | typing.Optional[dict]
    |

PYI016 [*] Duplicate union member `None`
   --> PYI016.py:140:33
    |
138 | # equivalent to int | dict | None
139 | field46: typing.Union[typing.Optional[int], typing.Optional[dict]]
140 | field47: typing.Optional[int] | typing.Optional[dict]
    |                                 ^^^^^^^^^^^^^^^
141 |
142 | # avoid reporting twice
    |
help: Remove duplicate union member `None`
    |
139 | field46: typing.Union[typing.Optional[int], typing.Optional[dict]]
    - field47: typing.Optional[int] | typing.Optional[dict]
140 + field47: typing.Union[None, int, dict]
141 |
    |

PYI016 [*] Duplicate union member `complex`
   --> PYI016.py:143:61
    |
142 | # avoid reporting twice
143 | field48: typing.Union[typing.Optional[typing.Union[complex, complex]], complex]
    |                                                             ^^^^^^^
144 | field49: typing.Optional[complex | complex] | complex
    |
help: Remove duplicate union member `complex`
    |
142 | # avoid reporting twice
    - field48: typing.Union[typing.Optional[typing.Union[complex, complex]], complex]
143 + field48: typing.Union[None, complex]
144 | field49: typing.Optional[complex | complex] | complex
    |

PYI016 [*] Duplicate union member `complex`
   --> PYI016.py:143:72
    |
142 | # avoid reporting twice
143 | field48: typing.Union[typing.Optional[typing.Union[complex, complex]], complex]
    |                                                                        ^^^^^^^
144 | field49: typing.Optional[complex | complex] | complex
    |
help: Remove duplicate union member `complex`
    |
142 | # avoid reporting twice
    - field48: typing.Union[typing.Optional[typing.Union[complex, complex]], complex]
143 + field48: typing.Union[None, complex]
144 | field49: typing.Optional[complex | complex] | complex
    |

PYI016 [*] Duplicate union member `complex`
   --> PYI016.py:144:36
    |
142 | # avoid reporting twice
143 | field48: typing.Union[typing.Optional[typing.Union[complex, complex]], complex]
144 | field49: typing.Optional[complex | complex] | complex
    |                                    ^^^^^^^
145 |
146 | # Regression test for https://github.com/astral-sh/ruff/issues/19403
    |
help: Remove duplicate union member `complex`
    |
143 | field48: typing.Union[typing.Optional[typing.Union[complex, complex]], complex]
    - field49: typing.Optional[complex | complex] | complex
144 + field49: None | complex
145 |
    |

PYI016 [*] Duplicate union member `complex`
   --> PYI016.py:144:47
    |
142 | # avoid reporting twice
143 | field48: typing.Union[typing.Optional[typing.Union[complex, complex]], complex]
144 | field49: typing.Optional[complex | complex] | complex
    |                                               ^^^^^^^
145 |
146 | # Regression test for https://github.com/astral-sh/ruff/issues/19403
    |
help: Remove duplicate union member `complex`
    |
143 | field48: typing.Union[typing.Optional[typing.Union[complex, complex]], complex]
    - field49: typing.Optional[complex | complex] | complex
144 + field49: None | complex
145 |
    |

PYI016 Duplicate union member `None`
   --> PYI016.py:148:37
    |
146 | # Regression test for https://github.com/astral-sh/ruff/issues/19403
147 | # Should throw duplicate union member but not fix
148 | isinstance(None, typing.Union[None, None])
    |                                     ^^^^
149 |
150 | # Regression test for https://github.com/astral-sh/ruff/issues/19914
    |
help: Remove duplicate union member `None`

PYI016 [*] Duplicate union member `typing.Literal[f"{x=}"]`
   --> PYI016.py:154:36
    |
152 | field50: typing.Literal[f"{00=}"] | typing.Literal[f"{000=}"]  # OK (f"{00=}" -> "00=0", f"{000=}" -> "000=0")
153 | field51: typing.Literal[f"{x=}"] | typing.Literal[f"{x}"]  # OK (f"{x=}" -> "x=1", f"{x}" -> "1")
154 | field52: typing.Literal[f"{x=}"] | typing.Literal[f"{x=}"]  # Error (true duplicate)
    |                                    ^^^^^^^^^^^^^^^^^^^^^^^
155 | field53: typing.Literal[f"{x:.2f}"] | typing.Literal[f"{x:.3f}"]  # OK (different format specs)
156 | field54: typing.Literal[f"{x}"] | typing.Literal[f"{x}"]  # Error (true duplicate)
    |
help: Remove duplicate union member `typing.Literal[f"{x=}"]`
    |
153 | field51: typing.Literal[f"{x=}"] | typing.Literal[f"{x}"]  # OK (f"{x=}" -> "x=1", f"{x}" -> "1")
    - field52: typing.Literal[f"{x=}"] | typing.Literal[f"{x=}"]  # Error (true duplicate)
154 + field52: typing.Literal[f"{x=}"]  # Error (true duplicate)
155 | field53: typing.Literal[f"{x:.2f}"] | typing.Literal[f"{x:.3f}"]  # OK (different format specs)
    |

PYI016 [*] Duplicate union member `typing.Literal[f"{x}"]`
   --> PYI016.py:156:35
    |
154 | field52: typing.Literal[f"{x=}"] | typing.Literal[f"{x=}"]  # Error (true duplicate)
155 | field53: typing.Literal[f"{x:.2f}"] | typing.Literal[f"{x:.3f}"]  # OK (different format specs)
156 | field54: typing.Literal[f"{x}"] | typing.Literal[f"{x}"]  # Error (true duplicate)
    |                                   ^^^^^^^^^^^^^^^^^^^^^^
157 | field55: typing.Literal[f"{x =}"] | typing.Literal[f"{x=}"]  # OK (different debug text due to spaces)
158 | field56: typing.Literal[f"{0x0=}"] | typing.Literal[f"{0o0=}"]  # OK (different source text: "0x0" vs "0o0")
    |
help: Remove duplicate union member `typing.Literal[f"{x}"]`
    |
155 | field53: typing.Literal[f"{x:.2f}"] | typing.Literal[f"{x:.3f}"]  # OK (different format specs)
    - field54: typing.Literal[f"{x}"] | typing.Literal[f"{x}"]  # Error (true duplicate)
156 + field54: typing.Literal[f"{x}"]  # Error (true duplicate)
157 | field55: typing.Literal[f"{x =}"] | typing.Literal[f"{x=}"]  # OK (different debug text due to spaces)
    |
