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

PYI036 (bad-exit-annotation) triggers on seemingly appropriate annotations #9794

Open
Sachaa-Thanasius opened this issue Feb 2, 2024 · 3 comments
Labels
rule Implementing or modifying a lint rule

Comments

@Sachaa-Thanasius
Copy link

Sachaa-Thanasius commented Feb 2, 2024

Code snippet
For additional context: Importing from types outside of the TYPE_CHECKING block doesn't trigger this. However, I'd prefer not actually importing that at runtime, since it can be expensive. Curious if this kind of case is in scope for this rule.

from typing import TYPE_CHECKING

from typing_extensions import Self


if TYPE_CHECKING:
    from types import TracebackType
else:

    class TracebackType:
        pass


class Example:
    def __enter__(self) -> Self:
        return self

    def __exit__(
        self,
        exc_type: type[BaseException] | None,
        exc_val: BaseException | None,
        traceback: TracebackType | None,
) -> None:
        return None

Invoked Command

ruff core\utils\_test.py --isolated --select PYI036

Output:

core\utils\_test.py:22:20: PYI036 The third argument in `__exit__` should be annotated with `object` or `types.TracebackType | None`
Found 1 error.

Relevant pyproject.toml Sections
Use of the --isolated and --select flags above makes this redundant, I think? If not, I will update to include them, though the only seemingly relevant thing is PYI's presence in the select list.

Version
ruff 0.2.0

@AlexWaygood AlexWaygood added the rule Implementing or modifying a lint rule label Feb 2, 2024
@T-256
Copy link
Contributor

T-256 commented Feb 2, 2024

In your case I think you could also do:

from __future__ import annotations
from typing import TYPE_CHECKING

from typing_extensions import Self

if TYPE_CHECKING:
    from types import TracebackType


class Example:
    def __enter__(self) -> Self:
        return self

    def __exit__(
        self,
        exc_type: type[BaseException] | None,
        exc_val: BaseException | None,
        traceback: TracebackType | None,
) -> None:
        return None

@Sachaa-Thanasius
Copy link
Author

Sachaa-Thanasius commented Feb 2, 2024

While that's true, I would rather not break type introspection for tools like typing.get_type_hints(). Having something in the type checking block's else clause prevents that, even if the type isn't exactly right. Hoping there's a "best of both worlds" option here, where I can not break that and have ruff's rule recognize what's happening here. If not, though, I understand.

@CarrotManMatt
Copy link
Contributor

I am running into this bug when importing the types inside a type-checking block & using quoted annotations rather than from __future__ import annotations. A resolution for this bug would be appreciated

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

No branches or pull requests

4 participants