Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend test cases for flake8-pyi #14280

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI016.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,27 @@ def func2() -> str | str: # PYI016: Duplicate union member `str`
# duplicates of the outer `int`), but not three times (which would indicate that
# we incorrectly re-checked the nested union).
field25: typing.Union[int, int | int] # PYI016: Duplicate union member `int`

# Should emit in cases with nested `typing.Union`
field26: typing.Union[typing.Union[int, int]] # PYI016: Duplicate union member `int`

# Should emit in cases with nested `typing.Union`
field27: typing.Union[typing.Union[typing.Union[int, int]]] # PYI016: Duplicate union member `int`

# Should emit in cases with mixed `typing.Union` and `|`
field28: typing.Union[int | int] # Error

# Should emit twice in cases with multiple nested `typing.Union`
field29: typing.Union[int, typing.Union[typing.Union[int, int]]] # Error

# Should emit once in cases with multiple nested `typing.Union`
field30: typing.Union[int, typing.Union[typing.Union[int, str]]] # Error

# Should emit once, and fix to `typing.Union[float, int]`
field31: typing.Union[float, typing.Union[int | int]] # Error

# Should emit once, and fix to `typing.Union[float, int]`
field32: typing.Union[float, typing.Union[int | int | int]] # Error

# Test case for mixed union type fix
field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error
24 changes: 24 additions & 0 deletions crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI016.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,27 @@ field24: typing.Union[int, typing.Union[int, int]] # PYI016: Duplicate union me
# duplicates of the outer `int`), but not three times (which would indicate that
# we incorrectly re-checked the nested union).
field25: typing.Union[int, int | int] # PYI016: Duplicate union member `int`

# Should emit in cases with nested `typing.Union`
field26: typing.Union[typing.Union[int, int]] # PYI016: Duplicate union member `int`

# Should emit in cases with nested `typing.Union`
field27: typing.Union[typing.Union[typing.Union[int, int]]] # PYI016: Duplicate union member `int`

# Should emit in cases with mixed `typing.Union` and `|`
field28: typing.Union[int | int] # Error

# Should emit twice in cases with multiple nested `typing.Union`
field29: typing.Union[int, typing.Union[typing.Union[int, int]]] # Error

# Should emit once in cases with multiple nested `typing.Union`
field30: typing.Union[int, typing.Union[typing.Union[int, str]]] # Error

# Should emit once, and fix to `typing.Union[float, int]`
field31: typing.Union[float, typing.Union[int | int]] # Error

# Should emit once, and fix to `typing.Union[float, int]`
field32: typing.Union[float, typing.Union[int | int | int]] # Error

# Test case for mixed union type fix
field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error
16 changes: 16 additions & 0 deletions crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI041.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,22 @@ async def f4(**kwargs: int | int | float) -> None:
...


def f5(arg1: int, *args: Union[int, int, float]) -> None:
...


def f6(arg1: int, *args: Union[Union[int, int, float]]) -> None:
...


def f7(arg1: int, *args: Union[Union[Union[int, int, float]]]) -> None:
...


def f8(arg1: int, *args: Union[Union[Union[int | int | float]]]) -> None:
...


class Foo:
def good(self, arg: int) -> None:
...
Expand Down
12 changes: 12 additions & 0 deletions crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI041.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,18 @@ def f3(arg1: int, *args: Union[int | int | float]) -> None: ... # PYI041
async def f4(**kwargs: int | int | float) -> None: ... # PYI041


def f5(arg1: int, *args: Union[int, int, float]) -> None: ... # PYI041


def f6(arg1: int, *args: Union[Union[int, int, float]]) -> None: ... # PYI041


def f7(arg1: int, *args: Union[Union[Union[int, int, float]]]) -> None: ... # PYI041


def f8(arg1: int, *args: Union[Union[Union[int | int | float]]]) -> None: ... # PYI041


class Foo:
def good(self, arg: int) -> None: ...

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
B: TypeAlias = typing.Union[Literal[b"bar", b"foo"], bytes, str]
C: TypeAlias = typing.Union[Literal[5], int, typing.Union[Literal["foo"], str]]
D: TypeAlias = typing.Union[Literal[b"str_bytes", 42], bytes, int]
E: TypeAlias = typing.Union[typing.Union[typing.Union[typing.Union[Literal["foo"], str]]]]
F: TypeAlias = typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
G: typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]

def func(x: complex | Literal[1J], y: Union[Literal[3.14], float]): ...

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ A: str | Literal["foo"]
B: TypeAlias = typing.Union[Literal[b"bar", b"foo"], bytes, str]
C: TypeAlias = typing.Union[Literal[5], int, typing.Union[Literal["foo"], str]]
D: TypeAlias = typing.Union[Literal[b"str_bytes", 42], bytes, int]
E: TypeAlias = typing.Union[typing.Union[typing.Union[typing.Union[Literal["foo"], str]]]]
F: TypeAlias = typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
G: typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]

def func(x: complex | Literal[1J], y: Union[Literal[3.14], float]): ...

Expand Down
13 changes: 8 additions & 5 deletions crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI055.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import builtins
from typing import Union

w: builtins.type[int] | builtins.type[str] | builtins.type[complex]
x: type[int] | type[str] | type[float]
y: builtins.type[int] | type[str] | builtins.type[complex]
z: Union[type[float], type[complex]]
z: Union[type[float, int], type[complex]]
s: builtins.type[int] | builtins.type[str] | builtins.type[complex]
t: type[int] | type[str] | type[float]
u: builtins.type[int] | type[str] | builtins.type[complex]
v: Union[type[float], type[complex]]
w: Union[type[float, int], type[complex]]
x: Union[Union[type[float, int], type[complex]]]
y: Union[Union[Union[type[float, int], type[complex]]]]
z: Union[type[complex], Union[Union[type[float, int]]]]


def func(arg: type[int] | str | type[float]) -> None:
Expand Down
13 changes: 8 additions & 5 deletions crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI055.pyi
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import builtins
from typing import Union

w: builtins.type[int] | builtins.type[str] | builtins.type[complex]
x: type[int] | type[str] | type[float]
y: builtins.type[int] | type[str] | builtins.type[complex]
z: Union[type[float], type[complex]]
z: Union[type[float, int], type[complex]]
s: builtins.type[int] | builtins.type[str] | builtins.type[complex]
t: type[int] | type[str] | type[float]
u: builtins.type[int] | type[str] | builtins.type[complex]
v: Union[type[float], type[complex]]
w: Union[type[float, int], type[complex]]
x: Union[Union[type[float, int], type[complex]]]
y: Union[Union[Union[type[float, int], type[complex]]]]
z: Union[type[complex], Union[Union[type[float, int]]]]

def func(arg: type[int] | str | type[float]) -> None: ...

Expand Down
12 changes: 12 additions & 0 deletions crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI062.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,20 @@
Literal[1, Literal[2], Literal[2]] # once
t.Literal[1, t.Literal[2, t.Literal[1]]] # once
typing_extensions.Literal[1, 1, 1] # twice
Literal[
1, # comment
Literal[ # another comment
1
]
] # once

# Ensure issue is only raised once, even on nested literals
MyType = Literal["foo", Literal[True, False, True], "bar"] # PYI062

n: Literal["No", "duplicates", "here", 1, "1"]


# nested literals, all equivalent to `Literal[1]`
Literal[Literal[1]] # no duplicate
Literal[Literal[Literal[1], Literal[1]]] # once
Literal[Literal[1], Literal[Literal[Literal[1]]]] # once
18 changes: 15 additions & 3 deletions crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI062.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,32 @@ from typing import Literal
import typing as t
import typing_extensions

x: Literal[True, False, True, False] # PY062 twice here
x: Literal[True, False, True, False] # PYI062 twice here

y: Literal[1, print("hello"), 3, Literal[4, 1]] # PY062 on the last 1
y: Literal[1, print("hello"), 3, Literal[4, 1]] # PYI062 on the last 1

z: Literal[{1, 3, 5}, "foobar", {1,3,5}] # PY062 on the set literal
z: Literal[{1, 3, 5}, "foobar", {1,3,5}] # PYI062 on the set literal

Literal[1, Literal[1]] # once
Literal[1, 2, Literal[1, 2]] # twice
Literal[1, Literal[1], Literal[1]] # twice
Literal[1, Literal[2], Literal[2]] # once
t.Literal[1, t.Literal[2, t.Literal[1]]] # once
typing_extensions.Literal[1, 1, 1] # twice
Literal[
1, # comment
Literal[ # another comment
1
]
] # once

# Ensure issue is only raised once, even on nested literals
MyType = Literal["foo", Literal[True, False, True], "bar"] # PYI062

n: Literal["No", "duplicates", "here", 1, "1"]


# nested literals, all equivalent to `Literal[1]`
Literal[Literal[1]] # no duplicate
Literal[Literal[Literal[1], Literal[1]]] # once
Literal[Literal[1], Literal[Literal[Literal[1]]]] # once
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,8 @@ PYI016.py:86:28: PYI016 [*] Duplicate union member `int`
85 | # we incorrectly re-checked the nested union).
86 | field25: typing.Union[int, int | int] # PYI016: Duplicate union member `int`
| ^^^ PYI016
87 |
88 | # Should emit in cases with nested `typing.Union`
|
= help: Remove duplicate union member `int`

Expand All @@ -523,13 +525,18 @@ PYI016.py:86:28: PYI016 [*] Duplicate union member `int`
85 85 | # we incorrectly re-checked the nested union).
86 |-field25: typing.Union[int, int | int] # PYI016: Duplicate union member `int`
86 |+field25: typing.Union[int, 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).
86 | field25: typing.Union[int, int | int] # PYI016: Duplicate union member `int`
| ^^^ PYI016
87 |
88 | # Should emit in cases with nested `typing.Union`
|
= help: Remove duplicate union member `int`

Expand All @@ -539,5 +546,151 @@ PYI016.py:86:34: PYI016 [*] Duplicate union member `int`
85 85 | # we incorrectly re-checked the nested union).
86 |-field25: typing.Union[int, int | int] # PYI016: Duplicate union member `int`
86 |+field25: typing.Union[int, 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`
| ^^^ PYI016
90 |
91 | # Should emit in cases with nested `typing.Union`
|
= help: Remove duplicate union member `int`

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
| ^^^ PYI016
96 |
97 | # Should emit twice in cases with multiple nested `typing.Union`
|
= help: Remove 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: typing.Union[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: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
| ^^^ PYI016
99 |
100 | # Should emit once in cases with multiple nested `typing.Union`
|
= help: Remove duplicate union member `int`

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
| ^^^ PYI016
105 |
106 | # Should emit once, and fix to `typing.Union[float, int]`
|
= help: Remove 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: typing.Union[float, typing.Union[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
| ^^^ PYI016
108 |
109 | # Test case for mixed union type fix
|
= help: Remove 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: typing.Union[float, typing.Union[int | 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
| ^^^ PYI016
108 |
109 | # Test case for mixed union type fix
|
= help: Remove 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: typing.Union[float, typing.Union[int | 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
| ^^^ PYI016
|
= help: Remove 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: typing.Union[typing.Union[int] | typing.Union[int | int]] # Error

PYI016.py:110:49: PYI016 [*] Duplicate union member `typing.Union[int | int]`
|
109 | # Test case for mixed union type fix
110 | field33: typing.Union[typing.Union[int | int] | typing.Union[int | int]] # Error
| ^^^^^^^^^^^^^^^^^^^^^^^ PYI016
|
= help: Remove duplicate union member `typing.Union[int | 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: typing.Union[typing.Union[int | 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
| ^^^ PYI016
|
= help: Remove 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: typing.Union[typing.Union[int | int] | typing.Union[int]] # Error
Loading