Description
This bug was discovered in #15719
Given something like:
from __future__ import annotations
import importlib.abc
from typing import TYPE_CHECKING
if TYPE_CHECKING:
import importlib.machinery
class Foo(importlib.abc.MetaPathFinder):
def bar(self) -> importlib.machinery.ModuleSpec: ...
importlib.machinery will incorrectly be flagged with TC004, since importlib.abc.MetaPathFinder binds to the same binding as importlib.machinery.ModuleSpec, so since the former is used at runtime, it thinks that importlib.machinery needs to be moved outside the TYPE_CHECKING block.
Combining the two imports into a shared binding makes sense, since what will be looked up is importlib and not importlib.machinery or importlib.abc.
This means that when we're checking the import bindings we need to expand the single importlib binding to its two import statements importlib.abc and importlib.machinery and for each reference check which of the two imports will actually be relevant.
Description
This bug was discovered in #15719
Given something like:
importlib.machinerywill incorrectly be flagged withTC004, sinceimportlib.abc.MetaPathFinderbinds to the same binding asimportlib.machinery.ModuleSpec, so since the former is used at runtime, it thinks thatimportlib.machineryneeds to be moved outside theTYPE_CHECKINGblock.Combining the two imports into a shared binding makes sense, since what will be looked up is
importliband notimportlib.machineryorimportlib.abc.This means that when we're checking the import bindings we need to expand the single
importlibbinding to its two import statementsimportlib.abcandimportlib.machineryand for each reference check which of the two imports will actually be relevant.