ruff
ruff copied to clipboard
F401+F811 false positive
Minimal reproducer
from foo import Foo
from typing import TypeAlias
class Bar:
Foo: TypeAlias = Foo
def bar(self) -> Foo: ...
Output
$ ruff stub.pyi
stub.pyi:1:17: F401 `foo.Foo` imported but unused
stub.pyi:5:5: F811 Redefinition of unused `Foo` from line 1
Found 2 error(s).
1 potentially fixable with the --fix option.
Ruff version: 0.0.227
Confirmed with 0.0.236 with a .pyi file.
Doesn't occur with a .py file unless prepending with from __future__ import annotations.
Is this, maybe, the same as #1401?
I believe it is not exactly the same. My reproducer would be equivalent to:
from foo import Foo
class Bar:
Foo = Foo
def bar(self) -> Foo: ...
and ruff is happy with this code.
This is a small variation to my original reproducer:
from typing import TypeAlias
class Foo: ...
class Bar:
Foo: TypeAlias = Foo
def bar(self) -> Foo: ...
This time Ruff is happy with it.
- My original reproducer triggers the warnings.
- Similar code with a locally defined symbol does not.
- Removing the
TypeAliasannotation silences the warning. - Changing the annotation to
Foo: Type = Fooalso silences the warning. So far this looks like a subtle bug related to visibility and/or theTypeAliasannotation.
Yeah this is really tricky.
Obligatory link to Tweet: https://twitter.com/charliermarsh/status/1659233087786459139
I believe we need to change the logic in this case to eagerly resolve if the binding is already defined, and otherwise, go through standard deferred resolution.