コード例 #1
0
    def test_message_loop_complex(self):
        src = """
        y = 0
        x = 10
        for y in range(1, 10):
            x = func(y)
            print(x)
        x = 10
        """
        mod = astroid.parse(src)
        mod.accept(CFGVisitor())
        assign_y, assign_x1, assign_x2, assign_x3 = mod.nodes_of_class(
            astroid.Assign)

        self.checker.visit_module(mod)
        with self.assertAddsMessages(
                pylint.testutils.Message(
                    msg_id='redundant-assignment',
                    node=assign_y,
                ),
                pylint.testutils.Message(
                    msg_id='redundant-assignment',
                    node=assign_x1,
                ),
        ):
            self.checker.visit_assign(assign_y)
            self.checker.visit_assign(assign_x1)
            self.checker.visit_assign(assign_x2)
            self.checker.visit_assign(assign_x3)
コード例 #2
0
    def test_message_complex(self):
        src = """
        def test(x):
            if True:
                y = 10
            else:
                for j in range(10):
                    if j > 10:
                        break
                else:
                    y = 10
            return y
        """
        mod = astroid.parse(src)
        mod.accept(CFGVisitor())
        func_node = mod.body[0]
        _, _, name_node_y = mod.nodes_of_class(astroid.Name)

        self.checker.visit_functiondef(func_node)
        with self.assertAddsMessages(
                pylint.testutils.Message(
                    msg_id='possibly-undefined',
                    node=name_node_y,
                ), ):
            self.checker.visit_name(name_node_y)
コード例 #3
0
def main(filepath: str) -> None:
    filename = os.path.splitext(os.path.basename(filepath))[0]
    mod = AstroidBuilder().file_build(filepath)
    visitor = CFGVisitor()
    mod.accept(visitor)

    display(visitor.cfgs, filename)
コード例 #4
0
def build_cfgs(
    src: str
) -> Dict[Union[nodes.FunctionDef, nodes.Module], ControlFlowGraph]:
    mod = astroid.parse(src)
    t = CFGVisitor()
    mod.accept(t)
    return t.cfgs
コード例 #5
0
ファイル: test_unreachable.py プロジェクト: pyta-uoft/pyta
def build_cfg(src: str, is_function: Optional[bool] = False) -> ControlFlowGraph:
    """<is_function> == True guarantees that the function node is the first node
    in the module."""
    mod = astroid.parse(src)
    t = CFGVisitor()
    mod.accept(t)
    if is_function:
        return t.cfgs[mod.body[0]]
    return t.cfgs[mod]
コード例 #6
0
 def test_no_message_loop(self):
     src = """
     y = 5
     while y > 5:
         x = 10
         print(x)
     """
     mod = astroid.parse(src)
     mod.accept(CFGVisitor())
     _, assign_x, *_ = mod.nodes_of_class(astroid.Assign)
     self.checker.visit_module(mod)
     with self.assertNoMessages():
         self.checker.visit_assign(assign_x)
コード例 #7
0
    def test_no_messages_simple(self):
        src = """
        x = 10
        print(x)
        x = 10
        """
        mod = astroid.parse(src)
        mod.accept(CFGVisitor())
        assign_1, *_ = mod.nodes_of_class(astroid.Assign)

        with self.assertNoMessages():
            self.checker.visit_module(mod)
            self.checker.visit_assign(assign_1)
コード例 #8
0
    def test_no_message_loop_(self):
        src = """
        y = 0
        for y in range(1, 10):
            x = 10
        """
        mod = astroid.parse(src)
        mod.accept(CFGVisitor())
        _, assign_x, *_ = mod.nodes_of_class(astroid.Assign)
        print(assign_x.as_string())

        self.checker.visit_module(mod)
        with self.assertNoMessages():
            self.checker.visit_assign(assign_x)
コード例 #9
0
    def test_augassign_simple_no_message(self):
        src = """
        y_pos = 5
        y_pos += 10
        """
        mod = astroid.parse(src)
        mod.accept(CFGVisitor())

        self.checker.visit_module(mod)
        with self.assertNoMessages():
            for node in mod.nodes_of_class(astroid.Assign):
                self.checker.visit_assign(node)
            for node in mod.nodes_of_class(astroid.AugAssign):
                self.checker.visit_augassign(node)
コード例 #10
0
    def test_no_messages_with_args(self):
        src = """
        def test(x):
            if True:
                x = 10
            print(x)
        """
        mod = astroid.parse(src)
        mod.accept(CFGVisitor())
        func_node = mod.body[0]
        _, name_node_x = mod.nodes_of_class(astroid.Name)

        with self.assertNoMessages():
            self.checker.visit_functiondef(func_node)
            self.checker.visit_name(name_node_x)
コード例 #11
0
    def test_with_comprehension(self):
        src = """
        def func(lst):
            test = [x for x in lst]
            x = 0
            print(x)
        """
        mod = astroid.parse(src)
        mod.accept(CFGVisitor())
        func_node = mod.body[0]
        # expression `x` at line `test = ...`
        name_node_x = next(func_node.nodes_of_class(astroid.Name))

        self.checker.visit_functiondef(func_node)
        with self.assertNoMessages():
            self.checker.visit_name(name_node_x)
コード例 #12
0
    def test_with_dict_comprehension(self):
        src = """
        def func(lst):
            test = {key:val for key, val in lst}
            key = 0
            print(key)
        """
        mod = astroid.parse(src)
        mod.accept(CFGVisitor())
        func_node = mod.body[0]
        # expression `key` at line `test = ...`
        name_node_key = next(func_node.nodes_of_class(nodes.Name))

        self.checker.visit_functiondef(func_node)
        with self.assertNoMessages():
            self.checker.visit_name(name_node_key)
コード例 #13
0
    def test_no_messages_if_else_with_ann_assign(self):
        src = """
        def test(x):
            if True:
                y: int = 10
            else:
                y = 20
            print(y)
        """
        mod = astroid.parse(src)
        mod.accept(CFGVisitor())
        func_node = mod.body[0]
        _, _, name_node_y = mod.nodes_of_class(astroid.Name)

        with self.assertNoMessages():
            self.checker.visit_functiondef(func_node)
            self.checker.visit_name(name_node_y)
コード例 #14
0
    def test_no_messages_with_nonlocal(self):
        src = """
        def test(x):
            x = 10
            nonlocal y
            if True:
                y = 10
            print(y)
        """
        mod = astroid.parse(src)
        mod.accept(CFGVisitor())
        func_node = mod.body[0]
        __, name_node_y = mod.nodes_of_class(nodes.Name)

        with self.assertNoMessages():
            self.checker.visit_functiondef(func_node)
            self.checker.visit_name(name_node_y)
コード例 #15
0
    def test_augassign_redundant(self):
        src = """
        y_pos = 5
        y_pos += 10
        y_pos = 10
        """
        mod = astroid.parse(src)
        mod.accept(CFGVisitor())
        augassign_node, *_ = mod.nodes_of_class(astroid.AugAssign)

        self.checker.visit_module(mod)
        with self.assertAddsMessages(
                pylint.testutils.Message(
                    msg_id='redundant-assignment',
                    node=augassign_node,
                )):
            self.checker.visit_augassign(augassign_node)
コード例 #16
0
    def test_message_simple(self):
        src = """
        x = 10
        x = 230
        print(x)
        """
        mod = astroid.parse(src)
        mod.accept(CFGVisitor())
        assign_1, _ = mod.nodes_of_class(astroid.Assign)

        self.checker.visit_module(mod)
        with self.assertAddsMessages(
                pylint.testutils.Message(
                    msg_id='redundant-assignment',
                    node=assign_1,
                ), ):
            self.checker.visit_assign(assign_1)
コード例 #17
0
    def test_no_message_function_def(self):
        src = """
        x = 10
        if False:
            x = 20
        else:
            def func():
                x = 1
        print(x)
        """
        mod = astroid.parse(src)
        mod.accept(CFGVisitor())
        assign_x, *_ = mod.nodes_of_class(astroid.Assign)

        self.checker.visit_module(mod)
        with self.assertNoMessages():
            self.checker.visit_assign(assign_x)
コード例 #18
0
    def test_no_message_loop_complex(self):
        src = """
        x = 10
        for y in range(1, 10):
            x = func(y)
            print(x)
        x = x - 1
        """
        mod = astroid.parse(src)
        mod.accept(CFGVisitor())
        assign_x1, assign_x2, assign_x3 = mod.nodes_of_class(astroid.Assign)

        self.checker.visit_module(mod)
        with self.assertNoMessages():
            self.checker.visit_assign(assign_x1)
            self.checker.visit_assign(assign_x2)
            self.checker.visit_assign(assign_x3)
コード例 #19
0
    def test_no_messages_simple(self):
        src = """
        def test(x):
            x = 10
            if True:
                return x
            return x
        """
        mod = astroid.parse(src)
        mod.accept(CFGVisitor())
        func_node = mod.body[0]
        name_node_a, name_node_b = mod.nodes_of_class(astroid.Name)

        with self.assertNoMessages():
            self.checker.visit_module(mod)
            self.checker.visit_functiondef(func_node)
            self.checker.visit_name(name_node_a)
            self.checker.visit_name(name_node_b)
コード例 #20
0
    def test_message_with_func_name(self):
        src = """
        if True:
            pass
        else:
            y = lambda: 20
        y()
        """
        mod = astroid.parse(src)
        mod.accept(CFGVisitor())
        *_, name_node_y = mod.nodes_of_class(astroid.Name)

        self.checker.visit_module(mod)
        with self.assertAddsMessages(
                pylint.testutils.Message(
                    msg_id='possibly-undefined',
                    node=name_node_y,
                ), ):
            self.checker.visit_name(name_node_y)
コード例 #21
0
    def test_no_message_if_complex(self):
        src = """
        x = 10
        y = 5
        if y > 5:
            x = 20
        elif y > 50:
            x = 15
        else:
            pass
        print(x)
        """
        mod = astroid.parse(src)
        mod.accept(CFGVisitor())
        assign_x, *_ = mod.nodes_of_class(astroid.Assign)

        self.checker.visit_module(mod)
        with self.assertNoMessages():
            self.checker.visit_assign(assign_x)
コード例 #22
0
    def test_message_with_args(self):
        src = """
        def test(x):
            if True:
                del x
            print(x)
        """
        mod = astroid.parse(src)
        mod.accept(CFGVisitor())
        func_node = mod.body[0]
        _, name_node_x = mod.nodes_of_class(astroid.Name)

        self.checker.visit_functiondef(func_node)
        with self.assertAddsMessages(
                pylint.testutils.Message(
                    msg_id='possibly-undefined',
                    node=name_node_x,
                ), ):
            self.checker.visit_name(name_node_x)
コード例 #23
0
    def test_message_with_del_simple(self):
        src = """
        def test(x):
            y = 0
            del y
            print(y)
        """
        mod = astroid.parse(src)
        mod.accept(CFGVisitor())
        func_node = mod.body[0]
        _, name_node_y = mod.nodes_of_class(nodes.Name)

        self.checker.visit_functiondef(func_node)
        with self.assertAddsMessages(
                pylint.testutils.MessageTest(msg_id="possibly-undefined",
                                             node=name_node_y),
                ignore_position=True,
        ):
            self.checker.visit_name(name_node_y)
コード例 #24
0
    def test_no_messages_with_class_def(self):
        """This example is a false negative due to how class definitions are
        represented in the control flow graph."""
        src = """
        class A:
            y = 10
            
        if True:
            x = 10
        else:
            y = 20
        print(y)
        """
        mod = astroid.parse(src)
        mod.accept(CFGVisitor())
        _, name_node_y = mod.nodes_of_class(astroid.Name)

        self.checker.visit_module(mod)
        with self.assertNoMessages():
            self.checker.visit_name(name_node_y)
コード例 #25
0
    def test_assign(self):
        src = """
        def func():
            if False:
                x = 10
            x = x + 1
        """
        mod = astroid.parse(src)
        mod.accept(CFGVisitor())
        func_node = mod.body[0]
        name_node_x = next(func_node.nodes_of_class(astroid.Name))
        print(list(func_node.nodes_of_class(astroid.Name)))

        self.checker.visit_functiondef(func_node)
        with self.assertAddsMessages(
                pylint.testutils.Message(
                    msg_id='possibly-undefined',
                    node=name_node_x,
                )):
            self.checker.visit_name(name_node_x)
コード例 #26
0
 def test_no_messages_with_import_from(self):
     src = """
     from random import j
     
     y = 0
     if y > 10:
         j = 10
     else:
         y = 5
     print(j)
     """
     mod = astroid.parse(src)
     mod.accept(CFGVisitor())
     name_node_y, name_node_print, name_node_j = mod.nodes_of_class(
         astroid.Name)
     with self.assertNoMessages():
         self.checker.visit_module(mod)
         self.checker.visit_name(name_node_y)
         self.checker.visit_name(name_node_print)
         self.checker.visit_name(name_node_j)
コード例 #27
0
    def test_message_scope(self):
        src = """
        x = 25
        def func():
            def func2():
                print(x - 1)
            func2()
        x = 10
        func()
        """
        mod = astroid.parse(src)
        mod.accept(CFGVisitor())
        assign_x, *_ = mod.nodes_of_class(astroid.Assign)

        self.checker.visit_module(mod)
        with self.assertAddsMessages(
                pylint.testutils.Message(
                    msg_id='redundant-assignment',
                    node=assign_x,
                )):
            self.checker.visit_assign(assign_x)
コード例 #28
0
    def test_multiple_messages_simple(self):
        src = """
        if True:
            y: int = 10
        else:
            x = 10
        print(x and y)
        """
        mod = astroid.parse(src)
        mod.accept(CFGVisitor())
        _, _, name_node_x, name_node_y = mod.nodes_of_class(nodes.Name)

        self.checker.visit_module(mod)
        with self.assertAddsMessages(
                pylint.testutils.MessageTest(msg_id="possibly-undefined",
                                             node=name_node_y),
                pylint.testutils.MessageTest(msg_id="possibly-undefined",
                                             node=name_node_x),
                ignore_position=True,
        ):
            self.checker.visit_name(name_node_y)
            self.checker.visit_name(name_node_x)
コード例 #29
0
    def test_message_if_stmt(self):
        src = """
        x = 10
        y = 5
        if y > 5:
            x = 20
        else:
            x = 15
        print(x)
            
        """
        mod = astroid.parse(src)
        mod.accept(CFGVisitor())
        assign_x, *_ = mod.nodes_of_class(astroid.Assign)

        self.checker.visit_module(mod)
        with self.assertAddsMessages(
                pylint.testutils.Message(
                    msg_id='redundant-assignment',
                    node=assign_x,
                ), ):
            self.checker.visit_assign(assign_x)
コード例 #30
0
    def test_no_messages_complex(self):
        src = """
        def test(x):
            if True:
                y = 10
            else:
                for j in range(10):
                    if j > 10:
                        y = 10
                        break
                else:
                    y = 10
            return y
        """
        mod = astroid.parse(src)
        mod.accept(CFGVisitor())
        func_node = mod.body[0]
        _, _, name_node_y = mod.nodes_of_class(astroid.Name)

        with self.assertNoMessages():
            self.checker.visit_functiondef(func_node)
            self.checker.visit_name(name_node_y)