예제 #1
0
def del_contained_elements_type(proxy_obj, value):
    """
    Deletes the contained element types that correspond to a certain key type (for dictionaries)
    :param proxy_obj:
    :param value:
    :return:
    """
    if can_store_elements(proxy_obj) or can_store_keypairs(proxy_obj):
        try:
            if type(proxy_obj) is TypeWrapper:
                delitem = proxy_obj.get_type_of_member('__delitem__')
                if isinstance(delitem, StypyTypeError):
                    return delitem
                else:
                    return stypy.type_inference_programs.stypy_interface.invoke(
                        Localization.get_current(), delitem, value)
            else:
                if not hasattr(proxy_obj, '__delitem__'):
                    return StypyTypeError(
                        Localization.get_current(),
                        "Trying to remove elements on a non-container type")
        except:
            return StypyTypeError(
                Localization.get_current(),
                "Trying to remove elements on a non-container type")
    else:
        return StypyTypeError(
            Localization.get_current(),
            "Trying to remove elements on a non-container type")
예제 #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
예제 #3
0
def set_contained_elements_type_for_key(proxy_obj, key, new_type):
    """
    Set the contained element types that correspond to a certain key type (for dictionaries)
    :param proxy_obj:
    :param key:
    :param new_type:
    :return:
    """
    if isinstance(proxy_obj, union_type.UnionType):
        return proxy_obj.set_contained_type_for_key(key, new_type)

    if hasattr(proxy_obj, '__setitem__'):
        existing_type = get_contained_elements_type_for_key(proxy_obj, key)
        if existing_type is undefined_type.UndefinedType:
            if proxy_obj is os.environ and key == '':
                return proxy_obj.__setitem__(' ', new_type)
            if is_type_inference_file_object(proxy_obj):
                return proxy_obj.__setitem__(Localization.get_current(), key,
                                             new_type)
            return proxy_obj.__setitem__(key, new_type)
        else:
            existing_type = union_type.UnionType.add(existing_type, new_type)
            if is_type_inference_file_object(proxy_obj):
                return proxy_obj.__setitem__(Localization.get_current(), key,
                                             existing_type)
            return proxy_obj.__setitem__(key, existing_type)
    else:
        return None
예제 #4
0
def __join_ssa_branches_types_of_members_for_object(obj, previous_context,
                                                    branch1, branch2):
    """
    Implementation of the SSA joining algorithm for two SSA branches, handling types of members
    :param previous_context:
    :param branch1: dict(obj, dict(name, type))
    :param branch2:
    :return:
    """
    type_dict = dict()

    # NOTE: Explanations in comments are done with an if/else control structure. Other structures are the same.

    # Proceed with the first branch (if)

    # For any variable stored in the first branch (note that we only deal with variables that change its type in the
    # active branch, not all the possible variables accessible within the SSA context. This is also a major speedup
    # over our previous version.
    for var_name in branch1:
        if var_name in branch2:
            # Variable defined in if and else body: Joins both types
            type_dict[var_name] = UnionType.add(branch1[var_name],
                                                branch2[var_name])
        else:
            # Variable defined in if and in the previous context: Joins the previous type and the if one
            previous_type = previous_context.get_type_of_member(
                Localization.get_current(), obj, var_name)
            if not isinstance(previous_type, StypyTypeError):
                type_dict[var_name] = UnionType.add(previous_type,
                                                    branch1[var_name])
            else:
                # Variable defined in if body, but did not exist in the previous context: Joins the if type with an
                # undefined type, as the if could not be executed
                type_dict[var_name] = UnionType.add(branch1[var_name],
                                                    UndefinedType)
                StypyTypeError.remove_error_msg(previous_type)

    # Now proceed with the second branch (else). If no else is present and empty dict is passed, and therefore no
    # processing is done.

    for var_name in branch2:
        if var_name in branch1:
            continue  # Already processed (above)
        else:
            # Variable defined only in the else body and in the previous context: Treat equally to the if branch
            # counterpart
            previous_type = previous_context.get_type_of_member(
                Localization.get_current(), obj, var_name)
            if not isinstance(previous_type, StypyTypeError):
                type_dict[var_name] = UnionType.add(previous_type,
                                                    branch2[var_name])
            else:
                # Variable defined in else body, but did not existed in the previous context: Same treatment as their
                # if branch counterpart
                type_dict[var_name] = UnionType.add(branch2[var_name],
                                                    UndefinedType)
                StypyTypeError.remove_error_msg(previous_type)

    # type_store_previous does not need to be iterated because it is included in the if and else stores
    return type_dict
예제 #5
0
    def del_member(self, name):
        """
        Deletes the member name from all the types in the union that declare it
        :param name:
        :return:
        """
        errors = []

        for type_ in self.types:
            type_ = stypy_types.type_intercession.del_member(
                Localization.get_current(), type_, name)
            if isinstance(type_, StypyTypeError):
                errors.append(type_)

        # If all types contained in the union do not have this member, the whole access is an error.
        if len(errors) == len(self.types):
            for error in errors:
                StypyTypeError.remove_error_msg(error)

            return StypyTypeError.no_type_can_delete_member_error(
                Localization.get_current(), self.types, name)
        else:
            # If not all the types return an error when accessing the members, the policy is different:
            # - Notified errors are turned to warnings in the general error log
            # - ErrorTypes are eliminated.
            for error in errors:
                error.turn_to_warning()

        return None
예제 #6
0
    def has_member(self, localization, obj, name):
        """
        Gets the type of the specified member name for the object obj, looking on its parent context if not found
        on its own type store
        :param localization:
        :param obj:
        :param name:
        :return:
        """
        try:
            # Lookup inside our types
            self.__get_hash(obj)
            if obj in self.types_of_members:
                obj = self.types_of_members[self.__get_hash(obj)][name]
                return True
        except KeyError:
            # If not found, lookup our parent context (if any) recursively
            if self.parent_context is not None:
                return self.parent_context.has_member(
                    Localization.get_current(), obj, name)
        except Exception as exc:
            try:
                # Lookup inside our types
                if id(obj) in self.types_of_members:
                    obj = self.types_of_members[id(obj)][name]
                    return True
            except KeyError:
                # If not found, lookup our parent context (if any) recursively
                if self.parent_context is not None:
                    return self.parent_context.has_member(
                        Localization.get_current(), obj, name)

        return super(SSAContext, self).has_member(localization, obj, name)
예제 #7
0
def get_contained_elements_type(proxy_obj,
                                multi_assign_arity=-1,
                                multi_assign_index=-1):
    """
    Get the type of the contained elements of the passed type
    :param proxy_obj:
    :return:
    """

    if type(proxy_obj) is file:
        return str()

    if type(proxy_obj) is type_groups.type_groups.DynamicType:
        return proxy_obj

    # Direct containers
    if type(proxy_obj) in types_that_store_contents_directly:
        try:
            return proxy_obj[0]
        except:
            return undefined_type.UndefinedType

    # Wrappers
    if isinstance(proxy_obj, TypeWrapper):
        if proxy_obj.can_store_elements():
            if proxy_obj.can_store_keypairs() and type(
                    proxy_obj.wrapped_type) is dict:
                return union_type.UnionType.create_from_type_list(
                    proxy_obj.wrapped_type.keys())

            if type(proxy_obj.wrapped_type
                    ) in types_that_store_contents_directly:
                try:
                    return proxy_obj.wrapped_type[0]
                except:
                    return undefined_type.UndefinedType
            return proxy_obj.get_contained_type(multi_assign_arity,
                                                multi_assign_index)

    else:
        if type(proxy_obj) is str:
            return str()
        else:
            # Other classes that define __setitem__
            m_get = get_getitem_method(proxy_obj)
            if m_get is not None:
                try:
                    return m_get(Localization.get_current(), *[int()])
                except TypeError:
                    return m_get(*[int()])

        # Error: Containers must be wrapped
        if proxy_obj is not None:
            return StypyTypeError(
                Localization.get_current(),
                "Elements of type '{0}' cannot contain types".format(
                    format_type(proxy_obj)))
        else:
            return StypyTypeError(Localization.get_current(),
                                  "The provided type cannot contain elements")
def set_member_to_object(localization, obj, name, value):
    """
    Sets the member name from the object obj to value
    :param localization:
    :param obj:
    :param name:
    :param value:
    :return:
    """
    if is_error(obj):
        return obj
    try:
        Localization.set_current(localization)
        if isinstance(obj, contexts.context.Context):
            return obj.set_type_of(localization, name, value)

        if isinstance(obj, TypeWrapper) and obj.is_declared_member(name):
            return obj.set_type_of_member(name, value)

        if name in reserved_members:
            try:
                set_attr(obj, name, value)
                return
            except:
                set_attr(obj, '__stypy'+ name, value)
                return
        set_attr(obj, name, value)
    except Exception as exc:
        return StypyTypeError.member_cannot_be_set_error(localization, obj, name, value, str(exc))
def generic_0parameter_test(type_store, var_name, method_name,
                            correct_return_type):
    obj = type_store.get_type_of(Localization(__file__), var_name)
    method = type_store.get_type_of_member(Localization(__file__), obj,
                                           method_name)

    result = invoke(Localization(__file__), method)

    compare_types(result, correct_return_type)
    def test_use_global_in_global_context_after_usage(self):
        self.type_store.set_type_of(self.loc, "global_var", int)
        self.type_store.set_type_of(self.loc, "global_func", types.FunctionType)
        self.type_store.declare_global(Localization(__file__, 1, 1), "global_var")
        self.type_store.declare_global(Localization(__file__, 2, 2), "global_func")

        compare_types(self.type_store.get_type_of(Localization(__file__, 3, 3), "global_var"), types.IntType)
        compare_types(self.type_store.get_type_of(Localization(__file__, 4, 4), "global_func"), types.FunctionType)

        assert len(Advice.get_advice_msgs()) == 2
예제 #11
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 test_local_variable_turned_global_before(self):
        self.type_store.declare_global(Localization(__file__, 1, 1), "global_var")
        self.type_store.set_type_of(Localization(__file__, 2, 2), "global_var", int)

        self.type_store = self.type_store.open_function_context("nested_func")
        num_warnings_before = len(TypeWarning.get_warning_msgs())
        compare_types(self.type_store.get_type_of(Localization(__file__, 3, 3), "global_var"), types.IntType)
        num_warnings_after = len(TypeWarning.get_warning_msgs())

        assert num_warnings_after == num_warnings_before + 1

        self.type_store.declare_global(Localization(__file__, 4, 4), "global_var")
        assert len(Advice.get_advice_msgs()) == 2

        self.type_store.declare_global(self.loc, "non_existing")

        assert_if_not_error(self.type_store.get_type_of(Localization(__file__, 5, 5), "non_existing"))

        self.type_store.declare_global(Localization(__file__, 6, 6), "foo")
        self.type_store.set_type_of(Localization(__file__, 7, 7), "foo", int)
        assert len(Advice.get_advice_msgs()) == 4

        self.type_store.declare_global(Localization(__file__, 8, 8), "foo_func")
        self.type_store.set_type_of(Localization(__file__, 9, 9), "foo_func", types.FunctionType)
        assert len(Advice.get_advice_msgs()) == 5

        compare_types(self.type_store.get_type_of(self.loc, "foo"), types.IntType)
        compare_types(self.type_store.get_type_of(self.loc, "foo_func"), types.FunctionType)
        self.type_store = self.type_store.close_function_context()

        compare_types(self.type_store.get_type_of(self.loc, "foo"), types.IntType)
        compare_types(self.type_store.get_type_of(self.loc, "foo_func"), types.FunctionType)
예제 #13
0
    def __eq__(self, type_):
        for member in self.members:
            if is_special_name_method(member):
                converted_name = convert_special_name_method(member)
                if has_member(Localization.get_current(), type_,
                              converted_name):
                    return False

            if has_member(Localization.get_current(), type_, member):
                return False

        return True
예제 #14
0
    def analyze(self):
        """
        Main stypy function. Performs all the steps to analyze the source file types in order
        """
        if self.verbose:
            info("Parsing file '" + self.source_file_path + "'\n")

        try:
            existing_ts = contexts.context.Context.get_current_active_context_for_module(self.source_file_path)
            if existing_ts is not None:
                self.analyzed_program_type_store = existing_ts
                return existing_ts
        except:
            pass

        # Obtain the AST of the source file
        # self.get_original_source_file_ast()

        # If a type data file have to be generated and the source file is suitable to do so, do it
        # if self.generate_type_data_file:
        #     if Stypy.__is_file_suitable_for_autocalculate_types(self.source_file_path):
        #         self.create_automatic_type_data_autogenerator_program()

        # Create the type inference program
        self.create_type_inference_program()

        try:
            return self.run_type_inference()
        except Exception as exc:
            return type_error.StypyTypeError(Localization.get_current(), exc.message)
예제 #15
0
def get_contained_elements_type_for_key(proxy_obj, key):
    """
    Get the contained element types that correspond to a certain key type (for dictionaries)
    :param proxy_obj:
    :param key:
    :return:
    """
    if isinstance(proxy_obj, union_type.UnionType):
        return proxy_obj.get_contained_type_for_key(key)

    if hasattr(proxy_obj, '__getitem__'):
        try:
            if is_type_inference_file_object(proxy_obj):
                return proxy_obj.__getitem__(Localization.get_current(), key)
            try:
                return proxy_obj.__getitem__(key)
            except KeyError:
                ks = proxy_obj.items()
                for k in ks:
                    if type(k[0]) is type(key):
                        return k[1]
                return undefined_type.UndefinedType
        except Exception as exc:
            return undefined_type.UndefinedType
    else:
        return None
예제 #16
0
    def __init__(self, localization, msg, prints_msg=True, snap=None):
        """
        Creates a warning with the provided message.
        :param localization: Caller information
        :param msg: Warning message
        :param prints_msg: As TypeErrors, TypeWarnings can also be silent if reporting them is not activated
        :return:
        """
        self.packed = False
        self.display_message = ""
        self.message = msg
        self.other_stack_traces = []
        if localization is None:
            localization = Localization(__file__, 1, 0)

        self.localization = localization
        if snap is None:
            self.stack_trace_snapshot = localization.stack_trace.get_snapshot()
        else:
            self.stack_trace_snapshot = snap

        # Create the message here to capture the execution point, as stack traces are dynamic.
        self.warn_msg = self.__msg()

        if (stypy_parameters.MAX_TYPE_WARNINGS > 0) and len(
                TypeWarning.warnings) > stypy_parameters.MAX_TYPE_WARNINGS:
            TypeWarning.type_warning_limit_hit = True
            return

        if prints_msg and self not in TypeWarning.warnings:
            TypeWarning.warnings.append(self)
예제 #17
0
    def del_member(self, localization, obj, name):
        """
        Deletes the type of the specified member name for the object obj, looking on its parent context if not found
        on its own type store
        :param localization:
        :param obj:
        :param name:
        :return:
        """
        try:
            if self.on_ssa:
                # Lookup inside our types
                if self.__get_hash(obj) not in self.types_of_members:
                    self.types_of_members[self.__get_hash(obj)] = dict()

                self.types_of_members[self.__get_hash(
                    obj)][name] = UndefinedType
                return None
            else:
                # Lookup inside our types
                del self.types_of_members[self.__get_hash(obj)][name]
                return None
        except KeyError:
            # If not found, lookup our parent context (if any) recursively
            if self.parent_context is not None:
                return self.parent_context.del_member(
                    Localization.get_current(), obj, name)

        return super(SSAContext, self).del_member(localization, obj, name)
예제 #18
0
    def get_type_of_member(self, name):
        """
        Get the type of the member name of the types of the union (if different types has the same member name with
        different types, a union type with all the possible types is returned).
        :param name:
        :return:
        """
        types_to_return = []
        errors = []

        # Add all the results of get_type_of_member for all stored types in a list
        for type_ in self.types:
            type_ = stypy_types.type_intercession.get_member(
                Localization.get_current(), type_, name)
            if isinstance(type_, StypyTypeError):
                errors.append(type_)
            else:
                types_to_return.append(type_)

        all_errors = len(errors) == len(self.types)

        if all_errors:
            return StypyTypeError.no_type_has_member_error(
                Localization.get_current(), self.types, name)
        else:
            # If there is an error, it means that the obtained member could be undefined in one of the contained
            # objects
            # if len(errors) > 0:
            #     types_to_return.append(UndefinedType)

            # If not all the types return an error when accessing the members, the policy is different:
            # - Notified errors are turned to warnings in the general error log, as there are combinations of types
            # that are valid
            # - ErrorTypes are eliminated from the error collection.
            for error in errors:
                error.turn_to_warning()

        # Calculate return type: If there is only one type, return it. If there are several types, return a
        # UnionType with all of them contained
        if len(types_to_return) == 1:
            return types_to_return[0]
        else:
            ret_union = None
            for type_ in types_to_return:
                ret_union = UnionType.add(ret_union, type_)

            return ret_union
예제 #19
0
    def __eq__(self, type_):
        if is_special_name_method(self.member):
            converted_name = convert_special_name_method(self.member)
            if has_member(Localization.get_current(), type_, converted_name):
                self.member_obj = get_member(Localization.get_current(), type_,
                                             converted_name)
                return True
            else:
                self.member_obj = None

        if has_member(Localization.get_current(), type_, self.member):
            self.member_obj = get_member(Localization.get_current(), type_,
                                         self.member)
            return True
        else:
            self.member_obj = None

        return False
예제 #20
0
    def __init__(self, localization=None, msg="", prints_msg=True):
        """
        Creates a particular instance of a type error amd adds it to the error list
        :param localization: Caller information
        :param msg: Error to report to the user
        :param prints_msg: Determines if this error is silent (report its message) or not. Some error are silent
        because they are generated to generate a more accurate TypeError later once the program determines that
        TypeErrors exist on certain places of the analyzed program. This is used in certain situations to avoid
        reporting the same error multiple times
        :return:
        """

        # This happens when a declared class has its parent inferred as an error type. If that happens, the class is
        # built using this constructor as a base class initializer. We throw an error indicating the issue and do not
        # build a standard error in this case.
        if type(localization) is str:
            StypyTypeError(
                Localization.get_current(),
                "The parent class of class '" + localization + "' is an error")
            return

        self.message = msg

        if localization is None:
            localization = Localization(__file__, 1, 0)

        self.localization = localization
        self.stack_trace_snapshot = localization.stack_trace.get_snapshot()

        # The error_msg is the full error to report to the user, composed by the passed msg and the stack trace.
        # We calculate it here to "capture" the precise execution point when the error is produced as stack trace is
        # dynamic and changes during the execution
        self.error_msg = self.__msg()

        if (stypy_parameters.MAX_TYPE_ERRORS > 0) and len(
                StypyTypeError.errors) > stypy_parameters.MAX_TYPE_ERRORS:
            StypyTypeError.type_error_limit_hit = True
            return

        # Add this error to the general error list if not already present
        if prints_msg and self not in StypyTypeError.errors:
            StypyTypeError.errors.append(self)
def get_member_from_object(localization, obj, name):
    """
    Get the member name from the object obj
    :param localization:
    :param obj:
    :param name:
    :return:
    """
    if is_error(obj):
        return obj

    Localization.set_current(localization)
    if isinstance(obj, contexts.context.Context):
        return obj.get_type_of(localization, name)

    if isinstance(obj, TypeWrapper) and (obj.is_declared_member(name) or name == '__getitem__'):
        try:
            return obj.get_type_of_member(name)
        except Exception as ex:
            return StypyTypeError.member_not_defined_error(localization, obj, name)

    if has_attr(obj, name):
        ret_type = type_inference_programs.stypy_interface.wrap_type(get_attr(obj, name))
        if name == '__bases__':
            base_type = None
            bases = obj.__bases__
            if not isinstance(bases, tuple):
                bases = (bases,)
            for type_ in bases:
                base_type = types.union_type.UnionType.add(base_type, type_)
            type_containers.set_contained_elements_type(ret_type, base_type)

        return ret_type

    if isinstance(obj, invokation.type_rules.type_groups.type_groups.DynamicType) or \
            (type(obj) is invokation.type_rules.type_groups.type_groups.DynamicType):
        return invokation.type_rules.type_groups.type_groups.DynamicType()

    # Variable not found
    return StypyTypeError.member_not_defined_error(localization, obj, name)
예제 #22
0
    def has_member(self, name):
        """
        Determines if any of the types in the union has the passed member name
        :param name:
        :return:
        """
        for type_ in self.types:
            type_ = stypy_types.type_intercession.get_member(
                Localization.get_current(), type_, name)
            if not isinstance(type_, StypyTypeError):
                return True

        return False
    def test_wrong_global_keyword_in_func(self):
        self.type_store.declare_global(Localization(__file__, 1, 1), "global_var")
        self.type_store.declare_global(Localization(__file__, 2, 2), "global_func")

        self.type_store.set_type_of(self.loc, "global_var", int)
        self.type_store.set_type_of(self.loc, "global_func", types.FunctionType)

        self.type_store = self.type_store.open_function_context("nested_func")
        num_warnings_before = len(TypeWarning.get_warning_msgs())
        compare_types(self.type_store.get_type_of(self.loc, "global_var"), types.IntType)
        compare_types(self.type_store.get_type_of(self.loc, "global_func"), types.FunctionType)
        num_warnings_after = len(TypeWarning.get_warning_msgs())

        # TypeWarning.print_warning_msgs()
        assert num_warnings_after == num_warnings_before + 2

        self.type_store.declare_global(Localization(__file__, 3, 3), "global_var")
        assert len(Advice.get_advice_msgs()) == 3

        self.type_store.declare_global(Localization(__file__, 4, 4), "global_func")
        assert len(Advice.get_advice_msgs()) == 4

        self.type_store = self.type_store.close_function_context()
def del_member_from_object(localization, obj, name):
    """
    Removes the member name from the object obj
    :param localization:
    :param obj:
    :param name:
    :return:
    """
    if is_error(obj):
        return obj
    try:
        Localization.set_current(localization)
        if isinstance(obj, TypeWrapper):
            if has_attr(obj, '__delitem__'):
                return type_inference_programs.stypy_interface.invoke(localization, obj.__delitem__, [name])
            if obj.is_declared_member(name):
                return obj.del_member(name)

        member_type = get_member(localization, obj, name)

        if isinstance(member_type, types.union_type.UnionType):
            if types.undefined_type.UndefinedType in member_type:
                TypeWarning(localization,
                            "Attempt to delete the potentially unexisting member '{0}' from an object".format(name))
        if isinstance(member_type, StypyTypeError):
            return member_type

        if isinstance(obj, contexts.context.Context):
            obj.del_type_of(localization, name)
            return

        del_attr(obj, name)
    except Exception as exc:
        if isinstance(obj, invokation.type_rules.type_groups.type_groups.DynamicType):
            return invokation.type_rules.type_groups.type_groups.DynamicType()
        return StypyTypeError.member_cannot_be_deleted_error(localization, obj, name, str(exc))
    def setUp(self):
        try:
            delattr(ClassA, "class_attribute")
        except:
            pass
        try:
            delattr(ClassA, "class_attribute2")
        except:
            pass
        try:
            delattr(ClassA, "class_attribute3")
        except:
            pass

        self.localization = Localization(__file__, 1, 1)
        self.context = SSAContext(None)
        self.context.set_type_of(self.localization, "var1", ClassA)
        self.context.set_type_of(self.localization, "var2", ClassA)
예제 #26
0
 def __delattr__(self, name):
     """
         For all the types stored in the union type, set the type of the member named member_name to the type
         specified in member_value. For example,
         if a UnionType has the types Class1 and Class2, both with the member "attr" so Class1.attr: int and
         Class2.attr: str, this method, if passsed a float as member_value will turn both classes "attr" to float.
         :param name: Name of the member to set
         :return None or a TypeError if the member cannot be set. Warnings are generated if the member of some of the
         stored objects cannot be set
     """
     # Class is writable over the contained members
     if name in object.__getattribute__(
             self, "declared_members") and not name == "__class__":
         try:
             object.__delattr__(self, name)
         except Exception as exc:
             return StypyTypeError.member_cannot_be_deleted_error(
                 Localization.get_current(), self, name, exc)
     else:
         return self.del_member(name)
    def test_use_global_in_global_context(self):
        num_warnings_before = len(TypeWarning.get_warning_msgs())
        self.type_store.declare_global(Localization(__file__, 1, 1), "global_var")
        self.type_store.declare_global(Localization(__file__, 2, 2), "global_func")

        self.type_store.set_type_of(Localization(__file__, 3, 3), "global_var", int)
        self.type_store.set_type_of(Localization(__file__, 4, 4), "global_func", types.FunctionType)

        compare_types(self.type_store.get_type_of(Localization(__file__, 5, 5), "global_var"), types.IntType)
        compare_types(self.type_store.get_type_of(Localization(__file__, 6, 6), "global_func"), types.FunctionType)
        num_warnings_after = len(TypeWarning.get_warning_msgs())

        assert len(Advice.get_advice_msgs()) == 2

        assert num_warnings_after == num_warnings_before
예제 #28
0
def set_contained_elements_type(proxy_obj, new_type):
    """
    Set the contained elements of a container
    :param proxy_obj:
    :param new_type:
    :return:
    """

    if type(proxy_obj) is type_groups.type_groups.DynamicType:
        return

    # Direct containers
    if type(proxy_obj) in types_that_store_contents_directly:
        try:
            if len(proxy_obj) > 0:
                return proxy_obj.__setitem__(0, new_type)
            else:
                return proxy_obj.append(new_type)
        except:
            pass

    # Wrappers
    if isinstance(proxy_obj, TypeWrapper):
        if type(proxy_obj.wrapped_type) in types_that_store_contents_directly:
            try:
                if len(proxy_obj.wrapped_type) > 0:
                    return proxy_obj.wrapped_type.__setitem__(0, new_type)
                else:
                    if hasattr(proxy_obj.wrapped_type, 'append'):
                        return proxy_obj.wrapped_type.append(new_type)
                    if isinstance(proxy_obj.wrapped_type, set):
                        proxy_obj.wrapped_type.add(new_type)
            except:
                pass

        return proxy_obj.set_contained_type(new_type)

    return StypyTypeError(
        Localization.get_current(),
        "Elements of type '{0}' cannot contain types".format(
            format_type(proxy_obj)))
    def setUp(self):
        self.instanceA = ClassA()
        self.instanceB = ClassB()

        try:
            delattr(self.instanceA, "instance_attribute")
        except:
            pass
        try:
            delattr(self.instanceA, "instance_attribute2")
        except:
            pass
        try:
            delattr(self.instanceA, "instance_attribute3")
        except:
            pass

        self.context = SSAContext(None)
        self.localization = Localization(__file__, 1, 1)

        self.context.set_type_of(self.localization, "var1", self.instanceA)
        self.context.set_type_of(self.localization, "var2", self.instanceA)
예제 #30
0
    def set_contained_type(self, type_):
        """
        Sets the contained types of all the types in the union
        :return:
        """
        errors = []
        for t in self.types:
            ret = stypy_types.type_containers.set_contained_elements_type(
                t, type_)
            if isinstance(ret, StypyTypeError):
                errors.append(ret)

        if len(errors) == len(self.types):
            for e in errors:
                StypyTypeError.remove_error_msg(e)
            return StypyTypeError(
                Localization.get_current(),
                "None of the possible types is able to store elements of type {0}"
                .format(type_))
        else:
            for e in errors:
                e.turn_to_warning()