Create a snapshot description that represents the state of a symbol table. The snapshot has a representation based on nested tuples and dicts that makes it easy and fast to find differences. Only "shallow" state is included in the snapshot -- references to things defined in other m
(name_prefix: str, table: SymbolTable)
| 164 | |
| 165 | |
| 166 | def snapshot_symbol_table(name_prefix: str, table: SymbolTable) -> dict[str, SymbolSnapshot]: |
| 167 | """Create a snapshot description that represents the state of a symbol table. |
| 168 | |
| 169 | The snapshot has a representation based on nested tuples and dicts |
| 170 | that makes it easy and fast to find differences. |
| 171 | |
| 172 | Only "shallow" state is included in the snapshot -- references to |
| 173 | things defined in other modules are represented just by the names of |
| 174 | the targets. |
| 175 | """ |
| 176 | result: dict[str, SymbolSnapshot] = {} |
| 177 | for name, symbol in table.items(): |
| 178 | node = symbol.node |
| 179 | # TODO: cross_ref? |
| 180 | fullname = node.fullname if node else None |
| 181 | common = (fullname, symbol.kind, symbol.module_public) |
| 182 | if isinstance(node, MypyFile): |
| 183 | # This is a cross-reference to another module. |
| 184 | # If the reference is busted because the other module is missing, |
| 185 | # the node will be a "stale_info" TypeInfo produced by fixup, |
| 186 | # but that doesn't really matter to us here. |
| 187 | result[name] = ("Moduleref", common) |
| 188 | elif isinstance(node, TypeVarExpr): |
| 189 | result[name] = ( |
| 190 | "TypeVar", |
| 191 | node.variance, |
| 192 | [snapshot_type(value) for value in node.values], |
| 193 | snapshot_type(node.upper_bound), |
| 194 | snapshot_type(node.default), |
| 195 | ) |
| 196 | elif isinstance(node, TypeAlias): |
| 197 | result[name] = ( |
| 198 | "TypeAlias", |
| 199 | snapshot_types(node.alias_tvars), |
| 200 | node.normalized, |
| 201 | node.no_args, |
| 202 | snapshot_optional_type(node.target), |
| 203 | ) |
| 204 | elif isinstance(node, ParamSpecExpr): |
| 205 | result[name] = ( |
| 206 | "ParamSpec", |
| 207 | node.variance, |
| 208 | snapshot_type(node.upper_bound), |
| 209 | snapshot_type(node.default), |
| 210 | ) |
| 211 | elif isinstance(node, TypeVarTupleExpr): |
| 212 | result[name] = ( |
| 213 | "TypeVarTuple", |
| 214 | node.variance, |
| 215 | snapshot_type(node.upper_bound), |
| 216 | snapshot_type(node.default), |
| 217 | ) |
| 218 | else: |
| 219 | assert symbol.kind != UNBOUND_IMPORTED |
| 220 | if node and get_prefix(node.fullname) != name_prefix: |
| 221 | # This is a cross-reference to a node defined in another module. |
| 222 | # Include the node kind (FuncDef, Decorator, TypeInfo, ...), so that we will |
| 223 | # reprocess when a *new* node is created instead of merging an existing one. |
searching dependent graphs…