예제 #1
0
    def infer_types(module: astroid.Module, node_type: type,
                    expr: Callable) -> Dict[astroid.node_classes.NodeNG, str]:
        """
        Infer the types of an attribute of all nodes of the same type in a module.

        :param module: The module node where all nodes are located in.
        :param node_type: Type of node of which the type will be inferred on a certain attribute.
        :param expr: Expression to extract the attribute from the node where the type will be
            inferred on. E.g., lambda node: node.func.expr.name
        :return: All nodes in the module of type 'node_type' with the inferred type of the attribute
            accessible with the expression 'expr'.
        """
        nodes = ASTUtil.search_nodes(module, node_type)
        source_code = ASTUtil.get_source_code(module)
        mypy_code = TypeInference.add_reveal_type_calls(
            source_code, nodes, expr)
        mypy_result = TypeInference.run_mypy(mypy_code)
        try:
            mypy_types = TypeInference.parse_mypy_result(mypy_result)
        except SyntaxError as ex:
            mypy_code_split = mypy_code.splitlines()
            faulty_code = mypy_code_split[int(ex.lineno) - 1]
            if "; reveal_type(" in faulty_code:
                original_code = faulty_code.split("; reveal_type(")[0]
                mypy_code_split[int(ex.lineno) - 1] = original_code
                mypy_types = TypeInference.parse_mypy_result(
                    "\n".join(mypy_code_split))
                return TypeInference.combine_nodes_with_inferred_types(
                    nodes, mypy_types)
            else:
                print("Skipping type checking of module {}: {}. Line {}: {}".
                      format(module.name, ex.msg, ex.lineno, faulty_code))
                return {}
        return TypeInference.combine_nodes_with_inferred_types(
            nodes, mypy_types)
예제 #2
0
 def test_search_body(self):
     """Test whether the correct body is returned."""
     module_tree = astroid.parse("""
         f()
         """)
     node = module_tree.body[0]
     assert ASTUtil.search_body(node) == module_tree.body
예제 #3
0
 def test_search_body_parent_module(self):
     """Test whether the module is returned when searching for the parent of its child."""
     module_tree = astroid.parse("""
         f()
         """)
     node = module_tree.body[0]
     assert ASTUtil.search_body_parent(node) == module_tree
예제 #4
0
 def test_search_body_parent_function(self):
     """Test whether the function is returned when searching for the parent of its child."""
     module_tree = astroid.parse("""
         def f():
             return 0
         """)
     node = module_tree.body[0].body[0]
     assert ASTUtil.search_body_parent(node) == module_tree.body[0]
예제 #5
0
    def handle(checker: BaseChecker, node: astroid.node_classes.NodeNG):
        """
        Handle a generic exception thrown in a checker by printing an error message.

        :param checker: Checker where the exception is thrown from.
        :param node: Node which is visited while the exception is thrown.
        """
        module = ASTUtil.search_module(node)
        print(
            "ERROR: Could not finish processing the checker {} on module {}. Continuing."
            .format(checker.name, module.name))
예제 #6
0
    def test_search_nodes(self):
        """Test the search_nodes method."""
        module_tree = astroid.parse("""
            a = b.c(d)

            def e(f):
                return g.h(i)
            """)
        found = ASTUtil.search_nodes(module_tree, astroid.Call)
        # noinspection PyUnresolvedReferences
        assert len(found) == 2 and found[0].func.attrname == "c" and found[
            1].func.attrname == "h"
예제 #7
0
 def test_get_source_code(self):
     """Test the get_source_code method."""
     source_code = "a = b.c(d)"
     module_tree = astroid.parse(source_code)
     assert ASTUtil.get_source_code(module_tree) == source_code