def __add__(localization, proxy_obj, arguments):
        ret_type = get_builtin_python_type_instance(localization, 'list')

        existing_type = get_contained_elements_type(get_self(proxy_obj))
        params = arguments[0]
        if can_store_elements(params):
            if existing_type is not None:
                if not isinstance(existing_type, union_type.UnionType):
                    new_type = existing_type
                else:
                    new_type = existing_type.duplicate()
            else:
                new_type = None
            other_type = get_contained_elements_type(params)
            if not isinstance(other_type, union_type.UnionType):
                other_type = [other_type]
            else:
                other_type = other_type.types

            for par in other_type:
                new_type = union_type.UnionType.add(new_type, par)
        else:
            new_type = union_type.UnionType.add(existing_type, arguments[0])

        set_contained_elements_type(ret_type, new_type)

        return ret_type
Beispiel #2
0
def will_iterate_loop(localization, condition_type):
    """
    A loop must iterate an iterable object or data structure or an string. This function checks if the iterable object
    is empty (its contents are of the type UndefinedType). In that case, it does not iterate
    :param localization: Caller information
    :param condition_type: Type of the condition
    :return:
    """
    if is_error_type(condition_type):
        return False

    if type(condition_type) is file:
        return True

    if condition_type is undefined_type.UndefinedType:
        return False

    if (can_store_elements(condition_type) or (
            can_represent_type(IterableObject, condition_type)) or call_utilities.is_iterable(condition_type)):
        try:
            Localization.set_current(localization)
            t = get_contained_elements_type(condition_type)
            if type(t) is undefined_type.UndefinedType or t is undefined_type.UndefinedType:
                return False
        except:
            pass

        return True

    return True
Beispiel #3
0
def is_suitable_for_loop_condition(localization, condition_type):
    """
    A loop must iterate an iterable object or data structure or an string. This function checks this
    :param localization: Caller information
    :param condition_type: Type of the condition
    :return:
    """
    if is_error_type(condition_type):
        return False

    if type(condition_type) is RecursionType:
        return False

    if type(condition_type) is file:
        return True

    if condition_type is undefined_type.UndefinedType:
        return False

    if not (can_store_elements(condition_type) or can_represent_type(Str, condition_type) or (
            can_represent_type(IterableObject, condition_type)) or call_utilities.is_iterable(condition_type)):
        StypyTypeError(localization, "The type of this for loop condition is erroneous")
        return False

    return True
    def nan_to_num(localization, proxy_obj, arguments):
        if RealNumber == type(arguments[0]):
            return call_utilities.cast_to_numpy_type(arguments[0])
        if can_store_elements(arguments[0]):
            return call_utilities.create_numpy_array(
                get_contained_elements_type(arguments[0]))

        return call_utilities.create_numpy_array(arguments[0].wrapped_type)
def turn_to_type(obj):
    """
    As in our type analysis process we may have to deal with code whose sources are not available, calls to this code
    must be performed so we can obtain return values that can be used in our program analysis. This code is responsible
     of turning the values obtained from these calls to its types so stypy is able to use its return types to analyze
     the program.
    :param obj:
    :return:
    """
    # Already wrapped: it is already a type
    if type(obj) is StandardWrapper:
        return obj
    if type(obj) in types_without_value:
        obj = type(obj)()

    wrapped_obj = wrap_contained_type(obj)

    # Special handling for dicts and similar
    if type_containers.can_store_keypairs(wrapped_obj):
        collected_items = dict()
        keys = obj.keys()
        for key in keys:
            values_for_key = type_containers.get_contained_elements_type_for_key(obj, key)
            key_type = turn_to_type(key)
            value_types = turn_to_type(values_for_key)
            try:
                existing_values = collected_items[key_type]
            except:
                existing_values = None

            collected_items[key_type] = UnionType.add(value_types, existing_values)

        for key in keys:
            del obj[key]

        for key, value in collected_items.items():
            type_containers.set_contained_elements_type_for_key(wrapped_obj, key, value)

        return wrapped_obj

    # Special handling for containers
    if type_containers.can_store_elements(wrapped_obj):
        union_contained = None
        for elem in obj:
            elem = turn_to_type(elem)
            if elem is type:
                union_contained = UnionType.add(union_contained, elem)
            else:
                try:
                    union_contained = UnionType.add(union_contained, known_python_types.get_sample_instance_for_type(
                        type(elem).__name__))
                except Exception as exc:
                    union_contained = UnionType.add(union_contained, elem)

        wrapped_obj.set_contained_type(union_contained)
        return wrapped_obj

    return obj
Beispiel #6
0
def get_type_of_for_loop_variable(localization, condition_type):
    """
    A loop must iterate an iterable object or data structure or an string. This function returns the contents of
    whatever the loop is iterating
    :param localization: Caller information
    :param condition_type: Type of the condition
    :return:
    """

    if type(condition_type) is RecursionType:
        return condition_type

    if type(condition_type) is StypyTypeError:
        return condition_type

    if type(condition_type) is types.FileType:
        return str()

    if condition_type is undefined_type.UndefinedType:
        return condition_type

    if can_store_keypairs(condition_type):
        return wrap_contained_type(get_key_types(condition_type))

    # If the type of the condition can store elements, return the type of stored elements
    if can_store_elements(condition_type):
        Localization.set_current(localization)
        return wrap_contained_type(get_contained_elements_type(condition_type))

    # If the type of the condition is some kind of string, return the type of string
    if can_represent_type(Str, condition_type):
        return wrap_contained_type(condition_type)

    # If the type of the condition is something iterable, return the result of calling its __iter__ method
    if can_represent_type(IterableObject, condition_type):
        iter_method = condition_type.get_type_of_member(localization, "__iter__")
        return wrap_contained_type(stypy_interface.invoke(localization, iter_method))

    if call_utilities.is_numpy_array(condition_type):
        return condition_type.get_contained_type()
    if call_utilities.is_ndenumerate(condition_type):
        contained = None
        for typ in condition_type.iter.coords:
            contained = union_type.UnionType.add(contained, typ)

        t = wrap_contained_type((contained,))
        t.set_contained_type(contained)
        return union_type.UnionType.add(t, numpy.int32)

    if call_utilities.is_ndindex(condition_type):
        t = wrap_contained_type((numpy.int32(),))
        t.set_contained_type(numpy.int32())
        return t

    return StypyTypeError(localization, "Invalid iterable type for a loop target ({0})".format(str(condition_type)))
    def __setslice__(localization, proxy_obj, arguments):
        existing_type = get_contained_elements_type(get_self(proxy_obj))
        params = arguments[2]
        if can_store_elements(params):
            new_type = existing_type
            other_type = get_contained_elements_type(params)
            if not isinstance(other_type, collections.Iterable):
                other_type = [other_type]
            for par in other_type:
                new_type = union_type.UnionType.add(new_type, par)
        else:
            new_type = union_type.UnionType.add(existing_type, arguments[2])

        set_contained_elements_type(get_self(proxy_obj), new_type)

        return types.NoneType
    def extend(localization, proxy_obj, arguments):
        existing_type = get_contained_elements_type(get_self(proxy_obj))
        params = arguments[0]
        if can_store_elements(params):
            new_type = existing_type
            other_type = get_contained_elements_type(params)
            if not isinstance(other_type, collections.Iterable):
                other_type = [other_type]
            for par in other_type:
                new_type = union_type.UnionType.add(new_type, par)
        else:
            return StypyTypeError.wrong_parameter_type_error(
                localization, "iterable",
                type(params).__name__)

        set_contained_elements_type(get_self(proxy_obj), new_type)

        return types.NoneType
    def __repr__(self):
        """
        str operator overload
        :return:
        """
        txt = type(self.wrapped_type).__name__
        if can_store_keypairs(self):
            txt += "{"
            keys = get_key_types(self)
            if is_union_type(keys):
                keys = keys.get_types()
            else:
                keys = list(keys)

            if len(keys) == 0:
                txt += "UndefinedType"
            else:
                for key in keys:
                    values = get_contained_elements_type_for_key(self, key)
                    if not isinstance(values, TypeWrapper):
                        contents = type(values).__name__
                    else:
                        contents = str(values)
                    txt += type(key).__name__ + ": " + contents + "; "
                txt = txt[:-2]
            return txt + "}\n"

        if can_store_elements(self):
            contained_type = get_contained_elements_type(self)
            if not isinstance(contained_type, TypeWrapper):
                if is_undefined(contained_type):
                    contents = "UndefinedType"
                else:
                    contents = type(contained_type).__name__
            else:
                contents = str(contained_type)
            return txt + "[" + contents + "]"

        return txt
    def defaultdict(localization, proxy_obj, arguments):
        ret = StandardWrapper(defaultdict())
        ret.stypy_default_value = types.NoneType
        if len(arguments) == 0:
            return ret

        if len(arguments) == 2:
            if hasattr(arguments[1], 'wrapped_type') and type(
                    arguments[1].wrapped_type) is defaultdict:
                d = arguments[1]
            else:
                d = StandardWrapper(dict())
                set_contained_elements_type_for_key(
                    d, get_contained_elements_type(arguments[1]),
                    get_contained_elements_type(arguments[1]))
            return StandardWrapper(defaultdict(arguments[0], d))
        else:
            if can_store_keypairs(arguments[0]):
                if compare_type(arguments[0], types.DictProxyType):
                    if isinstance(arguments[0], StandardWrapper):
                        contents = arguments[0].get_wrapped_type()
                    else:
                        contents = arguments[0]
                    ret = defaultdict(contents)
                    ret.stypy_default_value = contents
                    ret = StandardWrapper(ret)
                    return ret

                return arguments[0]
            else:
                if can_store_elements(arguments[0]):
                    contents = get_contained_elements_type(arguments[0])
                    if not compare_type(contents, tuple):
                        return StypyTypeError.object_must_be_type_error(
                            localization,
                            'Iterable argument to build a dictionary',
                            '(key,value) tuple')
                    else:
                        keys = get_contained_elements_type(contents)
                        values = keys
                        if isinstance(keys, union_type.UnionType):
                            keys = keys.types
                        else:
                            keys = [keys]

                        for key in keys:
                            set_contained_elements_type_for_key(
                                ret, key, values)

                        return ret
                else:
                    ret.setdefault(arguments[0])
                    if arguments[0] is types.NoneType:
                        ret.stypy_default_value = arguments[0]
                    else:
                        if hasattr(arguments[0], '__name__'):
                            ret.stypy_default_value = get_builtin_python_type_instance(
                                localization, arguments[0].__name__)
                        else:
                            return StypyTypeError(
                                localization,
                                "Invalid first parameter of defaultdict constructor: it must be a type or None"
                            )
                    return ret
def __set_contained_elements_type(localization, container, elements):
    """
    Modifies the types stored by a container, not dealing with union type indexes
    :param localization:
    :param container:
    :param elements:
    :return:
    """
    Localization.set_current(localization)
    if is_error_type(container):
        return container
    try:
        if type(elements) is tuple:
            # Key, value data structures
            if type_containers.can_store_keypairs(container):
                return type_containers.set_contained_elements_type_for_key(container, elements[0], elements[1])

            # Indexable data structures
            if type_containers.can_store_elements(container):
                if not type_group_generator.Integer == type(elements[0]):
                    if not hasattr(container, '__index__'):
                        # Ellipsis
                        if not (type_inspection.compare_type(elements[0], slice) and (type_inspection.compare_type(
                                elements[1], slice) or type_inspection.compare_type(
                            elements[1], list))):
                            return StypyTypeError(localization,
                                                  "Indexes of indexable containers must be Integers or instances that "
                                                  "implement the __index__ method")
                    else:
                        index_getter = getattr(container, '__index__')
                        if index_getter is not None:
                            if hasattr(index_getter,
                                       '__objclass__') and not index_getter.__objclass__.__name__ == "ndarray":
                                # res = invoke(localization, container, '__index__')
                                res = invoke(localization, index_getter)
                                if not type_group_generator.Integer == type(res):
                                    return StypyTypeError(localization,
                                                          "Indexes of indexable containers must be Integers or instances that "
                                                          "implement the __index__ method")

            else:
                # Other classes that define __setitem__
                m_set = type_containers.get_setitem_method(container)
                if m_set is not None:
                    try:
                        return m_set(localization, *elements)
                    except TypeError:
                        return m_set(*elements)

            if type_containers.is_slice(elements[0]):
                if type_containers.can_store_elements(elements[1]):
                    return type_containers.set_contained_elements_type(container,
                                                                       type_containers.get_contained_elements_type(
                                                                           elements[1]))
                else:
                    return type_containers.set_contained_elements_type(container, elements[1])
            else:
                return type_containers.set_contained_elements_type(container, elements[1])

        type_containers.set_contained_elements_type(container, elements)
    except Exception as ex:
        return StypyTypeError(localization, "Cannot store elements '{1}' into an object of type '{0}': {2}".format(
            type(container), str(elements), str(ex))
                              )