Whitelist some special cases for use in isinstance() with improper types.
(right: ProperType)
| 77 | |
| 78 | |
| 79 | def is_special_target(right: ProperType) -> bool: |
| 80 | """Whitelist some special cases for use in isinstance() with improper types.""" |
| 81 | if isinstance(right, FunctionLike) and right.is_type_obj(): |
| 82 | if right.type_object().fullname == "builtins.tuple": |
| 83 | # Used with Union[Type, Tuple[Type, ...]]. |
| 84 | return True |
| 85 | if right.type_object().fullname in ( |
| 86 | "mypy.types.Type", |
| 87 | "mypy.types.ProperType", |
| 88 | "mypy.types.TypeAliasType", |
| 89 | ): |
| 90 | # Special case: things like assert isinstance(typ, ProperType) are always OK. |
| 91 | return True |
| 92 | if right.type_object().fullname in ( |
| 93 | "mypy.types.UnboundType", |
| 94 | "mypy.types.TypeVarLikeType", |
| 95 | "mypy.types.TypeVarType", |
| 96 | "mypy.types.UnpackType", |
| 97 | "mypy.types.TypeVarTupleType", |
| 98 | "mypy.types.ParamSpecType", |
| 99 | "mypy.types.Parameters", |
| 100 | "mypy.types.RawExpressionType", |
| 101 | "mypy.types.EllipsisType", |
| 102 | "mypy.types.StarType", |
| 103 | "mypy.types.TypeList", |
| 104 | "mypy.types.CallableArgument", |
| 105 | "mypy.types.PartialType", |
| 106 | "mypy.types.ErasedType", |
| 107 | "mypy.types.DeletedType", |
| 108 | "mypy.types.RequiredType", |
| 109 | "mypy.types.ReadOnlyType", |
| 110 | "mypy.types.TypeGuardedType", |
| 111 | "mypy.types.PlaceholderType", |
| 112 | ): |
| 113 | # Special case: these are not valid targets for a type alias and thus safe. |
| 114 | # TODO: introduce a SyntheticType base to simplify this? |
| 115 | return True |
| 116 | elif isinstance(right, TupleType): |
| 117 | return all(is_special_target(t) for t in get_proper_types(right.items)) |
| 118 | return False |
| 119 | |
| 120 | |
| 121 | def is_improper_type(typ: Type) -> bool: |
no test coverage detected
searching dependent graphs…