Similar to NodeReplaceVisitor, but for type objects. Note: this visitor may sometimes visit unanalyzed types such as 'UnboundType' and 'RawExpressionType' For example, see NodeReplaceVisitor.process_base_func.
| 413 | |
| 414 | |
| 415 | class TypeReplaceVisitor(SyntheticTypeVisitor[None]): |
| 416 | """Similar to NodeReplaceVisitor, but for type objects. |
| 417 | |
| 418 | Note: this visitor may sometimes visit unanalyzed types |
| 419 | such as 'UnboundType' and 'RawExpressionType' For example, see |
| 420 | NodeReplaceVisitor.process_base_func. |
| 421 | """ |
| 422 | |
| 423 | def __init__(self, replacements: dict[SymbolNode, SymbolNode]) -> None: |
| 424 | self.replacements = replacements |
| 425 | |
| 426 | def visit_instance(self, typ: Instance) -> None: |
| 427 | typ.type = self.fixup(typ.type) |
| 428 | for arg in typ.args: |
| 429 | arg.accept(self) |
| 430 | if typ.last_known_value: |
| 431 | typ.last_known_value.accept(self) |
| 432 | |
| 433 | def visit_type_alias_type(self, typ: TypeAliasType) -> None: |
| 434 | assert typ.alias is not None |
| 435 | typ.alias = self.fixup(typ.alias) |
| 436 | for arg in typ.args: |
| 437 | arg.accept(self) |
| 438 | |
| 439 | def visit_any(self, typ: AnyType) -> None: |
| 440 | pass |
| 441 | |
| 442 | def visit_none_type(self, typ: NoneType) -> None: |
| 443 | pass |
| 444 | |
| 445 | def visit_callable_type(self, typ: CallableType) -> None: |
| 446 | for arg in typ.arg_types: |
| 447 | arg.accept(self) |
| 448 | typ.ret_type.accept(self) |
| 449 | if typ.definition: |
| 450 | # No need to fixup since this is just a cross-reference. |
| 451 | typ.definition = self.replacements.get(typ.definition, typ.definition) |
| 452 | # Fallback can be None for callable types that haven't been semantically analyzed. |
| 453 | if typ.fallback is not None: |
| 454 | typ.fallback.accept(self) |
| 455 | for tv in typ.variables: |
| 456 | if isinstance(tv, TypeVarType): |
| 457 | tv.upper_bound.accept(self) |
| 458 | for value in tv.values: |
| 459 | value.accept(self) |
| 460 | |
| 461 | def visit_overloaded(self, t: Overloaded) -> None: |
| 462 | for item in t.items: |
| 463 | item.accept(self) |
| 464 | # Fallback can be None for overloaded types that haven't been semantically analyzed. |
| 465 | if t.fallback is not None: |
| 466 | t.fallback.accept(self) |
| 467 | |
| 468 | def visit_erased_type(self, t: ErasedType) -> None: |
| 469 | # This type should exist only temporarily during type inference |
| 470 | raise RuntimeError("Cannot handle erased type") |
| 471 | |
| 472 | def visit_deleted_type(self, typ: DeletedType) -> None: |
no outgoing calls
no test coverage detected
searching dependent graphs…