Skip to content

[flake8-pyi] Fix false positive for PEP 695 generic __exit__ methods (PYI036)#26355

Closed
kpeis695 wants to merge 2 commits into
astral-sh:mainfrom
kpeis695:fix/pyi036-generic-type-param-false-positive
Closed

[flake8-pyi] Fix false positive for PEP 695 generic __exit__ methods (PYI036)#26355
kpeis695 wants to merge 2 commits into
astral-sh:mainfrom
kpeis695:fix/pyi036-generic-type-param-false-positive

Conversation

@kpeis695

Copy link
Copy Markdown

Summary

Fixes #25905.

When __exit__ or __aexit__ uses a PEP 695 type parameter bound to BaseException, annotations like type[T] | None and T | None are valid but PYI036 incorrectly flags them:

class Foo:
    def __exit__[T: BaseException](
        self, exc_type: type[T] | None, exc: T | None, tb: TracebackType | None, /
    ) -> bool: ...
# PYI036: The first argument in `__exit__` should be annotated with `object` or `type[BaseException] | None`
# PYI036: The second argument in `__exit__` should be annotated with `object` or `BaseException | None`

The validators is_base_exception_type and the second-arg check only matched type[BaseException] and BaseException literally. The fix passes the function's PEP 695 type params into the validators so type[T] and T are accepted when T is a type parameter whose bound is BaseException.

Type parameters with no bound (or a bound other than BaseException) continue to be flagged as before.

Test Plan

Snapshot tests (cargo nextest run and cargo insta test).

kpeis695 added 2 commits June 24, 2026 23:05
…T003`)

Fixes astral-sh#17226.

When a `Depends(...)` call is pre-assigned to a variable and that variable
is used as metadata in an `Annotated` annotation, FAST003 incorrectly fires
a false positive. The rule scans `Annotated` metadata elements for literal
`Depends(...)` calls; a bare name like `FindItem` is not a call expression,
so `depends_arguments` returns `None`, the element is silently skipped, and
the path parameter appears unused.

The fix treats a bare-name metadata element as `Dependency::Unknown` (unless
it clearly resolves to a function, class, or import), which causes the check
to abort conservatively rather than emitting a false positive.
…ods (`PYI036`)

Fixes astral-sh#25905.

When `__exit__` uses a PEP 695 type parameter bound to `BaseException`
(e.g. `def __exit__[T: BaseException](...)`), annotations like `type[T] | None`
and `T | None` are valid but PYI036 incorrectly flags them as bad.

The rule's validators only matched `type[BaseException]` and `BaseException`
literally. The fix passes the function's type params into the validators so
they can recognise `type[T]` and `T` when `T` is a type param whose bound is
`BaseException`.

Type params with no bound (or a bound other than `BaseException`) continue to
be flagged as before.
@astral-sh-bot astral-sh-bot Bot requested a review from ntBre June 25, 2026 06:26
@kpeis695 kpeis695 changed the title [] Fix false positive for PEP 695 generic __exit__ methods (PYI036) [flake8-pyi] Fix false positive for PEP 695 generic __exit__ methods (PYI036) Jun 25, 2026

@ntBre ntBre left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also has unrelated changes from #26354. Let's focus on one of these PRs at a time.

@kpeis695

Copy link
Copy Markdown
Author

Closing to reopen from a clean branch (only contains the PYI036 fix, no unrelated commits).

@kpeis695 kpeis695 closed this Jun 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bad-exit-annotation (PYI036) - false positive when using a generic for the exception type

2 participants