A representation of a type constraint. It can be either T <: type or T :> type (T is a type variable).
| 69 | |
| 70 | |
| 71 | class Constraint: |
| 72 | """A representation of a type constraint. |
| 73 | |
| 74 | It can be either T <: type or T :> type (T is a type variable). |
| 75 | """ |
| 76 | |
| 77 | type_var: TypeVarId |
| 78 | op = 0 # SUBTYPE_OF or SUPERTYPE_OF |
| 79 | target: Type |
| 80 | |
| 81 | def __init__(self, type_var: TypeVarLikeType, op: int, target: Type) -> None: |
| 82 | self.type_var = type_var.id |
| 83 | self.op = op |
| 84 | # TODO: should we add "assert not isinstance(target, UnpackType)"? |
| 85 | # UnpackType is a synthetic type, and is never valid as a constraint target. |
| 86 | self.target = target |
| 87 | self.origin_type_var = type_var |
| 88 | # These are additional type variables that should be solved for together with type_var. |
| 89 | # TODO: A cleaner solution may be to modify the return type of infer_constraints() |
| 90 | # to include these instead, but this is a rather big refactoring. |
| 91 | self.extra_tvars: list[TypeVarLikeType] = [] |
| 92 | |
| 93 | def __repr__(self) -> str: |
| 94 | op_str = "<:" |
| 95 | if self.op == SUPERTYPE_OF: |
| 96 | op_str = ":>" |
| 97 | return f"{self.type_var} {op_str} {self.target}" |
| 98 | |
| 99 | def __hash__(self) -> int: |
| 100 | return hash((self.type_var, self.op, self.target)) |
| 101 | |
| 102 | def __eq__(self, other: object) -> bool: |
| 103 | if not isinstance(other, Constraint): |
| 104 | return False |
| 105 | return (self.type_var, self.op, self.target) == (other.type_var, other.op, other.target) |
| 106 | |
| 107 | |
| 108 | def infer_constraints_for_callable( |
no outgoing calls
searching dependent graphs…