| 219 | |
| 220 | class DependencyVisitor(TraverserVisitor): |
| 221 | def __init__( |
| 222 | self, |
| 223 | type_map: dict[Expression, Type], |
| 224 | python_version: tuple[int, int], |
| 225 | alias_deps: defaultdict[str, set[str]], |
| 226 | options: Options | None = None, |
| 227 | ) -> None: |
| 228 | self.scope = Scope() |
| 229 | self.type_map = type_map |
| 230 | # This attribute holds a mapping from target to names of type aliases |
| 231 | # it depends on. These need to be processed specially, since they may |
| 232 | # appear in expanded form in symbol tables, because of a get_proper_type() |
| 233 | # somewhere. For example, after: |
| 234 | # A = int |
| 235 | # x: A |
| 236 | # the module symbol table will just have a Var `x` with type `int`, |
| 237 | # and the dependency of `x` on `A` is lost. Therefore, the alias dependencies |
| 238 | # are preserved at alias expansion points in `semanal.py`, stored as an attribute |
| 239 | # on MypyFile, and then passed here. |
| 240 | # TODO: fine-grained is more susceptible to this partially because we are reckless |
| 241 | # about get_proper_type() in *this specific file*. |
| 242 | self.alias_deps = alias_deps |
| 243 | self.map: dict[str, set[str]] = {} |
| 244 | self.is_class = False |
| 245 | self.is_package_init_file = False |
| 246 | self.options = options |
| 247 | |
| 248 | def visit_mypy_file(self, o: MypyFile) -> None: |
| 249 | with self.scope.module_scope(o.fullname): |