Refactor import-tracking to leverage existing AST bindings (#1856)
This PR refactors our import-tracking logic to leverage our existing logic for tracking bindings. It's both a significant simplification, a significant improvement (as we can now track reassignments), and closes out a bunch of subtle bugs. Though the AST tracks all bindings (e.g., when parsing `import os as foo`, we bind the name `foo` to a `BindingKind::Importation` that points to the `os` module), when I went to implement import tracking (e.g., to ensure that if the user references `List`, it's actually `typing.List`), I added a parallel system specifically for this use-case. That was a mistake, for a few reasons: 1. It didn't track reassignments, so if you had `from typing import List`, but `List` was later overridden, we'd still consider any reference to `List` to be `typing.List`. 2. It required a bunch of extra logic, include complex logic to try and optimize the lookups, since it's such a hot codepath. 3. There were a few bugs in the implementation that were just hard to correct under the existing abstractions (e.g., if you did `from typing import Optional as Foo`, then we'd treat any reference to `Foo` _or_ `Optional` as `typing.Optional` (even though, in that case, `Optional` was really unbound). The new implementation goes through our existing binding tracking: when we get a reference, we find the appropriate binding given the current scope stack, and normalize it back to its original target. Closes #1690. Closes #1790.
This commit is contained in:
9
resources/test/fixtures/flake8_annotations/allow_nested_overload.py
vendored
Normal file
9
resources/test/fixtures/flake8_annotations/allow_nested_overload.py
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
class C:
|
||||
from typing import overload
|
||||
|
||||
@overload
|
||||
def f(self, x: int, y: int) -> None:
|
||||
...
|
||||
|
||||
def f(self, x, y):
|
||||
pass
|
||||
1
resources/test/fixtures/pyflakes/F401_6.py
vendored
1
resources/test/fixtures/pyflakes/F401_6.py
vendored
@@ -9,7 +9,6 @@ from .background import BackgroundTasks
|
||||
# F401 `datastructures.UploadFile` imported but unused
|
||||
from .datastructures import UploadFile as FileUpload
|
||||
|
||||
|
||||
# OK
|
||||
import applications as applications
|
||||
|
||||
|
||||
@@ -5,4 +5,3 @@ from warnings import warn
|
||||
warnings.warn("this is ok")
|
||||
warn("by itself is also ok")
|
||||
logging.warning("this is fine")
|
||||
log.warning("this is ok")
|
||||
|
||||
10
resources/test/fixtures/pygrep-hooks/PGH002_1.py
vendored
10
resources/test/fixtures/pygrep-hooks/PGH002_1.py
vendored
@@ -2,14 +2,4 @@ import logging
|
||||
from logging import warn
|
||||
|
||||
logging.warn("this is not ok")
|
||||
log.warn("this is also not ok")
|
||||
warn("not ok")
|
||||
|
||||
|
||||
def foo():
|
||||
from logging import warn
|
||||
|
||||
def warn():
|
||||
pass
|
||||
|
||||
warn("has been redefined, but we will still report it")
|
||||
|
||||
Reference in New Issue
Block a user