diff --git a/crates/ruff/resources/test/fixtures/flake8_pyi/PYI055.py b/crates/ruff/resources/test/fixtures/flake8_pyi/PYI055.py index 84b0caf2ad..adbc1f737a 100644 --- a/crates/ruff/resources/test/fixtures/flake8_pyi/PYI055.py +++ b/crates/ruff/resources/test/fixtures/flake8_pyi/PYI055.py @@ -1,7 +1,6 @@ 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] @@ -9,7 +8,9 @@ z: Union[type[float], type[complex]] z: Union[type[float, int], type[complex]] -def func(arg: type[int] | str | type[float]) -> None: ... +def func(arg: type[int] | str | type[float]) -> None: + ... + # OK x: type[int, str, float] @@ -17,4 +18,14 @@ y: builtins.type[int, str, complex] z: Union[float, complex] -def func(arg: type[int, float] | str) -> None: ... +def func(arg: type[int, float] | str) -> None: + ... + + +# OK +item: type[requests_mock.Mocker] | type[httpretty] = requests_mock.Mocker + + +def func(): + # PYI055 + item: type[requests_mock.Mocker] | type[httpretty] = requests_mock.Mocker diff --git a/crates/ruff/resources/test/fixtures/flake8_pyi/PYI055.pyi b/crates/ruff/resources/test/fixtures/flake8_pyi/PYI055.pyi index 84b0caf2ad..3cc530f770 100644 --- a/crates/ruff/resources/test/fixtures/flake8_pyi/PYI055.pyi +++ b/crates/ruff/resources/test/fixtures/flake8_pyi/PYI055.pyi @@ -1,14 +1,12 @@ 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]] - def func(arg: type[int] | str | type[float]) -> None: ... # OK @@ -16,5 +14,11 @@ x: type[int, str, float] y: builtins.type[int, str, complex] z: Union[float, complex] - def func(arg: type[int, float] | str) -> None: ... + +# OK +item: type[requests_mock.Mocker] | type[httpretty] = requests_mock.Mocker + +def func(): + # PYI055 + item: type[requests_mock.Mocker] | type[httpretty] = requests_mock.Mocker diff --git a/crates/ruff/src/rules/flake8_pyi/rules/unnecessary_type_union.rs b/crates/ruff/src/rules/flake8_pyi/rules/unnecessary_type_union.rs index 488d7c9c8e..8c0cac5c97 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/unnecessary_type_union.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/unnecessary_type_union.rs @@ -43,6 +43,11 @@ impl Violation for UnnecessaryTypeUnion { /// PYI055 pub(crate) fn unnecessary_type_union<'a>(checker: &mut Checker, union: &'a Expr) { + // The `|` operator isn't always safe to allow to runtime-evaluated annotations. + if checker.semantic().execution_context().is_runtime() { + return; + } + let mut type_exprs = Vec::new(); // Check if `union` is a PEP604 union (e.g. `float | int`) or a `typing.Union[float, int]` diff --git a/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI055_PYI055.py.snap b/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI055_PYI055.py.snap index 78622d6f93..8f474e08d7 100644 --- a/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI055_PYI055.py.snap +++ b/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI055_PYI055.py.snap @@ -1,56 +1,12 @@ --- source: crates/ruff/src/rules/flake8_pyi/mod.rs --- -PYI055.py:5:4: PYI055 Multiple `type` members in a union. Combine them into one, e.g., `type[int | str | complex]`. - | -5 | w: builtins.type[int] | builtins.type[str] | builtins.type[complex] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055 -6 | x: type[int] | type[str] | type[float] -7 | y: builtins.type[int] | type[str] | builtins.type[complex] - | - -PYI055.py:6:4: PYI055 Multiple `type` members in a union. Combine them into one, e.g., `type[int | str | float]`. - | -5 | w: builtins.type[int] | builtins.type[str] | builtins.type[complex] -6 | x: type[int] | type[str] | type[float] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055 -7 | y: builtins.type[int] | type[str] | builtins.type[complex] -8 | z: Union[type[float], type[complex]] - | - -PYI055.py:7:4: PYI055 Multiple `type` members in a union. Combine them into one, e.g., `type[int | str | complex]`. - | -5 | w: builtins.type[int] | builtins.type[str] | builtins.type[complex] -6 | x: type[int] | type[str] | type[float] -7 | y: builtins.type[int] | type[str] | builtins.type[complex] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055 -8 | z: Union[type[float], type[complex]] -9 | z: Union[type[float, int], type[complex]] - | - -PYI055.py:8:4: PYI055 Multiple `type` members in a union. Combine them into one, e.g., `type[Union[float, complex]]`. - | -6 | x: type[int] | type[str] | type[float] -7 | y: builtins.type[int] | type[str] | builtins.type[complex] -8 | z: Union[type[float], type[complex]] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055 -9 | z: Union[type[float, int], type[complex]] - | - -PYI055.py:9:4: PYI055 Multiple `type` members in a union. Combine them into one, e.g., `type[Union[float, int, complex]]`. - | -7 | y: builtins.type[int] | type[str] | builtins.type[complex] -8 | z: Union[type[float], type[complex]] -9 | z: Union[type[float, int], type[complex]] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055 - | - -PYI055.py:12:15: PYI055 Multiple `type` members in a union. Combine them into one, e.g., `type[int | float]`. +PYI055.py:31:11: PYI055 Multiple `type` members in a union. Combine them into one, e.g., `type[requests_mock.Mocker | httpretty]`. | -12 | def func(arg: type[int] | str | type[float]) -> None: ... - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055 -13 | -14 | # OK +29 | def func(): +30 | # PYI055 +31 | item: type[requests_mock.Mocker] | type[httpretty] = requests_mock.Mocker + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055 | diff --git a/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI055_PYI055.pyi.snap b/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI055_PYI055.pyi.snap index f0ab0f3f53..a8262366ed 100644 --- a/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI055_PYI055.pyi.snap +++ b/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI055_PYI055.pyi.snap @@ -1,56 +1,79 @@ --- source: crates/ruff/src/rules/flake8_pyi/mod.rs --- -PYI055.pyi:5:4: PYI055 Multiple `type` members in a union. Combine them into one, e.g., `type[int | str | complex]`. +PYI055.pyi:4:4: PYI055 Multiple `type` members in a union. Combine them into one, e.g., `type[int | str | complex]`. | -5 | w: builtins.type[int] | builtins.type[str] | builtins.type[complex] +2 | from typing import Union +3 | +4 | w: builtins.type[int] | builtins.type[str] | builtins.type[complex] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055 -6 | x: type[int] | type[str] | type[float] -7 | y: builtins.type[int] | type[str] | builtins.type[complex] +5 | x: type[int] | type[str] | type[float] +6 | y: builtins.type[int] | type[str] | builtins.type[complex] | -PYI055.pyi:6:4: PYI055 Multiple `type` members in a union. Combine them into one, e.g., `type[int | str | float]`. +PYI055.pyi:5:4: PYI055 Multiple `type` members in a union. Combine them into one, e.g., `type[int | str | float]`. | -5 | w: builtins.type[int] | builtins.type[str] | builtins.type[complex] -6 | x: type[int] | type[str] | type[float] +4 | w: builtins.type[int] | builtins.type[str] | builtins.type[complex] +5 | x: type[int] | type[str] | type[float] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055 -7 | y: builtins.type[int] | type[str] | builtins.type[complex] -8 | z: Union[type[float], type[complex]] +6 | y: builtins.type[int] | type[str] | builtins.type[complex] +7 | z: Union[type[float], type[complex]] | -PYI055.pyi:7:4: PYI055 Multiple `type` members in a union. Combine them into one, e.g., `type[int | str | complex]`. +PYI055.pyi:6:4: PYI055 Multiple `type` members in a union. Combine them into one, e.g., `type[int | str | complex]`. | -5 | w: builtins.type[int] | builtins.type[str] | builtins.type[complex] -6 | x: type[int] | type[str] | type[float] -7 | y: builtins.type[int] | type[str] | builtins.type[complex] +4 | w: builtins.type[int] | builtins.type[str] | builtins.type[complex] +5 | x: type[int] | type[str] | type[float] +6 | y: builtins.type[int] | type[str] | builtins.type[complex] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055 -8 | z: Union[type[float], type[complex]] -9 | z: Union[type[float, int], type[complex]] +7 | z: Union[type[float], type[complex]] +8 | z: Union[type[float, int], type[complex]] | -PYI055.pyi:8:4: PYI055 Multiple `type` members in a union. Combine them into one, e.g., `type[Union[float, complex]]`. +PYI055.pyi:7:4: PYI055 Multiple `type` members in a union. Combine them into one, e.g., `type[Union[float, complex]]`. | -6 | x: type[int] | type[str] | type[float] -7 | y: builtins.type[int] | type[str] | builtins.type[complex] -8 | z: Union[type[float], type[complex]] +5 | x: type[int] | type[str] | type[float] +6 | y: builtins.type[int] | type[str] | builtins.type[complex] +7 | z: Union[type[float], type[complex]] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055 -9 | z: Union[type[float, int], type[complex]] +8 | z: Union[type[float, int], type[complex]] | -PYI055.pyi:9:4: PYI055 Multiple `type` members in a union. Combine them into one, e.g., `type[Union[float, int, complex]]`. - | -7 | y: builtins.type[int] | type[str] | builtins.type[complex] -8 | z: Union[type[float], type[complex]] -9 | z: Union[type[float, int], type[complex]] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055 - | - -PYI055.pyi:12:15: PYI055 Multiple `type` members in a union. Combine them into one, e.g., `type[int | float]`. +PYI055.pyi:8:4: PYI055 Multiple `type` members in a union. Combine them into one, e.g., `type[Union[float, int, complex]]`. | -12 | def func(arg: type[int] | str | type[float]) -> None: ... + 6 | y: builtins.type[int] | type[str] | builtins.type[complex] + 7 | z: Union[type[float], type[complex]] + 8 | z: Union[type[float, int], type[complex]] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055 + 9 | +10 | def func(arg: type[int] | str | type[float]) -> None: ... + | + +PYI055.pyi:10:15: PYI055 Multiple `type` members in a union. Combine them into one, e.g., `type[int | float]`. + | + 8 | z: Union[type[float, int], type[complex]] + 9 | +10 | def func(arg: type[int] | str | type[float]) -> None: ... | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055 -13 | -14 | # OK +11 | +12 | # OK + | + +PYI055.pyi:20:7: PYI055 Multiple `type` members in a union. Combine them into one, e.g., `type[requests_mock.Mocker | httpretty]`. + | +19 | # OK +20 | item: type[requests_mock.Mocker] | type[httpretty] = requests_mock.Mocker + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055 +21 | +22 | def func(): + | + +PYI055.pyi:24:11: PYI055 Multiple `type` members in a union. Combine them into one, e.g., `type[requests_mock.Mocker | httpretty]`. + | +22 | def func(): +23 | # PYI055 +24 | item: type[requests_mock.Mocker] | type[httpretty] = requests_mock.Mocker + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055 |