Ejemplo n.º 1
0
def get_pedal_type_from_type_literal(value, type_space=None) -> Type:
    if value == list:
        return ListType(empty=False)
    elif value == dict:
        return DictType(empty=False)
    elif isinstance(value, list):
        if value:
            return ListType(empty=False,
                            subtype=get_pedal_type_from_type_literal(
                                value[0], type_space))
        else:
            return ListType(empty=True)
    elif isinstance(value, dict):
        if not value:
            return DictType(empty=True)
        if all(isinstance(value, str) for k in value.keys()):
            return DictType(literals=[LiteralStr(s) for s in value.keys()],
                            values=[
                                get_pedal_type_from_type_literal(
                                    vv, type_space) for vv in value.values()
                            ])
        return DictType(keys=[
            get_pedal_type_from_type_literal(k, type_space)
            for k in value.keys()
        ],
                        values=[
                            get_pedal_type_from_type_literal(vv, type_space)
                            for vv in value.values()
                        ])
    elif isinstance(value, type):
        return get_pedal_type_from_str(value.__name__)
    else:
        return get_pedal_type_from_str(str(value))
Ejemplo n.º 2
0
def _builtin_zip(tifa, function_type, callee, args, position):
    """
    Definition of the built-in zip function, which consumes a series of
    sequences and returns a list of tuples, with each tuple composed of the
    elements of the sequence paired (or rather, tupled) together.
    """
    if args:
        tupled_types = TupleType(subtypes=[])
        for arg in args:
            tupled_types.subtypes.append(arg.index(0))
        return ListType(tupled_types, empty=False)
    return ListType(empty=True)
Ejemplo n.º 3
0
    def visit_List(self, node):
        """

        Args:
            node:

        Returns:

        """
        result_type = ListType()
        if node.elts:
            result_type.empty = False
            # TODO: confirm homogenous subtype
            for elt in node.elts:
                result_type.subtype = self.visit(elt)
        else:
            result_type.empty = True
        return result_type
Ejemplo n.º 4
0
def make_record(a_record) -> Type:
    if isinstance(a_record, dict):
        return DictType(
            literals=[LiteralStr(s) for s in a_record.keys()],
            values=[make_record(value) for value in a_record.values()])
    elif isinstance(a_record, list):
        return ListType(subtype=make_record(a_record[0]))
    else:
        return get_pedal_type_from_str(str(a_record))
Ejemplo n.º 5
0
def get_pedal_type_from_value(value, type_space=None) -> Type:
    """ Converts the Python value to a Pedal Type """
    if isinstance(value, bool):
        return BoolType()
    if isinstance(value, (int, float, complex)):
        return NumType()
    if isinstance(value, str):
        return StrType()
    if isinstance(value, type(None)):
        return NoneType()
    if isinstance(value, tuple):
        return TupleType(
            (get_pedal_type_from_value(t, type_space) for t in value))
    if isinstance(value, set):
        return SetType(
            (get_pedal_type_from_value(t, type_space) for t in value))
    if isinstance(value, frozenset):
        return FrozenSetType(
            (get_pedal_type_from_value(t, type_space) for t in value))
    if isinstance(value, list):
        if value:
            return ListType(empty=False,
                            subtype=get_pedal_type_from_value(value[0]))
        else:
            return ListType(empty=True)
    if isinstance(value, dict):
        if not value:
            return DictType(empty=True)
        if all(isinstance(value, str) for k in value.keys()):
            return DictType(literals=[LiteralStr(s) for s in value.keys()],
                            values=[
                                get_pedal_type_from_value(vv, type_space)
                                for vv in value.values()
                            ])
        return DictType(keys=[
            get_pedal_type_from_ast(k, type_space) for k in value.keys()
        ],
                        values=[
                            get_pedal_type_from_ast(vv, type_space)
                            for vv in value.values()
                        ])
    return UnknownType()
Ejemplo n.º 6
0
    def visit_ListComp(self, node):
        """

        Args:
            node:

        Returns:

        """
        # TODO: Handle comprehension scope
        for generator in node.generators:
            self.visit(generator)
        return ListType(self.visit(node.elt))
Ejemplo n.º 7
0
def get_pedal_type_from_json(val):
    """

    Args:
        val:

    Returns:

    """
    if val['type'] == 'DictType':
        values = [get_pedal_type_from_json(v) for v in val['values']]
        empty = val.get('empty', None)
        if 'literals' in val:
            literals = [
                get_pedal_literal_from_json(l) for l in val['literals']
            ]
            return DictType(empty, literals=literals, values=values)
        else:
            keys = [get_pedal_type_from_json(k) for k in val['keys']]
            return DictType(empty, keys=keys, values=values)
    elif val['type'] == 'ListType':
        return ListType(get_pedal_type_from_json(val.get('subtype', None)),
                        val.get('empty', None))
    elif val['type'] == 'StrType':
        return StrType(val.get('empty', None))
    elif val['type'] == 'BoolType':
        return BoolType()
    elif val['type'] == 'NoneType':
        return NoneType()
    elif val['type'] == 'NumType':
        return NumType()
    elif val['type'] == 'ModuleType':
        submodules = {
            name: get_pedal_type_from_json(m)
            for name, m in val.get('submodules', {}).items()
        }
        fields = {
            name: get_pedal_type_from_json(m)
            for name, m in val.get('fields', {}).items()
        }
        return ModuleType(name=val.get('name'),
                          submodules=submodules,
                          fields=fields)
    elif val['type'] == 'FunctionType':
        returns = get_pedal_type_from_json(
            val.get('returns', {'type': 'NoneType'}))
        return FunctionType(name=val.get('name'), returns=returns)
Ejemplo n.º 8
0
def get_builtin_function(name):
    """

    Args:
        name:

    Returns:

    """
    # Void Functions
    if name == "print":
        return FunctionType(name="print", returns=NoneType())
    # Math Functions
    elif name in ("int", "abs", "float", "len", "ord", "pow", "round", "sum"):
        return FunctionType(name=name, returns=NumType())
    # Boolean Functions
    elif name in ("bool", "all", "any", "isinstance"):
        return FunctionType(name=name, returns=BoolType())
    # String Functions
    elif name in ("str", 'chr', 'bin', 'repr', 'input'):
        return FunctionType(name=name, returns=StrType())
    # File Functions
    elif name == "open":
        return FunctionType(name="open", returns=FileType())
    # List Functions
    elif name == "map":
        return FunctionType(name="map", returns=ListType(empty=False))
    elif name == "list":
        return FunctionType(name="list",
                            definition=_builtin_sequence_constructor(ListType))
    # Set Functions
    elif name == "set":
        return FunctionType(name="set",
                            definition=_builtin_sequence_constructor(SetType))
    # Dict Functions
    elif name == "dict":
        return FunctionType(name="dict", returns=DictType())
    # Pass through
    elif name == "sorted":
        return FunctionType(name="sorted", returns='identity')
    elif name == "reversed":
        return FunctionType(name="reversed", returns='identity')
    elif name == "filter":
        return FunctionType(name="filter", returns='identity')
    # Special Functions
    elif name == "type":
        return FunctionType(name="type", returns=UnknownType())
    elif name == "range":
        return FunctionType(name="range",
                            returns=ListType(NumType(), empty=False))
    elif name == "dir":
        return FunctionType(name="dir",
                            returns=ListType(StrType(), empty=False))
    elif name == "max":
        return FunctionType(name="max", returns='element')
    elif name == "min":
        return FunctionType(name="min", returns='element')
    elif name == "zip":
        return FunctionType(name="zip", returns=_builtin_zip)
    elif name == "__import__":
        return FunctionType(name="__import__", returns=ModuleType())
    elif name == "globals":
        return FunctionType(name="globals",
                            returns=DictType(keys=StrType(),
                                             values=UnknownType(),
                                             empty=False))
    elif name in ("classmethod", "staticmethod"):
        return FunctionType(name=name, returns='identity')
    elif name in ("__name__", ):
        return StrType()
Ejemplo n.º 9
0
def get_pedal_type_from_ast(value: ast.AST, type_space=None) -> Type:
    """
    Determines the Pedal Type from this ast node.
    Args:
        value (ast.AST): An AST node.

    Returns:
        Type: A Pedal Type
    """
    try:
        if isinstance(value, ast.Constant):
            return get_pedal_type_from_value(value.value, type_space)
    except AttributeError as e:
        pass
    if isinstance(value, ast.Name):
        return get_pedal_type_from_str(value.id, type_space)
    elif isinstance(value, ast.Str):
        return StrType(bool(value.s))
    elif isinstance(value, ast.List):
        return ListType(subtype=(get_pedal_type_from_ast(
            value.elts[0], type_space) if value.elts else None),
                        empty=not bool(value.elts))
    elif isinstance(value, ast.Set):
        return SetType(subtype=(get_pedal_type_from_ast(
            value.elts[0], type_space) if value.elts else None),
                       empty=not bool(value.elts))
    elif isinstance(value, ast.Tuple):
        return TupleType(subtypes=[
            get_pedal_type_from_ast(e, type_space) for e in value.elts
        ])
    elif isinstance(value, ast.Dict):
        if not value.keys:
            return DictType(empty=True)
        if all(isinstance(k, ast.Str) for k in value.keys):
            return DictType(literals=[LiteralStr(s.s) for s in value.keys],
                            values=[
                                get_pedal_type_from_ast(vv, type_space)
                                for vv in value.values
                            ])
        return DictType(
            keys=[get_pedal_type_from_ast(k, type_space) for k in value.keys],
            values=[
                get_pedal_type_from_ast(vv, type_space) for vv in value.values
            ])
    # Support new style subscripts (e.g., ``list[int]``)
    elif ((IS_PYTHON_39 and isinstance(value, ast.Subscript))
          or isinstance(value, ast.Subscript)
          and isinstance(value.slice, ast.Index)):
        if IS_PYTHON_39:
            slice = value.slice
        else:
            slice = value.slice.value
        if isinstance(value.value, ast.Name):
            if isinstance(slice, ast.Name):
                subtype = get_pedal_type_from_str(slice.id)
                if value.value.id == "list":
                    return ListType(subtype=subtype, empty=False)
                if value.value.id == "set":
                    return SetType(subtype=subtype, empty=False)
                if value.value.id == "tuple":
                    return TupleType(subtypes=(subtype, ))
                if value.value.id == "frozenset":
                    return FrozenSetType(subtype=subtype, empty=False)
            elif isinstance(slice, ast.Tuple):
                subtypes = [
                    get_pedal_type_from_ast(e, type_space) for e in slice.elts
                ]
                if value.value.id == "tuple":
                    return TupleType(subtypes=subtypes)
                elif value.value.id == "dict" and len(subtypes) == 2:
                    return DictType(keys=subtypes[0], values=subtypes[1])
    # Top-level Module, parse it and get it back
    if isinstance(value, ast.Module) and value.body:
        if isinstance(value.body[0], ast.Expr):
            return get_pedal_type_from_ast(value.body[0].value, type_space)
    return UnknownType()