Ejemplo n.º 1
0
def visit_Call_get_value_from_tuple(self, node, context):
    """
    Visits a Call node
    :param node:
    :param context:
    :return:
    """

    context.append(node)
    # Localization of the function call
    localization = stypy_functions.create_localization(node.lineno,
                                                       node.col_offset)
    call_stmts = []
    arguments = []
    keyword_arguments = {}

    name_to_call = stypy_functions.get_descritive_element_name(node.func)

    # Obtain the function to be called
    call_stmts.append(
        stypy_functions.create_src_comment(
            "Call to {0}(...):".format(name_to_call), node.lineno))

    function_to_call = core_language.create_Name('stypy_get_value_from_tuple')

    if len(node.args) > 0:
        call_stmts.append(
            stypy_functions.create_src_comment("Processing the call arguments",
                                               node.lineno))
    # First call parameters are built from standard parameters plus var args (args + starargs)
    # Evaluate arguments of the call

    stmts, temp = self.visit(node.args[0], context)
    call_stmts.append(stmts)

    arguments.append(temp)
    arguments.append(node.args[1])
    arguments.append(node.args[2])

    call_stmts.append(
        stypy_functions.create_src_comment(
            "Calling {0}(tuple, tuple length, tuple pos)".format(name_to_call),
            node.lineno))
    call = functions.create_call(function_to_call,
                                 arguments,
                                 line=node.lineno,
                                 column=node.col_offset)

    assign_stmts, temp_assign = stypy_functions.create_temp_Assign(
        call,
        node.lineno,
        node.col_offset,
        descriptive_var_name="{0}_call_result".format(name_to_call))
    call_stmts.append(assign_stmts)

    return stypy_functions.flatten_lists(
        stypy_functions.create_blank_line(),
        call_stmts,
        stypy_functions.create_blank_line(),
    ), temp_assign
Ejemplo n.º 2
0
    def visit_ImportFrom(self, node):
        assign_node = []
        if hasattr(node, 'level'):
            if node.level > 0:
                module_name = SGMC.get_sgmc_full_module_name(
                    os.path.dirname(self.file_path))

                if module_name.startswith("."):
                    module_name = module_name[1:]

                if module_name.startswith("site_packages."):
                    module_name = module_name[len("site_packages."):]

                if node.level - 1 > 0:
                    parent_module_name = SGMC.get_parent_module_name(
                        module_name, node.level - 1)
                else:
                    parent_module_name = module_name

                if node.module is not None:
                    node.module = parent_module_name + "." + node.module
                else:
                    node.module = parent_module_name

                node.level = 0

        return stypy_functions.flatten_lists(node, assign_node)
    def visit_Assign(self, node):
        """
        Assign is the only visitor method that this visitor implement.
        :param node:
        :return:
        """
        assign_stmts = []
        value = node.value
        reversed_targets = node.targets
        reversed_targets.reverse()
        assign_stmts.append(stypy_functions.create_blank_line())
        if len(reversed_targets) > 1:
            assign_stmts.append(
                stypy_functions.create_src_comment(
                    "Multiple assignment of {0} elements.".format(
                        len(reversed_targets))))
        else:
            if hasattr(node, 'lineno'):
                assign_stmts.append(
                    stypy_functions.create_src_comment(
                        "Assigning a {1} to a {0} (line {2}):".format(
                            type(reversed_targets[0]).__name__,
                            type(value).__name__, node.lineno)))
            else:
                assign_stmts.append(
                    stypy_functions.create_src_comment(
                        "Assigning a {1} to a {0}:".format(
                            type(reversed_targets[0]).__name__,
                            type(value).__name__)))
        for assign_num in xrange(len(reversed_targets)):
            target = reversed_targets[assign_num]
            # Function guard is true? execute handler
            for handler_func_guard_tuple in self.__assignment_handlers:
                if handler_func_guard_tuple[0](target, value):
                    id_str, handler_func = handler_func_guard_tuple[1]
                    self.performed_transformations |= handler_func(
                        target, value, assign_stmts, node, id_str)
                    assign_stmts = stypy_functions.flatten_lists(assign_stmts)
                    value = target
                    break

        if len(assign_stmts) > 0:
            return assign_stmts
        return node
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
Ejemplo n.º 5
0
    def visit_ClassDef(self, node):
        """
        Transform class definitions to put its attribute initializers outside of the class definition
        :param node:
        :return:
        """
        self.class_attributes = filter(
            lambda element: isinstance(element, ast.Assign) or isinstance(
                element, ast.If) or (isinstance(element, ast.Expr) and type(
                    element.value) is ast.Call), node.body)

        self.class_method = filter(
            lambda element: isinstance(element, ast.FunctionDef), node.body)
        self.class_name = node.name

        attr_stmts = []
        for attr in self.class_attributes:
            separator_comment, comment = self.__extract_attribute_attached_comments(
                attr, node)
            if separator_comment is not None:
                node.body.remove(separator_comment)
                attr_stmts.append(separator_comment)

            if separator_comment is not None:
                node.body.remove(comment)
                attr_stmts.append(comment)

            node.body.remove(attr)

            if type(attr) is not ast.Assign:
                self.transform_names = True
                attr_stmts.append(self.visit(attr))
                self.transform_names = False
                continue

            if type(attr.targets[0]) is ast.Name:
                temp_class_attr = core_language.create_attribute(
                    node.name, attr.targets[0].id)
            else:
                try:
                    if type(attr.targets[0]) is ast.Subscript:
                        temp_class_attr = core_language.create_nested_attribute(
                            node.name, attr.targets[0].value)
                    else:
                        temp_class_attr = core_language.create_nested_attribute(
                            node.name, attr.targets[0])
                except Exception as ex:
                    print ex

            if not self.value_is_a_class_attribute(attr):
                self.transform_names = True
                value_var = self.visit(attr.value)
                self.transform_names = False
                attr_stmts.append(
                    core_language.create_Assign(temp_class_attr, value_var))
            else:
                if type(attr.value) is ast.Call:
                    func_name = core_language.create_nested_attribute(
                        node.name, attr.value.func)
                    attr.value.func = func_name
                    temp_class_value = attr.value
                else:
                    temp_class_value = core_language.create_nested_attribute(
                        node.name, attr.value)

                attr_stmts.append(
                    core_language.create_Assign(temp_class_attr,
                                                temp_class_value))

        # Extracting all attributes from a class may leave the program in an incorrect state if all the members in the
        # class are attributes. An empty class body is an error, we add a pass node in that special case
        if len(node.body
               ) == 0 or ClassAttributesVisitor.all_lines_are_comments(
                   node.body):
            node.body.append(stypy_functions.create_pass_node())

        return stypy_functions.flatten_lists(node, attr_stmts)