mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-28 04:45:01 +00:00
[flake8-pyi
, ruff
] Fix traversal of nested literals and unions (PYI016
, PYI051
, PYI055
, PYI062
, RUF041
) (#14641)
This commit is contained in:
parent
d9cbf2fe44
commit
dc29f52750
16 changed files with 318 additions and 169 deletions
|
@ -108,3 +108,6 @@ field32: typing.Union[float, typing.Union[int | int | int]] # Error
|
||||||
|
|
||||||
# Test case for mixed union type fix
|
# Test case for mixed union type fix
|
||||||
field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error
|
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
|
||||||
|
|
|
@ -107,4 +107,7 @@ field31: typing.Union[float, typing.Union[int | int]] # Error
|
||||||
field32: typing.Union[float, typing.Union[int | int | int]] # Error
|
field32: typing.Union[float, typing.Union[int | int | int]] # Error
|
||||||
|
|
||||||
# Test case for mixed union type fix
|
# Test case for mixed union type fix
|
||||||
field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error
|
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
|
||||||
|
|
|
@ -330,6 +330,16 @@ PYI016.py:89:41: PYI016 Duplicate union member `int`
|
||||||
|
|
|
|
||||||
= help: Remove duplicate union member `int`
|
= help: Remove 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`
|
||||||
|
| ^^^ PYI016
|
||||||
|
93 |
|
||||||
|
94 | # Should emit in cases with mixed `typing.Union` and `|`
|
||||||
|
|
|
||||||
|
= help: Remove duplicate union member `int`
|
||||||
|
|
||||||
PYI016.py:95:29: PYI016 Duplicate union member `int`
|
PYI016.py:95:29: PYI016 Duplicate union member `int`
|
||||||
|
|
|
|
||||||
94 | # Should emit in cases with mixed `typing.Union` and `|`
|
94 | # Should emit in cases with mixed `typing.Union` and `|`
|
||||||
|
@ -340,6 +350,16 @@ PYI016.py:95:29: PYI016 Duplicate union member `int`
|
||||||
|
|
|
|
||||||
= help: Remove duplicate union member `int`
|
= help: Remove duplicate union member `int`
|
||||||
|
|
||||||
|
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
|
||||||
|
| ^^^ PYI016
|
||||||
|
99 |
|
||||||
|
100 | # Should emit once in cases with multiple nested `typing.Union`
|
||||||
|
|
|
||||||
|
= help: Remove duplicate union member `int`
|
||||||
|
|
||||||
PYI016.py:98:59: PYI016 Duplicate union member `int`
|
PYI016.py:98:59: PYI016 Duplicate union member `int`
|
||||||
|
|
|
|
||||||
97 | # Should emit twice in cases with multiple nested `typing.Union`
|
97 | # Should emit twice in cases with multiple nested `typing.Union`
|
||||||
|
@ -350,6 +370,16 @@ PYI016.py:98:59: PYI016 Duplicate union member `int`
|
||||||
|
|
|
|
||||||
= help: Remove duplicate union member `int`
|
= help: Remove duplicate union member `int`
|
||||||
|
|
||||||
|
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
|
||||||
|
| ^^^ PYI016
|
||||||
|
102 |
|
||||||
|
103 | # Should emit once, and fix to `typing.Union[float, int]`
|
||||||
|
|
|
||||||
|
= help: Remove duplicate union member `int`
|
||||||
|
|
||||||
PYI016.py:104:49: PYI016 Duplicate union member `int`
|
PYI016.py:104:49: PYI016 Duplicate union member `int`
|
||||||
|
|
|
|
||||||
103 | # Should emit once, and fix to `typing.Union[float, int]`
|
103 | # Should emit once, and fix to `typing.Union[float, int]`
|
||||||
|
@ -385,21 +415,35 @@ PYI016.py:110:42: PYI016 Duplicate union member `int`
|
||||||
109 | # Test case for mixed union type fix
|
109 | # Test case for mixed union type fix
|
||||||
110 | field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error
|
110 | field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error
|
||||||
| ^^^ PYI016
|
| ^^^ PYI016
|
||||||
|
111 |
|
||||||
|
112 | # Test case for mixed union type
|
||||||
|
|
|
|
||||||
= help: Remove duplicate union member `int`
|
= help: Remove duplicate union member `int`
|
||||||
|
|
||||||
PYI016.py:110:49: PYI016 Duplicate union member `typing.Union[int | int]`
|
PYI016.py:110:62: PYI016 Duplicate union member `int`
|
||||||
|
|
|
|
||||||
109 | # Test case for mixed union type fix
|
109 | # Test case for mixed union type fix
|
||||||
110 | field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error
|
110 | field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ PYI016
|
| ^^^ PYI016
|
||||||
|
111 |
|
||||||
|
112 | # Test case for mixed union type
|
||||||
|
|
|
|
||||||
= help: Remove duplicate union member `typing.Union[int | int]`
|
= help: Remove duplicate union member `int`
|
||||||
|
|
||||||
PYI016.py:110:68: PYI016 Duplicate union member `int`
|
PYI016.py:110:68: PYI016 Duplicate union member `int`
|
||||||
|
|
|
|
||||||
109 | # Test case for mixed union type fix
|
109 | # Test case for mixed union type fix
|
||||||
110 | field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error
|
110 | field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error
|
||||||
| ^^^ PYI016
|
| ^^^ PYI016
|
||||||
|
111 |
|
||||||
|
112 | # Test case for mixed union type
|
||||||
|
|
|
|
||||||
= help: Remove duplicate union member `int`
|
= help: Remove duplicate union member `int`
|
||||||
|
|
||||||
|
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
|
||||||
|
|
|
||||||
|
= help: Remove duplicate union member `list[int]`
|
||||||
|
|
|
@ -330,6 +330,16 @@ PYI016.pyi:89:41: PYI016 Duplicate union member `int`
|
||||||
|
|
|
|
||||||
= help: Remove duplicate union member `int`
|
= help: Remove 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`
|
||||||
|
| ^^^ PYI016
|
||||||
|
93 |
|
||||||
|
94 | # Should emit in cases with mixed `typing.Union` and `|`
|
||||||
|
|
|
||||||
|
= help: Remove duplicate union member `int`
|
||||||
|
|
||||||
PYI016.pyi:95:29: PYI016 Duplicate union member `int`
|
PYI016.pyi:95:29: PYI016 Duplicate union member `int`
|
||||||
|
|
|
|
||||||
94 | # Should emit in cases with mixed `typing.Union` and `|`
|
94 | # Should emit in cases with mixed `typing.Union` and `|`
|
||||||
|
@ -340,6 +350,16 @@ PYI016.pyi:95:29: PYI016 Duplicate union member `int`
|
||||||
|
|
|
|
||||||
= help: Remove duplicate union member `int`
|
= help: Remove duplicate union member `int`
|
||||||
|
|
||||||
|
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
|
||||||
|
| ^^^ PYI016
|
||||||
|
99 |
|
||||||
|
100 | # Should emit once in cases with multiple nested `typing.Union`
|
||||||
|
|
|
||||||
|
= help: Remove duplicate union member `int`
|
||||||
|
|
||||||
PYI016.pyi:98:59: PYI016 Duplicate union member `int`
|
PYI016.pyi:98:59: PYI016 Duplicate union member `int`
|
||||||
|
|
|
|
||||||
97 | # Should emit twice in cases with multiple nested `typing.Union`
|
97 | # Should emit twice in cases with multiple nested `typing.Union`
|
||||||
|
@ -350,6 +370,16 @@ PYI016.pyi:98:59: PYI016 Duplicate union member `int`
|
||||||
|
|
|
|
||||||
= help: Remove duplicate union member `int`
|
= help: Remove duplicate union member `int`
|
||||||
|
|
||||||
|
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
|
||||||
|
| ^^^ PYI016
|
||||||
|
102 |
|
||||||
|
103 | # Should emit once, and fix to `typing.Union[float, int]`
|
||||||
|
|
|
||||||
|
= help: Remove duplicate union member `int`
|
||||||
|
|
||||||
PYI016.pyi:104:49: PYI016 Duplicate union member `int`
|
PYI016.pyi:104:49: PYI016 Duplicate union member `int`
|
||||||
|
|
|
|
||||||
103 | # Should emit once, and fix to `typing.Union[float, int]`
|
103 | # Should emit once, and fix to `typing.Union[float, int]`
|
||||||
|
@ -385,21 +415,35 @@ PYI016.pyi:110:42: PYI016 Duplicate union member `int`
|
||||||
109 | # Test case for mixed union type fix
|
109 | # Test case for mixed union type fix
|
||||||
110 | field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error
|
110 | field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error
|
||||||
| ^^^ PYI016
|
| ^^^ PYI016
|
||||||
|
111 |
|
||||||
|
112 | # Test case for mixed union type
|
||||||
|
|
|
|
||||||
= help: Remove duplicate union member `int`
|
= help: Remove duplicate union member `int`
|
||||||
|
|
||||||
PYI016.pyi:110:49: PYI016 Duplicate union member `typing.Union[int | int]`
|
PYI016.pyi:110:62: PYI016 Duplicate union member `int`
|
||||||
|
|
|
|
||||||
109 | # Test case for mixed union type fix
|
109 | # Test case for mixed union type fix
|
||||||
110 | field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error
|
110 | field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ PYI016
|
| ^^^ PYI016
|
||||||
|
111 |
|
||||||
|
112 | # Test case for mixed union type
|
||||||
|
|
|
|
||||||
= help: Remove duplicate union member `typing.Union[int | int]`
|
= help: Remove duplicate union member `int`
|
||||||
|
|
||||||
PYI016.pyi:110:68: PYI016 Duplicate union member `int`
|
PYI016.pyi:110:68: PYI016 Duplicate union member `int`
|
||||||
|
|
|
|
||||||
109 | # Test case for mixed union type fix
|
109 | # Test case for mixed union type fix
|
||||||
110 | field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error
|
110 | field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error
|
||||||
| ^^^ PYI016
|
| ^^^ PYI016
|
||||||
|
111 |
|
||||||
|
112 | # Test case for mixed union type
|
||||||
|
|
|
|
||||||
= help: Remove duplicate union member `int`
|
= help: Remove duplicate union member `int`
|
||||||
|
|
||||||
|
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]`
|
||||||
|
|
|
@ -25,6 +25,14 @@ PYI041.py:30:28: PYI041 Use `float` instead of `int | float`
|
||||||
|
|
|
|
||||||
= help: Remove redundant type
|
= help: Remove redundant type
|
||||||
|
|
||||||
|
PYI041.py:34:26: PYI041 Use `float` instead of `int | float`
|
||||||
|
|
|
||||||
|
34 | def f3(arg1: int, *args: Union[int | int | float]) -> None:
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^ PYI041
|
||||||
|
35 | ...
|
||||||
|
|
|
||||||
|
= help: Remove redundant type
|
||||||
|
|
||||||
PYI041.py:38:24: PYI041 Use `float` instead of `int | float`
|
PYI041.py:38:24: PYI041 Use `float` instead of `int | float`
|
||||||
|
|
|
|
||||||
38 | async def f4(**kwargs: int | int | float) -> None:
|
38 | async def f4(**kwargs: int | int | float) -> None:
|
||||||
|
@ -41,6 +49,30 @@ PYI041.py:42:26: PYI041 Use `float` instead of `int | float`
|
||||||
|
|
|
|
||||||
= help: Remove redundant type
|
= help: Remove redundant type
|
||||||
|
|
||||||
|
PYI041.py:46:26: PYI041 Use `float` instead of `int | float`
|
||||||
|
|
|
||||||
|
46 | def f6(arg1: int, *args: Union[Union[int, int, float]]) -> None:
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI041
|
||||||
|
47 | ...
|
||||||
|
|
|
||||||
|
= help: Remove redundant type
|
||||||
|
|
||||||
|
PYI041.py:50:26: PYI041 Use `float` instead of `int | float`
|
||||||
|
|
|
||||||
|
50 | def f7(arg1: int, *args: Union[Union[Union[int, int, float]]]) -> None:
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI041
|
||||||
|
51 | ...
|
||||||
|
|
|
||||||
|
= help: Remove redundant type
|
||||||
|
|
||||||
|
PYI041.py:54:26: PYI041 Use `float` instead of `int | float`
|
||||||
|
|
|
||||||
|
54 | def f8(arg1: int, *args: Union[Union[Union[int | int | float]]]) -> None:
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI041
|
||||||
|
55 | ...
|
||||||
|
|
|
||||||
|
= help: Remove redundant type
|
||||||
|
|
||||||
PYI041.py:59:10: PYI041 Use `complex` instead of `int | float | complex`
|
PYI041.py:59:10: PYI041 Use `complex` instead of `int | float | complex`
|
||||||
|
|
|
|
||||||
58 | def f9(
|
58 | def f9(
|
||||||
|
|
|
@ -22,6 +22,13 @@ PYI041.pyi:27:28: PYI041 Use `float` instead of `int | float`
|
||||||
|
|
|
|
||||||
= help: Remove redundant type
|
= help: Remove redundant type
|
||||||
|
|
||||||
|
PYI041.pyi:30:26: PYI041 Use `float` instead of `int | float`
|
||||||
|
|
|
||||||
|
30 | def f3(arg1: int, *args: Union[int | int | float]) -> None: ... # PYI041
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^ PYI041
|
||||||
|
|
|
||||||
|
= help: Remove redundant type
|
||||||
|
|
||||||
PYI041.pyi:33:24: PYI041 Use `float` instead of `int | float`
|
PYI041.pyi:33:24: PYI041 Use `float` instead of `int | float`
|
||||||
|
|
|
|
||||||
33 | async def f4(**kwargs: int | int | float) -> None: ... # PYI041
|
33 | async def f4(**kwargs: int | int | float) -> None: ... # PYI041
|
||||||
|
@ -66,6 +73,27 @@ PYI041.pyi:49:26: PYI041 Use `float` instead of `int | float`
|
||||||
|
|
|
|
||||||
= help: Remove redundant type
|
= help: Remove redundant type
|
||||||
|
|
||||||
|
PYI041.pyi:52:26: PYI041 Use `float` instead of `int | float`
|
||||||
|
|
|
||||||
|
52 | def f6(arg1: int, *args: Union[Union[int, int, float]]) -> None: ... # PYI041
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI041
|
||||||
|
|
|
||||||
|
= help: Remove redundant type
|
||||||
|
|
||||||
|
PYI041.pyi:55:26: PYI041 Use `float` instead of `int | float`
|
||||||
|
|
|
||||||
|
55 | def f7(arg1: int, *args: Union[Union[Union[int, int, float]]]) -> None: ... # PYI041
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI041
|
||||||
|
|
|
||||||
|
= help: Remove redundant type
|
||||||
|
|
||||||
|
PYI041.pyi:58:26: PYI041 Use `float` instead of `int | float`
|
||||||
|
|
|
||||||
|
58 | def f8(arg1: int, *args: Union[Union[Union[int | int | float]]]) -> None: ... # PYI041
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI041
|
||||||
|
|
|
||||||
|
= help: Remove redundant type
|
||||||
|
|
||||||
PYI041.pyi:64:24: PYI041 Use `complex` instead of `int | float | complex`
|
PYI041.pyi:64:24: PYI041 Use `complex` instead of `int | float | complex`
|
||||||
|
|
|
|
||||||
62 | def good(self, arg: int) -> None: ...
|
62 | def good(self, arg: int) -> None: ...
|
||||||
|
|
|
@ -70,6 +70,35 @@ PYI051.py:7:51: PYI051 `Literal[42]` is redundant in a union with `int`
|
||||||
9 | F: TypeAlias = typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
|
9 | F: TypeAlias = typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
|
||||||
|
|
|
|
||||||
|
|
||||||
|
PYI051.py:8:76: PYI051 `Literal["foo"]` is redundant in a union with `str`
|
||||||
|
|
|
||||||
|
6 | C: TypeAlias = typing.Union[Literal[5], int, typing.Union[Literal["foo"], str]]
|
||||||
|
7 | D: TypeAlias = typing.Union[Literal[b"str_bytes", 42], bytes, int]
|
||||||
|
8 | E: TypeAlias = typing.Union[typing.Union[typing.Union[typing.Union[Literal["foo"], str]]]]
|
||||||
|
| ^^^^^ PYI051
|
||||||
|
9 | F: TypeAlias = typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
|
||||||
|
10 | G: typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
|
||||||
|
|
|
||||||
|
|
||||||
|
PYI051.py:9:81: PYI051 `Literal["foo"]` is redundant in a union with `str`
|
||||||
|
|
|
||||||
|
7 | D: TypeAlias = typing.Union[Literal[b"str_bytes", 42], bytes, int]
|
||||||
|
8 | E: TypeAlias = typing.Union[typing.Union[typing.Union[typing.Union[Literal["foo"], str]]]]
|
||||||
|
9 | F: TypeAlias = typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
|
||||||
|
| ^^^^^ PYI051
|
||||||
|
10 | G: typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
|
||||||
|
|
|
||||||
|
|
||||||
|
PYI051.py:10:69: PYI051 `Literal["foo"]` is redundant in a union with `str`
|
||||||
|
|
|
||||||
|
8 | E: TypeAlias = typing.Union[typing.Union[typing.Union[typing.Union[Literal["foo"], str]]]]
|
||||||
|
9 | F: TypeAlias = typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
|
||||||
|
10 | G: typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
|
||||||
|
| ^^^^^ PYI051
|
||||||
|
11 |
|
||||||
|
12 | def func(x: complex | Literal[1J], y: Union[Literal[3.14], float]): ...
|
||||||
|
|
|
||||||
|
|
||||||
PYI051.py:12:31: PYI051 `Literal[1J]` is redundant in a union with `complex`
|
PYI051.py:12:31: PYI051 `Literal[1J]` is redundant in a union with `complex`
|
||||||
|
|
|
|
||||||
10 | G: typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
|
10 | G: typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
|
||||||
|
|
|
@ -70,6 +70,35 @@ PYI051.pyi:7:51: PYI051 `Literal[42]` is redundant in a union with `int`
|
||||||
9 | F: TypeAlias = typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
|
9 | F: TypeAlias = typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
|
||||||
|
|
|
|
||||||
|
|
||||||
|
PYI051.pyi:8:76: PYI051 `Literal["foo"]` is redundant in a union with `str`
|
||||||
|
|
|
||||||
|
6 | C: TypeAlias = typing.Union[Literal[5], int, typing.Union[Literal["foo"], str]]
|
||||||
|
7 | D: TypeAlias = typing.Union[Literal[b"str_bytes", 42], bytes, int]
|
||||||
|
8 | E: TypeAlias = typing.Union[typing.Union[typing.Union[typing.Union[Literal["foo"], str]]]]
|
||||||
|
| ^^^^^ PYI051
|
||||||
|
9 | F: TypeAlias = typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
|
||||||
|
10 | G: typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
|
||||||
|
|
|
||||||
|
|
||||||
|
PYI051.pyi:9:81: PYI051 `Literal["foo"]` is redundant in a union with `str`
|
||||||
|
|
|
||||||
|
7 | D: TypeAlias = typing.Union[Literal[b"str_bytes", 42], bytes, int]
|
||||||
|
8 | E: TypeAlias = typing.Union[typing.Union[typing.Union[typing.Union[Literal["foo"], str]]]]
|
||||||
|
9 | F: TypeAlias = typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
|
||||||
|
| ^^^^^ PYI051
|
||||||
|
10 | G: typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
|
||||||
|
|
|
||||||
|
|
||||||
|
PYI051.pyi:10:69: PYI051 `Literal["foo"]` is redundant in a union with `str`
|
||||||
|
|
|
||||||
|
8 | E: TypeAlias = typing.Union[typing.Union[typing.Union[typing.Union[Literal["foo"], str]]]]
|
||||||
|
9 | F: TypeAlias = typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
|
||||||
|
10 | G: typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
|
||||||
|
| ^^^^^ PYI051
|
||||||
|
11 |
|
||||||
|
12 | def func(x: complex | Literal[1J], y: Union[Literal[3.14], float]): ...
|
||||||
|
|
|
||||||
|
|
||||||
PYI051.pyi:12:31: PYI051 `Literal[1J]` is redundant in a union with `complex`
|
PYI051.pyi:12:31: PYI051 `Literal[1J]` is redundant in a union with `complex`
|
||||||
|
|
|
|
||||||
10 | G: typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
|
10 | G: typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
|
||||||
|
|
|
@ -106,12 +106,12 @@ PYI055.py:50:9: PYI055 [*] Multiple `type` members in a union. Combine them into
|
||||||
52 52 | ...
|
52 52 | ...
|
||||||
53 53 |
|
53 53 |
|
||||||
|
|
||||||
PYI055.py:56:15: PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[_T | Converter[_T]]`.
|
PYI055.py:56:9: PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[_T | Converter[_T]]`.
|
||||||
|
|
|
|
||||||
54 | def convert_union(union: UnionType) -> _T | None:
|
54 | def convert_union(union: UnionType) -> _T | None:
|
||||||
55 | converters: tuple[
|
55 | converters: tuple[
|
||||||
56 | Union[type[_T] | type[Converter[_T]] | Converter[_T] | Callable[[str], _T]], ... # PYI055
|
56 | Union[type[_T] | type[Converter[_T]] | Converter[_T] | Callable[[str], _T]], ... # PYI055
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055
|
||||||
57 | ] = union.__args__
|
57 | ] = union.__args__
|
||||||
58 | ...
|
58 | ...
|
||||||
|
|
|
|
||||||
|
@ -122,17 +122,17 @@ PYI055.py:56:15: PYI055 [*] Multiple `type` members in a union. Combine them int
|
||||||
54 54 | def convert_union(union: UnionType) -> _T | None:
|
54 54 | def convert_union(union: UnionType) -> _T | None:
|
||||||
55 55 | converters: tuple[
|
55 55 | converters: tuple[
|
||||||
56 |- Union[type[_T] | type[Converter[_T]] | Converter[_T] | Callable[[str], _T]], ... # PYI055
|
56 |- Union[type[_T] | type[Converter[_T]] | Converter[_T] | Callable[[str], _T]], ... # PYI055
|
||||||
56 |+ Union[type[_T | Converter[_T]] | Converter[_T] | Callable[[str], _T]], ... # PYI055
|
56 |+ type[_T | Converter[_T]] | Converter[_T] | Callable[[str], _T], ... # PYI055
|
||||||
57 57 | ] = union.__args__
|
57 57 | ] = union.__args__
|
||||||
58 58 | ...
|
58 58 | ...
|
||||||
59 59 |
|
59 59 |
|
||||||
|
|
||||||
PYI055.py:62:15: PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[_T | Converter[_T]]`.
|
PYI055.py:62:9: PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[_T | Converter[_T]]`.
|
||||||
|
|
|
|
||||||
60 | def convert_union(union: UnionType) -> _T | None:
|
60 | def convert_union(union: UnionType) -> _T | None:
|
||||||
61 | converters: tuple[
|
61 | converters: tuple[
|
||||||
62 | Union[type[_T] | type[Converter[_T]]] | Converter[_T] | Callable[[str], _T], ... # PYI055
|
62 | Union[type[_T] | type[Converter[_T]]] | Converter[_T] | Callable[[str], _T], ... # PYI055
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055
|
||||||
63 | ] = union.__args__
|
63 | ] = union.__args__
|
||||||
64 | ...
|
64 | ...
|
||||||
|
|
|
|
||||||
|
@ -143,17 +143,17 @@ PYI055.py:62:15: PYI055 [*] Multiple `type` members in a union. Combine them int
|
||||||
60 60 | def convert_union(union: UnionType) -> _T | None:
|
60 60 | def convert_union(union: UnionType) -> _T | None:
|
||||||
61 61 | converters: tuple[
|
61 61 | converters: tuple[
|
||||||
62 |- Union[type[_T] | type[Converter[_T]]] | Converter[_T] | Callable[[str], _T], ... # PYI055
|
62 |- Union[type[_T] | type[Converter[_T]]] | Converter[_T] | Callable[[str], _T], ... # PYI055
|
||||||
62 |+ Union[type[_T | Converter[_T]]] | Converter[_T] | Callable[[str], _T], ... # PYI055
|
62 |+ type[_T | Converter[_T]] | Converter[_T] | Callable[[str], _T], ... # PYI055
|
||||||
63 63 | ] = union.__args__
|
63 63 | ] = union.__args__
|
||||||
64 64 | ...
|
64 64 | ...
|
||||||
65 65 |
|
65 65 |
|
||||||
|
|
||||||
PYI055.py:68:15: PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[_T | Converter[_T]]`.
|
PYI055.py:68:9: PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[_T | Converter[_T]]`.
|
||||||
|
|
|
|
||||||
66 | def convert_union(union: UnionType) -> _T | None:
|
66 | def convert_union(union: UnionType) -> _T | None:
|
||||||
67 | converters: tuple[
|
67 | converters: tuple[
|
||||||
68 | Union[type[_T] | type[Converter[_T]] | str] | Converter[_T] | Callable[[str], _T], ... # PYI055
|
68 | Union[type[_T] | type[Converter[_T]] | str] | Converter[_T] | Callable[[str], _T], ... # PYI055
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055
|
||||||
69 | ] = union.__args__
|
69 | ] = union.__args__
|
||||||
70 | ...
|
70 | ...
|
||||||
|
|
|
|
||||||
|
@ -164,6 +164,6 @@ PYI055.py:68:15: PYI055 [*] Multiple `type` members in a union. Combine them int
|
||||||
66 66 | def convert_union(union: UnionType) -> _T | None:
|
66 66 | def convert_union(union: UnionType) -> _T | None:
|
||||||
67 67 | converters: tuple[
|
67 67 | converters: tuple[
|
||||||
68 |- Union[type[_T] | type[Converter[_T]] | str] | Converter[_T] | Callable[[str], _T], ... # PYI055
|
68 |- Union[type[_T] | type[Converter[_T]] | str] | Converter[_T] | Callable[[str], _T], ... # PYI055
|
||||||
68 |+ Union[type[_T | Converter[_T]] | str] | Converter[_T] | Callable[[str], _T], ... # PYI055
|
68 |+ type[_T | Converter[_T]] | str | Converter[_T] | Callable[[str], _T], ... # PYI055
|
||||||
69 69 | ] = union.__args__
|
69 69 | ] = union.__args__
|
||||||
70 70 | ...
|
70 70 | ...
|
||||||
|
|
|
@ -105,12 +105,12 @@ PYI055.pyi:8:4: PYI055 [*] Multiple `type` members in a union. Combine them into
|
||||||
10 10 | y: Union[Union[Union[type[float, int], type[complex]]]]
|
10 10 | y: Union[Union[Union[type[float, int], type[complex]]]]
|
||||||
11 11 | z: Union[type[complex], Union[Union[type[float, int]]]]
|
11 11 | z: Union[type[complex], Union[Union[type[float, int]]]]
|
||||||
|
|
||||||
PYI055.pyi:9:10: PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[Union[float, int, complex]]`.
|
PYI055.pyi:9:4: PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[Union[float, int, complex]]`.
|
||||||
|
|
|
|
||||||
7 | v: Union[type[float], type[complex]]
|
7 | v: Union[type[float], type[complex]]
|
||||||
8 | w: Union[type[float, int], type[complex]]
|
8 | w: Union[type[float, int], type[complex]]
|
||||||
9 | x: Union[Union[type[float, int], type[complex]]]
|
9 | x: Union[Union[type[float, int], type[complex]]]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055
|
||||||
10 | y: Union[Union[Union[type[float, int], type[complex]]]]
|
10 | y: Union[Union[Union[type[float, int], type[complex]]]]
|
||||||
11 | z: Union[type[complex], Union[Union[type[float, int]]]]
|
11 | z: Union[type[complex], Union[Union[type[float, int]]]]
|
||||||
|
|
|
|
||||||
|
@ -121,11 +121,52 @@ PYI055.pyi:9:10: PYI055 [*] Multiple `type` members in a union. Combine them int
|
||||||
7 7 | v: Union[type[float], type[complex]]
|
7 7 | v: Union[type[float], type[complex]]
|
||||||
8 8 | w: Union[type[float, int], type[complex]]
|
8 8 | w: Union[type[float, int], type[complex]]
|
||||||
9 |-x: Union[Union[type[float, int], type[complex]]]
|
9 |-x: Union[Union[type[float, int], type[complex]]]
|
||||||
9 |+x: Union[type[Union[float, int, complex]]]
|
9 |+x: type[Union[float, int, complex]]
|
||||||
10 10 | y: Union[Union[Union[type[float, int], type[complex]]]]
|
10 10 | y: Union[Union[Union[type[float, int], type[complex]]]]
|
||||||
11 11 | z: Union[type[complex], Union[Union[type[float, int]]]]
|
11 11 | z: Union[type[complex], Union[Union[type[float, int]]]]
|
||||||
12 12 |
|
12 12 |
|
||||||
|
|
||||||
|
PYI055.pyi:10:4: PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[Union[float, int, complex]]`.
|
||||||
|
|
|
||||||
|
8 | w: Union[type[float, int], type[complex]]
|
||||||
|
9 | x: Union[Union[type[float, int], type[complex]]]
|
||||||
|
10 | y: Union[Union[Union[type[float, int], type[complex]]]]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055
|
||||||
|
11 | z: Union[type[complex], Union[Union[type[float, int]]]]
|
||||||
|
|
|
||||||
|
= help: Combine multiple `type` members
|
||||||
|
|
||||||
|
ℹ Safe fix
|
||||||
|
7 7 | v: Union[type[float], type[complex]]
|
||||||
|
8 8 | w: Union[type[float, int], type[complex]]
|
||||||
|
9 9 | x: Union[Union[type[float, int], type[complex]]]
|
||||||
|
10 |-y: Union[Union[Union[type[float, int], type[complex]]]]
|
||||||
|
10 |+y: type[Union[float, int, complex]]
|
||||||
|
11 11 | z: Union[type[complex], Union[Union[type[float, int]]]]
|
||||||
|
12 12 |
|
||||||
|
13 13 | def func(arg: type[int] | str | type[float]) -> None: ...
|
||||||
|
|
||||||
|
PYI055.pyi:11:4: PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[Union[complex, float, int]]`.
|
||||||
|
|
|
||||||
|
9 | x: Union[Union[type[float, int], type[complex]]]
|
||||||
|
10 | y: Union[Union[Union[type[float, int], type[complex]]]]
|
||||||
|
11 | z: Union[type[complex], Union[Union[type[float, int]]]]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055
|
||||||
|
12 |
|
||||||
|
13 | def func(arg: type[int] | str | type[float]) -> None: ...
|
||||||
|
|
|
||||||
|
= help: Combine multiple `type` members
|
||||||
|
|
||||||
|
ℹ Safe fix
|
||||||
|
8 8 | w: Union[type[float, int], type[complex]]
|
||||||
|
9 9 | x: Union[Union[type[float, int], type[complex]]]
|
||||||
|
10 10 | y: Union[Union[Union[type[float, int], type[complex]]]]
|
||||||
|
11 |-z: Union[type[complex], Union[Union[type[float, int]]]]
|
||||||
|
11 |+z: type[Union[complex, float, int]]
|
||||||
|
12 12 |
|
||||||
|
13 13 | def func(arg: type[int] | str | type[float]) -> None: ...
|
||||||
|
14 14 |
|
||||||
|
|
||||||
PYI055.pyi:13:15: PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[int | float]`.
|
PYI055.pyi:13:15: PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[int | float]`.
|
||||||
|
|
|
|
||||||
11 | z: Union[type[complex], Union[Union[type[float, int]]]]
|
11 | z: Union[type[complex], Union[Union[type[float, int]]]]
|
||||||
|
|
|
@ -318,24 +318,6 @@ PYI062.py:25:46: PYI062 [*] Duplicate literal member `True`
|
||||||
27 27 | n: Literal["No", "duplicates", "here", 1, "1"]
|
27 27 | n: Literal["No", "duplicates", "here", 1, "1"]
|
||||||
28 28 |
|
28 28 |
|
||||||
|
|
||||||
PYI062.py:32:37: PYI062 [*] Duplicate literal member `1`
|
|
||||||
|
|
|
||||||
30 | # nested literals, all equivalent to `Literal[1]`
|
|
||||||
31 | Literal[Literal[1]] # no duplicate
|
|
||||||
32 | Literal[Literal[Literal[1], Literal[1]]] # once
|
|
||||||
| ^ PYI062
|
|
||||||
33 | Literal[Literal[1], Literal[Literal[Literal[1]]]] # once
|
|
||||||
|
|
|
||||||
= help: Remove duplicates
|
|
||||||
|
|
||||||
ℹ Safe fix
|
|
||||||
29 29 |
|
|
||||||
30 30 | # nested literals, all equivalent to `Literal[1]`
|
|
||||||
31 31 | Literal[Literal[1]] # no duplicate
|
|
||||||
32 |-Literal[Literal[Literal[1], Literal[1]]] # once
|
|
||||||
32 |+Literal[Literal[1]] # once
|
|
||||||
33 33 | Literal[Literal[1], Literal[Literal[Literal[1]]]] # once
|
|
||||||
|
|
||||||
PYI062.py:32:37: PYI062 [*] Duplicate literal member `1`
|
PYI062.py:32:37: PYI062 [*] Duplicate literal member `1`
|
||||||
|
|
|
|
||||||
30 | # nested literals, all equivalent to `Literal[1]`
|
30 | # nested literals, all equivalent to `Literal[1]`
|
||||||
|
|
|
@ -318,24 +318,6 @@ PYI062.pyi:25:46: PYI062 [*] Duplicate literal member `True`
|
||||||
27 27 | n: Literal["No", "duplicates", "here", 1, "1"]
|
27 27 | n: Literal["No", "duplicates", "here", 1, "1"]
|
||||||
28 28 |
|
28 28 |
|
||||||
|
|
||||||
PYI062.pyi:32:37: PYI062 [*] Duplicate literal member `1`
|
|
||||||
|
|
|
||||||
30 | # nested literals, all equivalent to `Literal[1]`
|
|
||||||
31 | Literal[Literal[1]] # no duplicate
|
|
||||||
32 | Literal[Literal[Literal[1], Literal[1]]] # once
|
|
||||||
| ^ PYI062
|
|
||||||
33 | Literal[Literal[1], Literal[Literal[Literal[1]]]] # once
|
|
||||||
|
|
|
||||||
= help: Remove duplicates
|
|
||||||
|
|
||||||
ℹ Safe fix
|
|
||||||
29 29 |
|
|
||||||
30 30 | # nested literals, all equivalent to `Literal[1]`
|
|
||||||
31 31 | Literal[Literal[1]] # no duplicate
|
|
||||||
32 |-Literal[Literal[Literal[1], Literal[1]]] # once
|
|
||||||
32 |+Literal[Literal[1]] # once
|
|
||||||
33 33 | Literal[Literal[1], Literal[Literal[Literal[1]]]] # once
|
|
||||||
|
|
||||||
PYI062.pyi:32:37: PYI062 [*] Duplicate literal member `1`
|
PYI062.pyi:32:37: PYI062 [*] Duplicate literal member `1`
|
||||||
|
|
|
|
||||||
30 | # nested literals, all equivalent to `Literal[1]`
|
30 | # nested literals, all equivalent to `Literal[1]`
|
||||||
|
|
|
@ -216,26 +216,6 @@ RUF041.py:24:1: RUF041 [*] Unnecessary nested `Literal`
|
||||||
26 26 |
|
26 26 |
|
||||||
27 27 | # OK
|
27 27 | # OK
|
||||||
|
|
||||||
RUF041.py:24:9: RUF041 [*] Unnecessary nested `Literal`
|
|
||||||
|
|
|
||||||
22 | # nested literals, all equivalent to `Literal[1]`
|
|
||||||
23 | Literal[Literal[1]]
|
|
||||||
24 | Literal[Literal[Literal[1], Literal[1]]]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF041
|
|
||||||
25 | Literal[Literal[1], Literal[Literal[Literal[1]]]]
|
|
||||||
|
|
|
||||||
= help: Replace with flattened `Literal`
|
|
||||||
|
|
||||||
ℹ Safe fix
|
|
||||||
21 21 |
|
|
||||||
22 22 | # nested literals, all equivalent to `Literal[1]`
|
|
||||||
23 23 | Literal[Literal[1]]
|
|
||||||
24 |-Literal[Literal[Literal[1], Literal[1]]]
|
|
||||||
24 |+Literal[Literal[1, 1]]
|
|
||||||
25 25 | Literal[Literal[1], Literal[Literal[Literal[1]]]]
|
|
||||||
26 26 |
|
|
||||||
27 27 | # OK
|
|
||||||
|
|
||||||
RUF041.py:25:1: RUF041 [*] Unnecessary nested `Literal`
|
RUF041.py:25:1: RUF041 [*] Unnecessary nested `Literal`
|
||||||
|
|
|
|
||||||
23 | Literal[Literal[1]]
|
23 | Literal[Literal[1]]
|
||||||
|
@ -256,24 +236,3 @@ RUF041.py:25:1: RUF041 [*] Unnecessary nested `Literal`
|
||||||
26 26 |
|
26 26 |
|
||||||
27 27 | # OK
|
27 27 | # OK
|
||||||
28 28 | x: Literal[True, False, True, False]
|
28 28 | x: Literal[True, False, True, False]
|
||||||
|
|
||||||
RUF041.py:25:29: RUF041 [*] Unnecessary nested `Literal`
|
|
||||||
|
|
|
||||||
23 | Literal[Literal[1]]
|
|
||||||
24 | Literal[Literal[Literal[1], Literal[1]]]
|
|
||||||
25 | Literal[Literal[1], Literal[Literal[Literal[1]]]]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^ RUF041
|
|
||||||
26 |
|
|
||||||
27 | # OK
|
|
||||||
|
|
|
||||||
= help: Replace with flattened `Literal`
|
|
||||||
|
|
||||||
ℹ Safe fix
|
|
||||||
22 22 | # nested literals, all equivalent to `Literal[1]`
|
|
||||||
23 23 | Literal[Literal[1]]
|
|
||||||
24 24 | Literal[Literal[Literal[1], Literal[1]]]
|
|
||||||
25 |-Literal[Literal[1], Literal[Literal[Literal[1]]]]
|
|
||||||
25 |+Literal[Literal[1], Literal[Literal[1]]]
|
|
||||||
26 26 |
|
|
||||||
27 27 | # OK
|
|
||||||
28 28 | x: Literal[True, False, True, False]
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
---
|
---
|
||||||
source: crates/ruff_linter/src/rules/ruff/mod.rs
|
source: crates/ruff_linter/src/rules/ruff/mod.rs
|
||||||
snapshot_kind: text
|
|
||||||
---
|
---
|
||||||
RUF041.pyi:6:4: RUF041 [*] Unnecessary nested `Literal`
|
RUF041.pyi:6:4: RUF041 [*] Unnecessary nested `Literal`
|
||||||
|
|
|
|
||||||
|
@ -216,26 +215,6 @@ RUF041.pyi:24:1: RUF041 [*] Unnecessary nested `Literal`
|
||||||
26 26 |
|
26 26 |
|
||||||
27 27 | # OK
|
27 27 | # OK
|
||||||
|
|
||||||
RUF041.pyi:24:9: RUF041 [*] Unnecessary nested `Literal`
|
|
||||||
|
|
|
||||||
22 | # nested literals, all equivalent to `Literal[1]`
|
|
||||||
23 | Literal[Literal[1]]
|
|
||||||
24 | Literal[Literal[Literal[1], Literal[1]]]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF041
|
|
||||||
25 | Literal[Literal[1], Literal[Literal[Literal[1]]]]
|
|
||||||
|
|
|
||||||
= help: Replace with flattened `Literal`
|
|
||||||
|
|
||||||
ℹ Safe fix
|
|
||||||
21 21 |
|
|
||||||
22 22 | # nested literals, all equivalent to `Literal[1]`
|
|
||||||
23 23 | Literal[Literal[1]]
|
|
||||||
24 |-Literal[Literal[Literal[1], Literal[1]]]
|
|
||||||
24 |+Literal[Literal[1, 1]]
|
|
||||||
25 25 | Literal[Literal[1], Literal[Literal[Literal[1]]]]
|
|
||||||
26 26 |
|
|
||||||
27 27 | # OK
|
|
||||||
|
|
||||||
RUF041.pyi:25:1: RUF041 [*] Unnecessary nested `Literal`
|
RUF041.pyi:25:1: RUF041 [*] Unnecessary nested `Literal`
|
||||||
|
|
|
|
||||||
23 | Literal[Literal[1]]
|
23 | Literal[Literal[1]]
|
||||||
|
@ -256,24 +235,3 @@ RUF041.pyi:25:1: RUF041 [*] Unnecessary nested `Literal`
|
||||||
26 26 |
|
26 26 |
|
||||||
27 27 | # OK
|
27 27 | # OK
|
||||||
28 28 | x: Literal[True, False, True, False]
|
28 28 | x: Literal[True, False, True, False]
|
||||||
|
|
||||||
RUF041.pyi:25:29: RUF041 [*] Unnecessary nested `Literal`
|
|
||||||
|
|
|
||||||
23 | Literal[Literal[1]]
|
|
||||||
24 | Literal[Literal[Literal[1], Literal[1]]]
|
|
||||||
25 | Literal[Literal[1], Literal[Literal[Literal[1]]]]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^ RUF041
|
|
||||||
26 |
|
|
||||||
27 | # OK
|
|
||||||
|
|
|
||||||
= help: Replace with flattened `Literal`
|
|
||||||
|
|
||||||
ℹ Safe fix
|
|
||||||
22 22 | # nested literals, all equivalent to `Literal[1]`
|
|
||||||
23 23 | Literal[Literal[1]]
|
|
||||||
24 24 | Literal[Literal[Literal[1], Literal[1]]]
|
|
||||||
25 |-Literal[Literal[1], Literal[Literal[Literal[1]]]]
|
|
||||||
25 |+Literal[Literal[1], Literal[Literal[1]]]
|
|
||||||
26 26 |
|
|
||||||
27 27 | # OK
|
|
||||||
28 28 | x: Literal[True, False, True, False]
|
|
||||||
|
|
|
@ -373,7 +373,7 @@ where
|
||||||
) where
|
) where
|
||||||
F: FnMut(&'a Expr, &'a Expr),
|
F: FnMut(&'a Expr, &'a Expr),
|
||||||
{
|
{
|
||||||
// Ex) x | y
|
// Ex) `x | y`
|
||||||
if let Expr::BinOp(ast::ExprBinOp {
|
if let Expr::BinOp(ast::ExprBinOp {
|
||||||
op: Operator::BitOr,
|
op: Operator::BitOr,
|
||||||
left,
|
left,
|
||||||
|
@ -396,17 +396,21 @@ where
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ex) Union[x, y]
|
// Ex) `Union[x, y]`
|
||||||
if let Expr::Subscript(ast::ExprSubscript { value, slice, .. }) = expr {
|
if let Expr::Subscript(ast::ExprSubscript { value, slice, .. }) = expr {
|
||||||
if semantic.match_typing_expr(value, "Union") {
|
if semantic.match_typing_expr(value, "Union") {
|
||||||
if let Expr::Tuple(tuple) = &**slice {
|
if let Expr::Tuple(tuple) = &**slice {
|
||||||
// Traverse each element of the tuple within the union recursively to handle cases
|
// Traverse each element of the tuple within the union recursively to handle cases
|
||||||
// such as `Union[..., Union[...]]
|
// such as `Union[..., Union[...]]`
|
||||||
tuple
|
tuple
|
||||||
.iter()
|
.iter()
|
||||||
.for_each(|elem| inner(func, semantic, elem, Some(expr)));
|
.for_each(|elem| inner(func, semantic, elem, Some(expr)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ex) `Union[Union[a, b]]` and `Union[a | b | c]`
|
||||||
|
inner(func, semantic, slice, Some(expr));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,18 +439,19 @@ where
|
||||||
) where
|
) where
|
||||||
F: FnMut(&'a Expr, &'a Expr),
|
F: FnMut(&'a Expr, &'a Expr),
|
||||||
{
|
{
|
||||||
// Ex) Literal[x, y]
|
// Ex) `Literal[x, y]`
|
||||||
if let Expr::Subscript(ast::ExprSubscript { value, slice, .. }) = expr {
|
if let Expr::Subscript(ast::ExprSubscript { value, slice, .. }) = expr {
|
||||||
if semantic.match_typing_expr(value, "Literal") {
|
if semantic.match_typing_expr(value, "Literal") {
|
||||||
match &**slice {
|
match &**slice {
|
||||||
Expr::Tuple(tuple) => {
|
Expr::Tuple(tuple) => {
|
||||||
// Traverse each element of the tuple within the literal recursively to handle cases
|
// Traverse each element of the tuple within the literal recursively to handle cases
|
||||||
// such as `Literal[..., Literal[...]]
|
// such as `Literal[..., Literal[...]]`
|
||||||
for element in tuple {
|
for element in tuple {
|
||||||
inner(func, semantic, element, Some(expr));
|
inner(func, semantic, element, Some(expr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
other => {
|
other => {
|
||||||
|
// Ex) `Literal[Literal[...]]`
|
||||||
inner(func, semantic, other, Some(expr));
|
inner(func, semantic, other, Some(expr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
use ruff_python_ast::helpers::from_relative_import;
|
use ruff_python_ast::helpers::from_relative_import;
|
||||||
use ruff_python_ast::name::{QualifiedName, UnqualifiedName};
|
use ruff_python_ast::name::{QualifiedName, UnqualifiedName};
|
||||||
use ruff_python_ast::{self as ast, Expr, ExprContext, Operator, PySourceType, Stmt};
|
use ruff_python_ast::{self as ast, Expr, ExprContext, PySourceType, Stmt};
|
||||||
use ruff_text_size::{Ranged, TextRange, TextSize};
|
use ruff_text_size::{Ranged, TextRange, TextSize};
|
||||||
|
|
||||||
use crate::binding::{
|
use crate::binding::{
|
||||||
|
@ -1506,38 +1506,48 @@ impl<'a> SemanticModel<'a> {
|
||||||
/// Return `true` if the model is in a nested union expression (e.g., the inner `Union` in
|
/// Return `true` if the model is in a nested union expression (e.g., the inner `Union` in
|
||||||
/// `Union[Union[int, str], float]`).
|
/// `Union[Union[int, str], float]`).
|
||||||
pub fn in_nested_union(&self) -> bool {
|
pub fn in_nested_union(&self) -> bool {
|
||||||
// Ex) `Union[Union[int, str], float]`
|
let mut parent_expressions = self.current_expressions().skip(1);
|
||||||
if self
|
|
||||||
.current_expression_grandparent()
|
|
||||||
.and_then(Expr::as_subscript_expr)
|
|
||||||
.is_some_and(|parent| self.match_typing_expr(&parent.value, "Union"))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ex) `int | Union[str, float]`
|
match parent_expressions.next() {
|
||||||
if self.current_expression_parent().is_some_and(|parent| {
|
// The parent expression is of the inner union is a single `typing.Union`.
|
||||||
matches!(
|
// Ex) `Union[Union[a, b]]`
|
||||||
parent,
|
Some(Expr::Subscript(parent)) => self.match_typing_expr(&parent.value, "Union"),
|
||||||
Expr::BinOp(ast::ExprBinOp {
|
// The parent expression is of the inner union is a tuple with two or more
|
||||||
op: Operator::BitOr,
|
// comma-separated elements and the parent of that tuple is a `typing.Union`.
|
||||||
..
|
// Ex) `Union[Union[a, b], Union[c, d]]`
|
||||||
})
|
Some(Expr::Tuple(_)) => parent_expressions
|
||||||
)
|
.next()
|
||||||
}) {
|
.and_then(Expr::as_subscript_expr)
|
||||||
return true;
|
.is_some_and(|grandparent| self.match_typing_expr(&grandparent.value, "Union")),
|
||||||
|
// The parent expression of the inner union is a PEP604-style union.
|
||||||
|
// Ex) `a | b | c` or `Union[a, b] | c`
|
||||||
|
// In contrast to `typing.Union`, PEP604-style unions are always binary operations, e.g.
|
||||||
|
// the expression `a | b | c` is represented by two binary unions: `(a | b) | c`.
|
||||||
|
Some(Expr::BinOp(bin_op)) => bin_op.op.is_bit_or(),
|
||||||
|
// Not a nested union otherwise.
|
||||||
|
_ => false,
|
||||||
}
|
}
|
||||||
|
|
||||||
false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return `true` if the model is in a nested literal expression (e.g., the inner `Literal` in
|
/// Return `true` if the model is in a nested literal expression (e.g., the inner `Literal` in
|
||||||
/// `Literal[Literal[int, str], float]`).
|
/// `Literal[Literal[int, str], float]`).
|
||||||
pub fn in_nested_literal(&self) -> bool {
|
pub fn in_nested_literal(&self) -> bool {
|
||||||
// Ex) `Literal[Literal[int, str], float]`
|
let mut parent_expressions = self.current_expressions().skip(1);
|
||||||
self.current_expression_grandparent()
|
|
||||||
.and_then(Expr::as_subscript_expr)
|
match parent_expressions.next() {
|
||||||
.is_some_and(|parent| self.match_typing_expr(&parent.value, "Literal"))
|
// The parent expression of the current `Literal` is a tuple, and the
|
||||||
|
// grandparent is a `Literal`.
|
||||||
|
// Ex) `Literal[Literal[str], Literal[int]]`
|
||||||
|
Some(Expr::Tuple(_)) => parent_expressions
|
||||||
|
.next()
|
||||||
|
.and_then(Expr::as_subscript_expr)
|
||||||
|
.is_some_and(|grandparent| self.match_typing_expr(&grandparent.value, "Literal")),
|
||||||
|
// The parent expression of the current `Literal` is also a `Literal`.
|
||||||
|
// Ex) `Literal[Literal[str]]`
|
||||||
|
Some(Expr::Subscript(parent)) => self.match_typing_expr(&parent.value, "Literal"),
|
||||||
|
// Not a nested literal otherwise
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if `left` and `right` are in the same branches of an `if`, `match`, or
|
/// Returns `true` if `left` and `right` are in the same branches of an `if`, `match`, or
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue