def test_integer_list_constant(self): input = [1, 2, 3] node = ast.parse(str(input)).body[0].value expected_output = ListType(Type.int) typeanalyser = TypeAnalyser(Analyser(node), {}) output = typeanalyser.get_type(input) self.assertEqual(expected_output, output)
def test_boolean_list_constant(self): input = [True, False] node = ast.parse(str(input)).body[0].value expected_output = ListType(Type.bool) typeanalyser = TypeAnalyser(Analyser(node), {}) output = typeanalyser.get_type(input) self.assertEqual(expected_output, output)
def test_any_list_constant(self): input = [1, '2', False] node = ast.parse(str(input)).body[0].value expected_output = ListType(UnionType.build([Type.int, Type.str])) typeanalyser = TypeAnalyser(Analyser(node), {}) output = typeanalyser.get_type(input) self.assertEqual(expected_output, output)
class Type: @classmethod def builtin_types(cls) -> Dict[str, IType]: """ Gets a dictionary that maps each type with its name :return: A dictionary that maps each Python builtin type representation with its name """ builtin_types = [ Type.int, Type.bool, Type.str, Type.list, Type.tuple, Type.dict, Type.range, Type.bytes, Type.bytearray, Type.none ] return { tpe._identifier: tpe for tpe in builtin_types if isinstance(tpe, IType) } @classmethod def all_types(cls) -> Dict[str, IType]: return { tpe._identifier: tpe for tpe in vars(cls).values() if isinstance(tpe, IType) } @classmethod def get_type(cls, value: Any) -> IType: """ Returns the type of the given value. :param value: value to get the type :return: Returns the type of the value. `Type.none` by default. """ val: IType = None for type in vars(cls).values(): if isinstance(type, IType) and type.is_type_of(value): val = type.build(value) break if val is not None: return val return cls.none @classmethod def get_generic_type(cls, *types: IType) -> IType: """ Returns the common generic type between the given values. :param types: list of type to be compared :return: Returns the common generic type of the values if exist. `Type.any` otherwise. """ generic = cls.any if len(types) > 0: generic_types = [cls.mutableSequence, cls.mapping, cls.sequence] generic_types.append( generic) # any type must be the last value in the list generic = types[0] for tpe in types[1:]: if generic == tpe or generic.is_type_of(tpe): continue if tpe.is_type_of(generic): generic = tpe continue for gen in generic_types: if gen.is_type_of(generic) and gen.is_type_of(tpe): generic = gen break if generic is Type.any: break return generic # Builtin Types int = IntType() bool = BoolType() str = StrType() none = NoneType() bytes = BytesType() bytearray = ByteArrayType() tuple = TupleType() list = ListType() dict = DictType() range = RangeType(int) # Generic types sequence = GenericSequenceType() mutableSequence = GenericMutableSequenceType() mapping = GenericMappingType() exception = BaseExceptionType() any = anyType