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)
def enable_usage_of_dynamic_types_warning(localization, fname=""):
    """
    Enable the warning that informs the user that dynamic types are used and therefore type inference results may not
    be accurate
    :param localization:
    :return:
    """
    TypeWarning.enable_usage_of_dynamic_types_warning(localization, fname)
    def setUp(self):
        if ROOT_PATH not in sys.path:
            sys.path.append(ROOT_PATH)

        self.file_path = CODE_GENERATION_TESTING_PROGRAMS_PATH + "/test_programs"
        StypyTypeError.reset_error_msgs()
        TypeWarning.reset_warning_msgs()
        ModuleLineNumbering.clear_cache()
        # TypeAnnotationRecord.clear_annotations()
        context.Context.module_parent_contexts = dict()
    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
    def test_read_global_variable_in_func_no_global_keyword(self):
        self.type_store.declare_global(self.loc, "global_var")
        self.type_store.declare_global(self.loc, "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())

        assert num_warnings_after == num_warnings_before + 2

        self.type_store = self.type_store.close_function_context()
Beispiel #6
0
    def test_simple_union_invoke(self):
        union = UnionType.add(int(), str())

        islower = self.type_store.get_type_of_member(self.loc, union,
                                                     "islower")
        res = invoke(self.loc, islower)

        self.assertTrue(len(TypeWarning.get_warning_msgs()) == 1)
        compare_types(res, False)
Beispiel #7
0
def is_suitable_condition(localization, condition_type):
    """
    Checks if the type of a condition is suitable. Only checks if the type of a condition is an error, except if
    coding advices is enabled. In that case a warning is issued if the condition is not bool.
    :param localization: Caller information
    :param condition_type: Type of the condition
    :return:
    """
    if is_error_type(condition_type):
        return condition_type

    if ENABLE_CODING_ADVICES:
        if not type(condition_type) is bool:
            TypeWarning.instance(localization,
                                 "The type of this condition is not boolean ({0}). Is that what you really intend?".
                                 format(condition_type))

    return True
Beispiel #8
0
    def test_call_simple_union_type_param(self):
        union_param = UnionType.create_from_type_list([int(), str(), float()])

        import math
        math_module = math
        sqrt_func = self.type_store.get_type_of_member(self.loc, math_module,
                                                       "sqrt")
        ret = invoke(self.loc, sqrt_func, union_param)

        self.assertTrue(len(TypeWarning.get_warning_msgs()) == 1)

        compare_types(ret, float())
    def test_global_var_wrong_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 = 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())

        assert num_warnings_after == num_warnings_before + 2

        self.type_store.set_type_of(self.loc, "global_var", float)
        assert len(StypyTypeError.get_error_msgs()) == 1
        self.type_store.set_type_of(self.loc, "global_func", types.NoneType)
        assert len(StypyTypeError.get_error_msgs()) == 2

        self.type_store = self.type_store.close_function_context()

        num_warnings_after = len(TypeWarning.get_warning_msgs())
        assert num_warnings_after == num_warnings_before
def ensure_slice_bounds(localization, lower, upper, step):
    """
    Check the parameters of a created slice to make sure that the slice have correct bounds. If not, it returns a
    silent TypeError, as the specific problem (invalid lower, upper or step parameter is reported separately)
    :param localization: Caller information
    :param lower: Lower bound of the slice or None
    :param upper: Upper bound of the slice or None
    :param step: Step of the slice or None
    :return: A slice object or a TypeError is its parameters are invalid
    """
    error = False
    r, w = __slice_bounds_checking(lower)

    if len(w) > 0 and len(r) > 0:
        TypeWarning(localization, "Some of the possible types of the lower bound of the slice ({0}) are invalid".
                    format(lower))
    if len(w) > 0 and len(r) == 0:
        StypyTypeError(localization, "The type of the lower bound of the slice ({0}) is invalid".format(lower))
        error = True

    r, w = __slice_bounds_checking(upper)
    if len(w) > 0 and len(r) > 0:
        TypeWarning(localization, "Some of the possible types of the upper bound of the slice ({0}) are invalid".
                    format(upper))
    if len(w) > 0 and len(r) == 0:
        StypyTypeError(localization, "The type of the upper bound of the slice ({0}) is invalid".format(upper))
        error = True

    r, w = __slice_bounds_checking(step)
    if len(w) > 0 and len(r) > 0:
        TypeWarning(localization, "Some of the possible types of the step of the slice ({0}) are invalid".
                    format(step))
    if len(w) > 0 and len(r) == 0:
        StypyTypeError(localization, "The type of the step of the slice ({0}) is invalid".format(step))
        error = True

    if not error:
        return get_builtin_python_type_instance(localization, 'slice')
    else:
        return StypyTypeError(localization, "Type error when specifying slice bounds", prints_msg=False)
    def test_existing_global_var_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 = self.type_store.open_function_context("nested_func")
        self.type_store.declare_global(self.loc, "global_var")
        self.type_store.declare_global(self.loc, "global_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

        res = self.type_store.set_type_of(self.loc, "global_var", str)
        res = self.type_store.set_type_of(self.loc, "global_func", types.NoneType)
        assert res is None
        self.type_store = self.type_store.close_function_context()
        compare_types(self.type_store.get_type_of(self.loc, "global_var"), types.StringType)
        compare_types(self.type_store.get_type_of(self.loc, "global_func"), types.NoneType)
    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 test_call_union_type(self):
        abs_func = self.context.get_type_of(self.localization, 'abs')
        union_valid = UnionType.create_from_type_list([True, complex()])
        union_mixed = UnionType.create_from_type_list([int(), list()])
        union_wrong = UnionType.create_from_type_list([dict(), list()])

        # Two valid types
        ret = invoke(self.localization, abs_func, union_valid)
        compare_types(ret, [int(), float()])

        # Two types: one valid, one invalid
        ret = invoke(self.localization, abs_func, union_mixed)
        compare_types(type(ret), int)
        assert len(TypeWarning.get_warning_msgs()) == 1

        # Two invalid types
        ret = invoke(self.localization, abs_func, union_wrong)
        compare_types(type(ret), StypyTypeError)
        assert len(StypyTypeError.get_error_msgs()) == 1
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))
Beispiel #15
0
    def test_union_invoke_return_types(self):
        class Foo:
            def method(self, localization):
                return True

            def method_2(self, localization):
                return str()

        class Foo2:
            def method(self, localization):
                return False

            def method_2(self, localization):
                return int()

        # Access a member that can be provided only by some of the types in the union
        union = UnionType.add(Foo(), Foo2())

        method = self.type_store.get_type_of_member(self.loc, union,
                                                    "method_2")
        res = invoke(self.loc, method)
        self.assertTrue(len(TypeWarning.get_warning_msgs()) == 0)

        compare_types(res, [str(), int()])
Beispiel #16
0

if __name__ == "__main__":
    # sys.argv = ['stypy_checker', 'code_tryouts.py']
    # ['stypy.py', './stypy.py']
    options = __check_args(sys.argv)

    if "-strict" in options:
        TypeWarning.warnings_as_errors = True

    tinit = time.time()
    ti_type_store, analysis_run_time = stypy_compilation_main(sys.argv)
    tend = time.time()
    if not (ti_type_store is None and analysis_run_time is None):
        errors = StypyTypeError.get_error_msgs()
        warnings = TypeWarning.get_warning_msgs()

        if len(errors) > 0:
            print("- {0} error(s) detected:\n".format(len(errors)))
            print_msgs(errors)
        else:
            print("- No errors detected.\n")

        if len(warnings) > 0:
            print("- {0} warning(s) detected:\n".format(len(warnings)))
            print_msgs(warnings)
        else:
            print("- No warnings detected.\n")

        # analyzed_program = sys.argv[1].split('\\')[-1].split('/')[-1]
        # print "'" + analyzed_program + "' type checked in {:.4f} seconds.".format(tend - tinit)
Beispiel #17
0
    def test_change_type(self):
        # Set a member on non-modifiable types
        union1 = UnionType.add(int, str)

        union1.__class__ = int

        self.assertTrue(len(StypyTypeError.get_error_msgs()) == 1)

        class Foo:
            def method(self):
                pass

            def method_2(self):
                pass

        class Foo2:
            def method(self):
                pass

            def method_2(self):
                pass

        # Set a member with some of the types of the union able to be modified
        union2 = UnionType.add(Foo(), str)

        union2.__class__ = Foo2
        self.assertTrue(len(TypeWarning.get_warning_msgs()) == 1)

        # TypeWarning.print_warning_msgs()
        union_types = map(lambda x: type(x), union2.get_types())
        compare_types(union_types, [type(Foo2()), types.TypeType])

        TypeWarning.reset_warning_msgs()

        instance1 = Foo()
        union3 = UnionType.add(instance1, str)

        instance2 = Foo2()
        union3 = UnionType.add(instance2, union3)

        union3.__class__ = Foo2

        self.assertTrue(len(TypeWarning.get_warning_msgs()) == 1)

        union_types = map(lambda x: type(x), union2.get_types())
        compare_types(union_types, [type(Foo2()), types.TypeType])

        TypeWarning.reset_warning_msgs()
        StypyTypeError.reset_error_msgs()

        # Set a member using all-modifiable types
        foo1 = Foo()
        foo2 = Foo()
        union4 = UnionType.add(foo1, foo2)

        self.assertTrue(len(TypeWarning.get_warning_msgs()) == 0)

        self.assertTrue(len(StypyTypeError.get_error_msgs()) == 0)
        self.assertTrue(len(TypeWarning.get_warning_msgs()) == 0)

        ret = union4
        compare_types(ret, foo1)
Beispiel #18
0
 def setUp(self):
     self.loc = Localization(__file__)
     StypyTypeError.reset_error_msgs()
     TypeWarning.reset_warning_msgs()
     self.type_store = Context(None, __file__)
def generic_1parameter_test(type_store,
                            var_name,
                            method_name,
                            correct_types,
                            correct_return_types,
                            incorrect_types,
                            expected_num_of_warnings,
                            expected_num_of_warnings_in_correct_calls=0):
    obj = type_store.get_type_of(Localization(__file__), var_name)
    method = type_store.get_type_of_member(Localization(__file__), obj,
                                           method_name)

    # Correct calls
    for i in range(len(correct_types)):
        result = invoke(Localization(__file__), method, correct_types[i])
        type_store.set_type_of(Localization(__file__), "result_i", result)
        compare_types(
            type_store.get_type_of(Localization(__file__), "result_i"),
            correct_return_types[i])

    # Incorrect calls
    for i in range(len(incorrect_types)):
        result = invoke(Localization(__file__), method, incorrect_types[i])
        type_store.set_type_of(Localization(__file__), "result_i", result)
        assert_if_not_error(
            type_store.get_type_of(Localization(__file__), "result_i"))

    # Incorrect calls (arity)
    for i in range(len(correct_types)):
        result = invoke(Localization(__file__), method, correct_types[i], None)
        type_store.set_type_of(Localization(__file__), "result_i", result)
        assert_if_not_error(
            type_store.get_type_of(Localization(__file__), "result_i"))

    # Union type call (all correct)
    union = create_union_type(correct_types)
    result = invoke(Localization(__file__), method, union)

    if result is StypyTypeError:
        compare_types(result, correct_return_types[0])
    else:
        expected_result = create_union_type(
            stypy_functions.flatten_lists(*correct_return_types))
        compare_types(result, expected_result)

    assertTrue(
        len(TypeWarning.get_warning_msgs()) ==
        expected_num_of_warnings_in_correct_calls,
        "got {0} warings, expected {1}".format(
            len(TypeWarning.get_warning_msgs()),
            expected_num_of_warnings_in_correct_calls))

    # Union type call (mix correct/incorrect)
    union = create_union_type(correct_types + incorrect_types)
    result = invoke(Localization(__file__), method, union)
    if result is StypyTypeError:
        compare_types(result, correct_return_types[0])
    else:
        expected_result = create_union_type(
            stypy_functions.flatten_lists(*correct_return_types))
        compare_types(result, expected_result)

    assertTrue(
        len(TypeWarning.get_warning_msgs()) == expected_num_of_warnings,
        "got {0} warings, expected {1}".format(
            len(TypeWarning.get_warning_msgs()), expected_num_of_warnings))

    TypeWarning.reset_warning_msgs()

    # Union type call (all incorrect)
    if len(incorrect_types) > 0:
        union = create_union_type(incorrect_types)
        result = invoke(Localization(__file__), method, union)
        assert_if_not_error(result)

        assertTrue(len(TypeWarning.warnings) == 0)  # All bad, no warnings
Beispiel #20
0
 def setUp(self):
     self.loc = Localization(__file__)
     StypyTypeError.reset_error_msgs()
     TypeWarning.reset_warning_msgs()
Beispiel #21
0
    def test_get_type_of_member(self):
        context = Context(None, __file__)
        # Access a member that none of the stored types has
        union1 = UnionType.add(int, str)

        ret = union1.foo

        assert_if_not_error(ret)

        class Foo:
            att1 = int

            def method(self):
                pass

            def method_2(self):
                pass

        class Foo2:
            att1 = float

            def method(self):
                pass

            def method_2(self):
                pass

        # Access a member that can be provided only by some of the types in the union
        union2 = UnionType.add(Foo, str)

        ret = union2.method
        self.assertTrue(len(TypeWarning.get_warning_msgs()) == 1)

        TypeWarning.reset_warning_msgs()
        compare_types(ret, Foo.method)

        instance1 = Foo()
        union3 = UnionType.add(instance1, str)

        instance2 = Foo2()
        union3 = UnionType.add(instance2, union3)

        ret = union3.method
        self.assertTrue(len(TypeWarning.get_warning_msgs()) == 1)

        compare_types(ret, [
            instance1.method,
            instance2.method,
        ])

        TypeWarning.reset_warning_msgs()

        # Access a member that can be provided by all the types in the union
        union4 = UnionType.add(Foo, Foo2)

        self.assertTrue(len(TypeWarning.get_warning_msgs()) == 0)

        ret = union4.method
        compare_types(ret, [Foo.method, Foo2.method])

        ret = union4.att1
        compare_types(ret, [int, float])

        # Access a member that can be provided by all the types in the union (using only Python types)
        union5 = UnionType.add(int, str)

        self.assertTrue(len(TypeWarning.get_warning_msgs()) == 0)

        context.set_type_of(self.loc, "union5", union5)

        # "__str__" is a special method so we have to use the context to access to it
        ret = context.get_type_of_member(self.loc, union5, "__str__")
        compare_types(ret, [int.__str__, str.__str__])
Beispiel #22
0
    def test_set_type_of_member(self):
        # Set a member on non-modifiable types
        union1 = UnionType.add(int, str)

        union1.foo = int

        self.assertTrue(len(StypyTypeError.get_error_msgs()) == 1)

        class Foo:
            def method(self):
                pass

            def method_2(self):
                pass

        class Foo2:
            def method(self):
                pass

            def method_2(self):
                pass

        # Set a member with some of the types of the union able to be modified
        union2 = UnionType.add(Foo, str)

        union2.member = str
        self.assertTrue(len(TypeWarning.get_warning_msgs()) == 1)

        # TypeWarning.print_warning_msgs()
        compare_types(union2.member, str)
        self.assertTrue(len(TypeWarning.get_warning_msgs()) == 2)

        TypeWarning.reset_warning_msgs()

        instance1 = Foo()
        union3 = UnionType.add(instance1, str)

        instance2 = Foo2()
        union3 = UnionType.add(instance2, union3)

        union3.member = str

        self.assertTrue(len(TypeWarning.get_warning_msgs()) == 1)

        compare_types(union3.member, str)

        TypeWarning.reset_warning_msgs()
        StypyTypeError.reset_error_msgs()

        # Set a member using all-modifiable types
        union4 = UnionType.add(Foo, Foo2)

        self.assertTrue(len(TypeWarning.get_warning_msgs()) == 0)

        union4.member = float
        self.assertTrue(len(StypyTypeError.get_error_msgs()) == 0)
        self.assertTrue(len(TypeWarning.get_warning_msgs()) == 0)

        ret = union4.member
        compare_types(ret, float)

        def obj_func(cls):
            pass

        union4.class_method = types.MethodType(obj_func, union4)

        ret = union4.class_method
        compare_types(ret, types.MethodType(obj_func, union4))
Beispiel #23
0
    def __call__(self, localization, *call_args, **call_kwargs):
        contained_elements = get_contained_elements_type(self.type_)
        if isinstance(contained_elements, union_type.UnionType):
            types_to_examine = contained_elements.types
        else:
            types_to_examine = [contained_elements]

        right_types = []
        wrong_types = []

        for type_ in types_to_examine:
            match_found = False
            for declared_contained_type in self.content_types:
                if declared_contained_type == IterableDataStructureWithTypedElements.__get_type_of(
                        type_):
                    if isinstance(declared_contained_type, DependentType):
                        declared_contained_type.set_type(type_)
                        if hasattr(declared_contained_type, 'member'):
                            declared_contained_type.member_obj = getattr(
                                type_, declared_contained_type.member)
                        if declared_contained_type.call_arity == 0:
                            correct, return_type = declared_contained_type(
                                localization)
                        else:
                            correct, return_type = declared_contained_type(
                                localization, type_)
                        if correct:
                            match_found = True
                            if type_ not in right_types:
                                right_types.append(type_)
                                if type_ in wrong_types:
                                    wrong_types.remove(type_)
                        else:
                            if type_ not in wrong_types and type_ not in right_types:
                                wrong_types.append(type_)
                    else:
                        match_found = True
                        right_types.append(type_)

            if not match_found:
                if type_ not in wrong_types and type_ not in right_types:
                    wrong_types.append(type_)

        if self.report_errors:
            # All types are wrong
            if len(right_types) == 0:
                if len(wrong_types) > 0:
                    StypyTypeError(
                        localization,
                        "None of the iterable contained types: {0} match the expected ones {1}"
                        .format(str(types_to_examine),
                                str(self.content_types)))
            else:
                if len(wrong_types) > 0:
                    TypeWarning(
                        localization,
                        "Some of the iterable contained types: {0} do not match the expected ones {1}"
                        .format(str(wrong_types), str(self.content_types)))
        else:
            if len(right_types) == 0 and len(wrong_types) > 0:
                TypeWarning(
                    localization,
                    "Some of the iterable contained types: {0} do not match the expected ones {1}"
                    .format(str(wrong_types), str(self.content_types)))

        if len(right_types) > 0:
            return True, None
        else:
            return False, wrong_types
Beispiel #24
0
    def test_change_base_types(self):
        # Set a member on non-modifiable types
        union1 = UnionType.add(int, str)

        union1.__bases__ = (int, )

        self.assertTrue(len(StypyTypeError.get_error_msgs()) == 1)

        class Foo:
            def method(self):
                pass

            def method_2(self):
                pass

        class Foo2:
            def method(self):
                pass

            def method_2(self):
                pass

        # Set a member with some of the types of the union able to be modified
        union2 = UnionType.add(Foo(), str)

        union2.__bases__ = (Foo2, )
        self.assertTrue(len(TypeWarning.get_warning_msgs()) == 1)

        # TypeWarning.print_warning_msgs()
        compare_types(union2.__bases__.types[0].contained_types, Foo2)
        compare_types(union2.__bases__.types[1].contained_types,
                      str.__bases__[0])

        TypeWarning.reset_warning_msgs()

        instance1 = Foo()
        union3 = UnionType.add(instance1, str)

        instance2 = Foo2()
        union3 = UnionType.add(instance2, union3)

        union3.__bases__ = (Foo2, )

        self.assertTrue(len(TypeWarning.get_warning_msgs()) == 1)

        compare_types(union3.__bases__.types[0].contained_types, Foo2)
        compare_types(union3.__bases__.types[1].contained_types,
                      str.__bases__[0])

        #compare_types(union3.__bases__, [(Foo2,), str.__bases__])

        TypeWarning.reset_warning_msgs()
        StypyTypeError.reset_error_msgs()

        # Set a member using all-modifiable types
        union4 = UnionType.add(Foo(), Foo())

        self.assertTrue(len(TypeWarning.get_warning_msgs()) == 0)

        union4.__bases__ = (Foo2, )
        self.assertTrue(len(StypyTypeError.get_error_msgs()) == 0)
        self.assertTrue(len(TypeWarning.get_warning_msgs()) == 0)

        ret = union4.__bases__
        compare_types(ret, (Foo2, ))
    def run_stypy_with_program(self,
                               program_file,
                               verbose=False,
                               generate_type_data_file=False,
                               output_results=False,
                               output_file=None,
                               time_stypy=False,
                               force_type_data_file=True,
                               expected_errors=0):
        route = SGMC.get_sgmc_route(program_file)
        destination_file = SGMC.sgmc_cache_absolute_path + route
        init = 0
        end = 0
        try:
            if time_stypy:
                init = time.time()

            stypy = stypy_main.Stypy(
                program_file,
                PYTHON_EXE,
                verbose,
                generate_type_data_file,
                type_inference_program_file=destination_file,
                is_main=True)
            result = stypy.analyze()
            if time_stypy:
                end = time.time()
        except SystemExit as se:
            return -2

        file_ = None
        if output_file is not None:
            file_ = open(output_file, "w")

        if type(result) is StypyTypeError:
            self.print_output(
                "AN ERROR OCURRED WHILE ANALYZING TYPE INFERENCE FILES:\n",
                file_)
            self.print_output(result, file_)
            if output_file is not None:
                file_.close()

            return -3  # Analysis error

        ti_type_store = stypy.get_analyzed_program_type_store()

        if output_results or verbose:
            self.print_output("\n*************** Type store *************** ",
                              file_)
            self.print_output(ti_type_store, file_)

            self.print_output("\n*************** Errors *************** ",
                              file_)
            errors = stypy.get_analyzed_program_errors()

            if len(errors) > 0:
                self.print_output("{0} errors detected:\n".format(len(errors)),
                                  file_)
                err_count = 1
                for error in errors:
                    self.print_output(
                        str(err_count) + ": " + str(error) + "\n", file_)
                    err_count += 1
            else:
                self.print_output("No errors detected.", file_)

            if StypyTypeError.type_error_limit_hit:
                print(
                    "MAXIMUM LIMIT OF REPORTED ERRORS REACHED: NOT ALL TYPE ERRORS WERE CAPTURED"
                )

            self.print_output("\n*************** Warnings *************** ",
                              file_)
            # Pack warnings
            TypeWarning.pack_warnings()
            stypy.analyzed_program_warnings = TypeWarning.get_warning_msgs()

            warnings = stypy.get_analyzed_program_warnings()
            if len(warnings) > 0:
                self.print_output(
                    "{0} warnings detected:\n".format(len(warnings)), file_)
                warn_count = 1
                for warning in warnings:
                    self.print_output(
                        str(warn_count) + ": " + str(warning) + "\n", file_)
                    warn_count += 1
            else:
                self.print_output("No warnings detected.", file_)

                self.print_output("\n", file_)

            if TypeWarning.type_warning_limit_hit:
                print(
                    "MAXIMUM LIMIT OF REPORTED WARNINGS REACHED: NOT ALL TYPE WARNINGS WERE CAPTURED"
                )

        if output_file is not None:
            file_.close()

        if time_stypy:
            print("Stypy analyzed the program in " + str(end - init) +
                  " seconds.")
        if ti_type_store is None:
            return None
        else:
            ret = check_type_store(ti_type_store, program_file, verbose,
                                   force_type_data_file)
            if not force_type_data_file:
                if len(stypy.get_analyzed_program_errors()) > 0:
                    # If no type data file is present, we can test for a number of expected type errors in the programs
                    if expected_errors == len(
                            stypy.get_analyzed_program_errors()):
                        return 0
                    return -2  # Errors exist in the analysis
                else:
                    return 0  # No error

            return ret
Beispiel #26
0
 def __init__(self):
     TypeWarning.enable_usage_of_recursion_warning()