Is left a subtype of right? A few special cases such as right being 'object' are handled in is_subtype and don't need to be covered here.
| 42 | |
| 43 | |
| 44 | class SubtypeVisitor(RTypeVisitor[bool]): |
| 45 | """Is left a subtype of right? |
| 46 | |
| 47 | A few special cases such as right being 'object' are handled in |
| 48 | is_subtype and don't need to be covered here. |
| 49 | """ |
| 50 | |
| 51 | def __init__(self, right: RType, *, relaxed: bool = False) -> None: |
| 52 | self.right = right |
| 53 | self.relaxed = relaxed |
| 54 | |
| 55 | def visit_rinstance(self, left: RInstance) -> bool: |
| 56 | return isinstance(self.right, RInstance) and self.right.class_ir in left.class_ir.mro |
| 57 | |
| 58 | def visit_rvec(self, left: RVec) -> bool: |
| 59 | # TODO: Better implementation |
| 60 | return left == self.right |
| 61 | |
| 62 | def visit_runion(self, left: RUnion) -> bool: |
| 63 | return all(is_subtype(item, self.right, relaxed=self.relaxed) for item in left.items) |
| 64 | |
| 65 | def visit_rprimitive(self, left: RPrimitive) -> bool: |
| 66 | right = self.right |
| 67 | if is_bool_rprimitive(left): |
| 68 | if is_tagged(right) or is_fixed_width_rtype(right): |
| 69 | return True |
| 70 | elif is_bit_rprimitive(left): |
| 71 | if is_bool_rprimitive(right) or is_tagged(right) or is_fixed_width_rtype(right): |
| 72 | return True |
| 73 | elif is_short_int_rprimitive(left): |
| 74 | if is_int_rprimitive(right): |
| 75 | return True |
| 76 | if self.relaxed and is_fixed_width_rtype(right): |
| 77 | return True |
| 78 | elif is_int_rprimitive(left): |
| 79 | if self.relaxed and is_fixed_width_rtype(right): |
| 80 | return True |
| 81 | elif is_fixed_width_rtype(left): |
| 82 | if is_int_rprimitive(right): |
| 83 | return True |
| 84 | return left is right |
| 85 | |
| 86 | def visit_rtuple(self, left: RTuple) -> bool: |
| 87 | if is_tuple_rprimitive(self.right): |
| 88 | return True |
| 89 | if isinstance(self.right, RTuple): |
| 90 | return len(self.right.types) == len(left.types) and all( |
| 91 | is_subtype(t1, t2, relaxed=self.relaxed) |
| 92 | for t1, t2 in zip(left.types, self.right.types) |
| 93 | ) |
| 94 | return False |
| 95 | |
| 96 | def visit_rstruct(self, left: RStruct) -> bool: |
| 97 | return isinstance(self.right, RStruct) and self.right.name == left.name |
| 98 | |
| 99 | def visit_rarray(self, left: RArray) -> bool: |
| 100 | return left == self.right |
| 101 |
no outgoing calls
no test coverage detected
searching dependent graphs…