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

False negatives on PYI rules #8771

Closed
6 of 7 tasks
AlexWaygood opened this issue Nov 19, 2023 · 3 comments
Closed
6 of 7 tasks

False negatives on PYI rules #8771

AlexWaygood opened this issue Nov 19, 2023 · 3 comments
Labels
help wanted Contributions especially welcome rule Implementing or modifying a lint rule

Comments

@AlexWaygood
Copy link
Member

AlexWaygood commented Nov 19, 2023

Ruff reports no errors on the following code snippet (saved as a .pyi stub file) with the command ruff --select=PYI, whereas flake8-pyi reports quite a few ;)

import mypy_extensions
import typing
import typing_extensions

from typing import TypedDict, TypeVarTuple, Union
from typing_extensions import TypeAlias

DoublyNestedAlias: TypeAlias = Union[type[str], type[float] | type[bytes]]

class _UnusedTypedDict3(mypy_extensions.TypedDict):
    baz: dict[str, str]

_UnusedTypedDict4 = TypedDict("_UnusedTypedDict4", {"-": int, "def": str})
_UnusedTypedDict5 = typing_extensions.TypedDict("_UnusedTypedDict5", {"foo": bytes, "bar": str})
_P = typing_extensions.ParamSpec("_P")
_Ts = TypeVarTuple("_Ts")

type lowercase_alias = str | int
type _LooksLikeATypeVarT = str | int
type _Unused = str | int

def badfunc1(*args: typing.NoReturn) -> None: ...
def badfunc2(**kwargs: typing_extensions.NoReturn) -> None: ...

If I run flake8 --extend-ignore=Y023,Y031,Y037 on the same file (with the latest version of the flake8-pyi installed), it reports the following violations:

sample.pyi:8:49: Y055 Multiple "type[Foo]" members in a union. Combine them into one, e.g. "type[float | bytes]".
sample.pyi:10:1: Y049 TypedDict "_UnusedTypedDict3" is not used
sample.pyi:13:1: Y049 TypedDict "_UnusedTypedDict4" is not used
sample.pyi:14:1: Y049 TypedDict "_UnusedTypedDict5" is not used
sample.pyi:15:1: Y018 ParamSpec "_P" is not used
sample.pyi:16:1: Y018 TypeVarTuple "_Ts" is not used
sample.pyi:18:1: Y042 Type aliases should use the CamelCase naming convention
sample.pyi:19:1: Y043 Bad name for a type alias (the "T" suffix implies a TypeVar)
sample.pyi:19:1: Y047 Type alias "_LooksLikeATypeVarT" is not used
sample.pyi:20:1: Y047 Type alias "_Unused" is not used
sample.pyi:22:15: Y050 Use "typing_extensions.Never" instead of "NoReturn" for argument annotations
sample.pyi:23:16: Y050 Use "typing_extensions.Never" instead of "NoReturn" for argument annotations

TODO:

@AlexWaygood
Copy link
Member Author

(Some of these are due to recent changes we've made in flake8-pyi -- e.g. the violations on lines 18-20 are because we recently extended our type alias rules to cover type aliases created using PEP-695 type statements.)

@charliermarsh charliermarsh added the rule Implementing or modifying a lint rule label Nov 19, 2023
@charliermarsh
Copy link
Member

Thank you!

@zanieb zanieb added the help wanted Contributions especially welcome label Nov 20, 2023
charliermarsh pushed a commit that referenced this issue Dec 1, 2023
…#8948)

## Summary

Triggers `no-return-argument-annotation-in-stub` (`PYI050`) for vararg
and kwarg `NoReturn` type annotations.

Related to #8771.

## Test Plan

`cargo test`
charliermarsh pushed a commit that referenced this issue Dec 2, 2023
… and `t-suffixed-type-alias` (#8966)

## Summary

Check PEP 695 type alias definitions for `snake-case-type-alias`
(`PYI042`) and `t-suffixed-type-alias` (`PYI043`)

Related to #8771.

## Test Plan

`cargo test`
charliermarsh pushed a commit that referenced this issue Dec 20, 2023
## Summary

Part of #8771. flake8-pyi will emit a Y018 error for unused TypeVars,
ParamSpecs or TypeVarTuples; Ruff currently only emits PYI018 for unused
TypeVars.

This is my first "proper" Ruff PR -- let me know if there's a better way
of doing this! Not sure if the repeated calls to `match_typing_expr()`
are ideal.

## Test Plan

I manually updated the fixtures to add some unused ParamSpecs and
TypeVarTuples, and then updated the snapshots using `cargo insta
review`. All tests then passed when run using `cargo test`.
charliermarsh pushed a commit that referenced this issue Jan 18, 2024
## Summary

Fixes one of the issues listed in
#8771. Fairly straightforward!

## Test Plan

`cargo test` / `cargo insta review`
AlexWaygood added a commit that referenced this issue Jan 18, 2024
## Summary

Fixes another of the bullet points from #8771

## Test Plan

`cargo test` / `cargo insta review`
@AlexWaygood
Copy link
Member Author

AlexWaygood commented Jan 18, 2024

All but one of these are now ticked off 🥳

I'm closing this now, since the last one is sort-of in a category by itself, and I'm not sure we'd want to fix it. The obvious way to teach ruff to recognize mypy_extensions.TypedDict would be to have ruff recognize mypy_extensions as a "typing module" in the same way as typing or typing_extensions. But unlike typing and typing_extensions, mypy_extensions is, well, mypy-specific -- other type checkers accord it no special treatment. mypy_extensions.TypedDict specifically is also deprecated in favour of typing(_extensions).TypedDict (though there's yet to be a release that includes the DeprecationWarning)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Contributions especially welcome rule Implementing or modifying a lint rule
Projects
None yet
Development

No branches or pull requests

3 participants