Path 1: 232 calls (0.45)

For (232)

None (232)

1def _check_consider_using_enumerate(self, node: nodes.For) -> None:
2        """Emit a convention whenever range and len are used for indexing."""
3        # Verify that we have a `range([start], len(...), [stop])` call and
4        # that the object which is iterated is used as a subscript in the
5        # body of the for.
6
7        # Is it a proper range call?
8        if not isinstance(node.iter, nodes.Call):
9            return
10        if not self._is_builtin(node.iter.func, "range"):
11            return
12        if not node.iter.args:
13            return
14        is_constant_zero = (
15            isinstance(node.iter.args[0], nodes.Const) and node.iter.args[0].value == 0
16        )
17        if len(node.iter.args) == 2 and not is_constant_zero:
18            return
19        if len(node.iter.args) > 2:
20            return
21
22        # Is it a proper len call?
23        if not isinstance(node.iter.args[-1], nodes.Call):
24            return
25        second_func = node.iter.args[-1].func
26        if not self._is_builtin(second_func, "len"):
27            return
28        len_args = node.iter.args[-1].args
29        if not len_args or len(len_args) != 1:
30            return
31        iterating_object = len_args[0]
32        if isinstance(iterating_object, nodes.Name):
33            expected_subscript_val_type = nodes.Name
34        elif isinstance(iterating_object, nodes.Attribute):
35            expected_subscript_val_type = nodes.Attribute
36        else:
37            return
38        # If we're defining __iter__ on self, enumerate won't work
39        scope = node.scope()
40        if (
41            isinstance(iterating_object, nodes.Name)
42            and iterating_object.name == "self"
43            and scope.name == "__iter__"
44        ):
45            return
46
47        # Verify that the body of the for loop uses a subscript
48        # with the object that was iterated. This uses some heuristics
49        # in order to make sure that the same object is used in the
50        # for body.
51        for child in node.body:
52            for subscript in child.nodes_of_class(nodes.Subscript):
53                if not isinstance(subscript.value, expected_subscript_val_type):
54                    continue
55
56                value = subscript.slice
57                if not isinstance(value, nodes.Name):
58                    continue
59                if subscript.value.scope() != node.scope():
60                    # Ignore this subscript if it's not in the same
61                    # scope. This means that in the body of the for
62                    # loop, another scope was created, where the same
63                    # name for the iterating object was used.
64                    continue
65                if value.name == node.target.name and (
66                    isinstance(subscript.value, nodes.Name)
67                    and iterating_object.name == subscript.value.name
68                    or isinstance(subscript.value, nodes.Attribute)
69                    and iterating_object.attrname == subscript.value.attrname
70                ):
71                    self.add_message("consider-using-enumerate", node=node)
72                    return
            

Path 2: 135 calls (0.26)

For (135)

None (135)

1def _check_consider_using_enumerate(self, node: nodes.For) -> None:
2        """Emit a convention whenever range and len are used for indexing."""
3        # Verify that we have a `range([start], len(...), [stop])` call and
4        # that the object which is iterated is used as a subscript in the
5        # body of the for.
6
7        # Is it a proper range call?
8        if not isinstance(node.iter, nodes.Call):
9            return
10        if not self._is_builtin(node.iter.func, "range"):
11            return
12        if not node.iter.args:
13            return
14        is_constant_zero = (
15            isinstance(node.iter.args[0], nodes.Const) and node.iter.args[0].value == 0
16        )
17        if len(node.iter.args) == 2 and not is_constant_zero:
18            return
19        if len(node.iter.args) > 2:
20            return
21
22        # Is it a proper len call?
23        if not isinstance(node.iter.args[-1], nodes.Call):
24            return
25        second_func = node.iter.args[-1].func
26        if not self._is_builtin(second_func, "len"):
27            return
28        len_args = node.iter.args[-1].args
29        if not len_args or len(len_args) != 1:
30            return
31        iterating_object = len_args[0]
32        if isinstance(iterating_object, nodes.Name):
33            expected_subscript_val_type = nodes.Name
34        elif isinstance(iterating_object, nodes.Attribute):
35            expected_subscript_val_type = nodes.Attribute
36        else:
37            return
38        # If we're defining __iter__ on self, enumerate won't work
39        scope = node.scope()
40        if (
41            isinstance(iterating_object, nodes.Name)
42            and iterating_object.name == "self"
43            and scope.name == "__iter__"
44        ):
45            return
46
47        # Verify that the body of the for loop uses a subscript
48        # with the object that was iterated. This uses some heuristics
49        # in order to make sure that the same object is used in the
50        # for body.
51        for child in node.body:
52            for subscript in child.nodes_of_class(nodes.Subscript):
53                if not isinstance(subscript.value, expected_subscript_val_type):
54                    continue
55
56                value = subscript.slice
57                if not isinstance(value, nodes.Name):
58                    continue
59                if subscript.value.scope() != node.scope():
60                    # Ignore this subscript if it's not in the same
61                    # scope. This means that in the body of the for
62                    # loop, another scope was created, where the same
63                    # name for the iterating object was used.
64                    continue
65                if value.name == node.target.name and (
66                    isinstance(subscript.value, nodes.Name)
67                    and iterating_object.name == subscript.value.name
68                    or isinstance(subscript.value, nodes.Attribute)
69                    and iterating_object.attrname == subscript.value.attrname
70                ):
71                    self.add_message("consider-using-enumerate", node=node)
72                    return
            

Path 3: 125 calls (0.24)

For (125)

None (125)

1def _check_consider_using_enumerate(self, node: nodes.For) -> None:
2        """Emit a convention whenever range and len are used for indexing."""
3        # Verify that we have a `range([start], len(...), [stop])` call and
4        # that the object which is iterated is used as a subscript in the
5        # body of the for.
6
7        # Is it a proper range call?
8        if not isinstance(node.iter, nodes.Call):
9            return
10        if not self._is_builtin(node.iter.func, "range"):
11            return
12        if not node.iter.args:
13            return
14        is_constant_zero = (
15            isinstance(node.iter.args[0], nodes.Const) and node.iter.args[0].value == 0
16        )
17        if len(node.iter.args) == 2 and not is_constant_zero:
18            return
19        if len(node.iter.args) > 2:
20            return
21
22        # Is it a proper len call?
23        if not isinstance(node.iter.args[-1], nodes.Call):
24            return
25        second_func = node.iter.args[-1].func
26        if not self._is_builtin(second_func, "len"):
27            return
28        len_args = node.iter.args[-1].args
29        if not len_args or len(len_args) != 1:
30            return
31        iterating_object = len_args[0]
32        if isinstance(iterating_object, nodes.Name):
33            expected_subscript_val_type = nodes.Name
34        elif isinstance(iterating_object, nodes.Attribute):
35            expected_subscript_val_type = nodes.Attribute
36        else:
37            return
38        # If we're defining __iter__ on self, enumerate won't work
39        scope = node.scope()
40        if (
41            isinstance(iterating_object, nodes.Name)
42            and iterating_object.name == "self"
43            and scope.name == "__iter__"
44        ):
45            return
46
47        # Verify that the body of the for loop uses a subscript
48        # with the object that was iterated. This uses some heuristics
49        # in order to make sure that the same object is used in the
50        # for body.
51        for child in node.body:
52            for subscript in child.nodes_of_class(nodes.Subscript):
53                if not isinstance(subscript.value, expected_subscript_val_type):
54                    continue
55
56                value = subscript.slice
57                if not isinstance(value, nodes.Name):
58                    continue
59                if subscript.value.scope() != node.scope():
60                    # Ignore this subscript if it's not in the same
61                    # scope. This means that in the body of the for
62                    # loop, another scope was created, where the same
63                    # name for the iterating object was used.
64                    continue
65                if value.name == node.target.name and (
66                    isinstance(subscript.value, nodes.Name)
67                    and iterating_object.name == subscript.value.name
68                    or isinstance(subscript.value, nodes.Attribute)
69                    and iterating_object.attrname == subscript.value.attrname
70                ):
71                    self.add_message("consider-using-enumerate", node=node)
72                    return
            

Path 4: 5 calls (0.01)

For (5)

None (5)

1def _check_consider_using_enumerate(self, node: nodes.For) -> None:
2        """Emit a convention whenever range and len are used for indexing."""
3        # Verify that we have a `range([start], len(...), [stop])` call and
4        # that the object which is iterated is used as a subscript in the
5        # body of the for.
6
7        # Is it a proper range call?
8        if not isinstance(node.iter, nodes.Call):
9            return
10        if not self._is_builtin(node.iter.func, "range"):
11            return
12        if not node.iter.args:
13            return
14        is_constant_zero = (
15            isinstance(node.iter.args[0], nodes.Const) and node.iter.args[0].value == 0
16        )
17        if len(node.iter.args) == 2 and not is_constant_zero:
18            return
19        if len(node.iter.args) > 2:
20            return
21
22        # Is it a proper len call?
23        if not isinstance(node.iter.args[-1], nodes.Call):
24            return
25        second_func = node.iter.args[-1].func
26        if not self._is_builtin(second_func, "len"):
27            return
28        len_args = node.iter.args[-1].args
29        if not len_args or len(len_args) != 1:
30            return
31        iterating_object = len_args[0]
32        if isinstance(iterating_object, nodes.Name):
33            expected_subscript_val_type = nodes.Name
34        elif isinstance(iterating_object, nodes.Attribute):
35            expected_subscript_val_type = nodes.Attribute
36        else:
37            return
38        # If we're defining __iter__ on self, enumerate won't work
39        scope = node.scope()
40        if (
41            isinstance(iterating_object, nodes.Name)
42            and iterating_object.name == "self"
43            and scope.name == "__iter__"
44        ):
45            return
46
47        # Verify that the body of the for loop uses a subscript
48        # with the object that was iterated. This uses some heuristics
49        # in order to make sure that the same object is used in the
50        # for body.
51        for child in node.body:
52            for subscript in child.nodes_of_class(nodes.Subscript):
53                if not isinstance(subscript.value, expected_subscript_val_type):
54                    continue
55
56                value = subscript.slice
57                if not isinstance(value, nodes.Name):
58                    continue
59                if subscript.value.scope() != node.scope():
60                    # Ignore this subscript if it's not in the same
61                    # scope. This means that in the body of the for
62                    # loop, another scope was created, where the same
63                    # name for the iterating object was used.
64                    continue
65                if value.name == node.target.name and (
66                    isinstance(subscript.value, nodes.Name)
67                    and iterating_object.name == subscript.value.name
68                    or isinstance(subscript.value, nodes.Attribute)
69                    and iterating_object.attrname == subscript.value.attrname
70                ):
71                    self.add_message("consider-using-enumerate", node=node)
72                    return
            

Path 5: 3 calls (0.01)

For (3)

None (3)

1def _check_consider_using_enumerate(self, node: nodes.For) -> None:
2        """Emit a convention whenever range and len are used for indexing."""
3        # Verify that we have a `range([start], len(...), [stop])` call and
4        # that the object which is iterated is used as a subscript in the
5        # body of the for.
6
7        # Is it a proper range call?
8        if not isinstance(node.iter, nodes.Call):
9            return
10        if not self._is_builtin(node.iter.func, "range"):
11            return
12        if not node.iter.args:
13            return
14        is_constant_zero = (
15            isinstance(node.iter.args[0], nodes.Const) and node.iter.args[0].value == 0
16        )
17        if len(node.iter.args) == 2 and not is_constant_zero:
18            return
19        if len(node.iter.args) > 2:
20            return
21
22        # Is it a proper len call?
23        if not isinstance(node.iter.args[-1], nodes.Call):
24            return
25        second_func = node.iter.args[-1].func
26        if not self._is_builtin(second_func, "len"):
27            return
28        len_args = node.iter.args[-1].args
29        if not len_args or len(len_args) != 1:
30            return
31        iterating_object = len_args[0]
32        if isinstance(iterating_object, nodes.Name):
33            expected_subscript_val_type = nodes.Name
34        elif isinstance(iterating_object, nodes.Attribute):
35            expected_subscript_val_type = nodes.Attribute
36        else:
37            return
38        # If we're defining __iter__ on self, enumerate won't work
39        scope = node.scope()
40        if (
41            isinstance(iterating_object, nodes.Name)
42            and iterating_object.name == "self"
43            and scope.name == "__iter__"
44        ):
45            return
46
47        # Verify that the body of the for loop uses a subscript
48        # with the object that was iterated. This uses some heuristics
49        # in order to make sure that the same object is used in the
50        # for body.
51        for child in node.body:
52            for subscript in child.nodes_of_class(nodes.Subscript):
53                if not isinstance(subscript.value, expected_subscript_val_type):
54                    continue
55
56                value = subscript.slice
57                if not isinstance(value, nodes.Name):
58                    continue
59                if subscript.value.scope() != node.scope():
60                    # Ignore this subscript if it's not in the same
61                    # scope. This means that in the body of the for
62                    # loop, another scope was created, where the same
63                    # name for the iterating object was used.
64                    continue
65                if value.name == node.target.name and (
66                    isinstance(subscript.value, nodes.Name)
67                    and iterating_object.name == subscript.value.name
68                    or isinstance(subscript.value, nodes.Attribute)
69                    and iterating_object.attrname == subscript.value.attrname
70                ):
71                    self.add_message("consider-using-enumerate", node=node)
72                    return
            

Path 6: 2 calls (0.0)

For (2)

None (2)

1def _check_consider_using_enumerate(self, node: nodes.For) -> None:
2        """Emit a convention whenever range and len are used for indexing."""
3        # Verify that we have a `range([start], len(...), [stop])` call and
4        # that the object which is iterated is used as a subscript in the
5        # body of the for.
6
7        # Is it a proper range call?
8        if not isinstance(node.iter, nodes.Call):
9            return
10        if not self._is_builtin(node.iter.func, "range"):
11            return
12        if not node.iter.args:
13            return
14        is_constant_zero = (
15            isinstance(node.iter.args[0], nodes.Const) and node.iter.args[0].value == 0
16        )
17        if len(node.iter.args) == 2 and not is_constant_zero:
18            return
19        if len(node.iter.args) > 2:
20            return
21
22        # Is it a proper len call?
23        if not isinstance(node.iter.args[-1], nodes.Call):
24            return
25        second_func = node.iter.args[-1].func
26        if not self._is_builtin(second_func, "len"):
27            return
28        len_args = node.iter.args[-1].args
29        if not len_args or len(len_args) != 1:
30            return
31        iterating_object = len_args[0]
32        if isinstance(iterating_object, nodes.Name):
33            expected_subscript_val_type = nodes.Name
34        elif isinstance(iterating_object, nodes.Attribute):
35            expected_subscript_val_type = nodes.Attribute
36        else:
37            return
38        # If we're defining __iter__ on self, enumerate won't work
39        scope = node.scope()
40        if (
41            isinstance(iterating_object, nodes.Name)
42            and iterating_object.name == "self"
43            and scope.name == "__iter__"
44        ):
45            return
46
47        # Verify that the body of the for loop uses a subscript
48        # with the object that was iterated. This uses some heuristics
49        # in order to make sure that the same object is used in the
50        # for body.
51        for child in node.body:
52            for subscript in child.nodes_of_class(nodes.Subscript):
53                if not isinstance(subscript.value, expected_subscript_val_type):
54                    continue
55
56                value = subscript.slice
57                if not isinstance(value, nodes.Name):
58                    continue
59                if subscript.value.scope() != node.scope():
60                    # Ignore this subscript if it's not in the same
61                    # scope. This means that in the body of the for
62                    # loop, another scope was created, where the same
63                    # name for the iterating object was used.
64                    continue
65                if value.name == node.target.name and (
66                    isinstance(subscript.value, nodes.Name)
67                    and iterating_object.name == subscript.value.name
68                    or isinstance(subscript.value, nodes.Attribute)
69                    and iterating_object.attrname == subscript.value.attrname
70                ):
71                    self.add_message("consider-using-enumerate", node=node)
72                    return
            

Path 7: 1 calls (0.0)

For (1)

None (1)

1def _check_consider_using_enumerate(self, node: nodes.For) -> None:
2        """Emit a convention whenever range and len are used for indexing."""
3        # Verify that we have a `range([start], len(...), [stop])` call and
4        # that the object which is iterated is used as a subscript in the
5        # body of the for.
6
7        # Is it a proper range call?
8        if not isinstance(node.iter, nodes.Call):
9            return
10        if not self._is_builtin(node.iter.func, "range"):
11            return
12        if not node.iter.args:
13            return
14        is_constant_zero = (
15            isinstance(node.iter.args[0], nodes.Const) and node.iter.args[0].value == 0
16        )
17        if len(node.iter.args) == 2 and not is_constant_zero:
18            return
19        if len(node.iter.args) > 2:
20            return
21
22        # Is it a proper len call?
23        if not isinstance(node.iter.args[-1], nodes.Call):
24            return
25        second_func = node.iter.args[-1].func
26        if not self._is_builtin(second_func, "len"):
27            return
28        len_args = node.iter.args[-1].args
29        if not len_args or len(len_args) != 1:
30            return
31        iterating_object = len_args[0]
32        if isinstance(iterating_object, nodes.Name):
33            expected_subscript_val_type = nodes.Name
34        elif isinstance(iterating_object, nodes.Attribute):
35            expected_subscript_val_type = nodes.Attribute
36        else:
37            return
38        # If we're defining __iter__ on self, enumerate won't work
39        scope = node.scope()
40        if (
41            isinstance(iterating_object, nodes.Name)
42            and iterating_object.name == "self"
43            and scope.name == "__iter__"
44        ):
45            return
46
47        # Verify that the body of the for loop uses a subscript
48        # with the object that was iterated. This uses some heuristics
49        # in order to make sure that the same object is used in the
50        # for body.
51        for child in node.body:
52            for subscript in child.nodes_of_class(nodes.Subscript):
53                if not isinstance(subscript.value, expected_subscript_val_type):
54                    continue
55
56                value = subscript.slice
57                if not isinstance(value, nodes.Name):
58                    continue
59                if subscript.value.scope() != node.scope():
60                    # Ignore this subscript if it's not in the same
61                    # scope. This means that in the body of the for
62                    # loop, another scope was created, where the same
63                    # name for the iterating object was used.
64                    continue
65                if value.name == node.target.name and (
66                    isinstance(subscript.value, nodes.Name)
67                    and iterating_object.name == subscript.value.name
68                    or isinstance(subscript.value, nodes.Attribute)
69                    and iterating_object.attrname == subscript.value.attrname
70                ):
71                    self.add_message("consider-using-enumerate", node=node)
72                    return
            

Path 8: 1 calls (0.0)

For (1)

1def _check_consider_using_enumerate(self, node: nodes.For) -> None:
2        """Emit a convention whenever range and len are used for indexing."""
3        # Verify that we have a `range([start], len(...), [stop])` call and
4        # that the object which is iterated is used as a subscript in the
5        # body of the for.
6
7        # Is it a proper range call?
8        if not isinstance(node.iter, nodes.Call):
9            return
10        if not self._is_builtin(node.iter.func, "range"):
11            return
12        if not node.iter.args:
13            return
14        is_constant_zero = (
15            isinstance(node.iter.args[0], nodes.Const) and node.iter.args[0].value == 0
16        )
17        if len(node.iter.args) == 2 and not is_constant_zero:
18            return
19        if len(node.iter.args) > 2:
20            return
21
22        # Is it a proper len call?
23        if not isinstance(node.iter.args[-1], nodes.Call):
24            return
25        second_func = node.iter.args[-1].func
26        if not self._is_builtin(second_func, "len"):
27            return
28        len_args = node.iter.args[-1].args
29        if not len_args or len(len_args) != 1:
30            return
31        iterating_object = len_args[0]
32        if isinstance(iterating_object, nodes.Name):
33            expected_subscript_val_type = nodes.Name
34        elif isinstance(iterating_object, nodes.Attribute):
35            expected_subscript_val_type = nodes.Attribute
36        else:
37            return
38        # If we're defining __iter__ on self, enumerate won't work
39        scope = node.scope()
40        if (
41            isinstance(iterating_object, nodes.Name)
42            and iterating_object.name == "self"
43            and scope.name == "__iter__"
44        ):
45            return
46
47        # Verify that the body of the for loop uses a subscript
48        # with the object that was iterated. This uses some heuristics
49        # in order to make sure that the same object is used in the
50        # for body.
51        for child in node.body:
52            for subscript in child.nodes_of_class(nodes.Subscript):
53                if not isinstance(subscript.value, expected_subscript_val_type):
54                    continue
55
56                value = subscript.slice
57                if not isinstance(value, nodes.Name):
58                    continue
59                if subscript.value.scope() != node.scope():
60                    # Ignore this subscript if it's not in the same
61                    # scope. This means that in the body of the for
62                    # loop, another scope was created, where the same
63                    # name for the iterating object was used.
64                    continue
65                if value.name == node.target.name and (
66                    isinstance(subscript.value, nodes.Name)
67                    and iterating_object.name == subscript.value.name
68                    or isinstance(subscript.value, nodes.Attribute)
69                    and iterating_object.attrname == subscript.value.attrname
70                ):
71                    self.add_message("consider-using-enumerate", node=node)
72                    return
            

Path 9: 1 calls (0.0)

For (1)

None (1)

1def _check_consider_using_enumerate(self, node: nodes.For) -> None:
2        """Emit a convention whenever range and len are used for indexing."""
3        # Verify that we have a `range([start], len(...), [stop])` call and
4        # that the object which is iterated is used as a subscript in the
5        # body of the for.
6
7        # Is it a proper range call?
8        if not isinstance(node.iter, nodes.Call):
9            return
10        if not self._is_builtin(node.iter.func, "range"):
11            return
12        if not node.iter.args:
13            return
14        is_constant_zero = (
15            isinstance(node.iter.args[0], nodes.Const) and node.iter.args[0].value == 0
16        )
17        if len(node.iter.args) == 2 and not is_constant_zero:
18            return
19        if len(node.iter.args) > 2:
20            return
21
22        # Is it a proper len call?
23        if not isinstance(node.iter.args[-1], nodes.Call):
24            return
25        second_func = node.iter.args[-1].func
26        if not self._is_builtin(second_func, "len"):
27            return
28        len_args = node.iter.args[-1].args
29        if not len_args or len(len_args) != 1:
30            return
31        iterating_object = len_args[0]
32        if isinstance(iterating_object, nodes.Name):
33            expected_subscript_val_type = nodes.Name
34        elif isinstance(iterating_object, nodes.Attribute):
35            expected_subscript_val_type = nodes.Attribute
36        else:
37            return
38        # If we're defining __iter__ on self, enumerate won't work
39        scope = node.scope()
40        if (
41            isinstance(iterating_object, nodes.Name)
42            and iterating_object.name == "self"
43            and scope.name == "__iter__"
44        ):
45            return
46
47        # Verify that the body of the for loop uses a subscript
48        # with the object that was iterated. This uses some heuristics
49        # in order to make sure that the same object is used in the
50        # for body.
51        for child in node.body:
52            for subscript in child.nodes_of_class(nodes.Subscript):
53                if not isinstance(subscript.value, expected_subscript_val_type):
54                    continue
55
56                value = subscript.slice
57                if not isinstance(value, nodes.Name):
58                    continue
59                if subscript.value.scope() != node.scope():
60                    # Ignore this subscript if it's not in the same
61                    # scope. This means that in the body of the for
62                    # loop, another scope was created, where the same
63                    # name for the iterating object was used.
64                    continue
65                if value.name == node.target.name and (
66                    isinstance(subscript.value, nodes.Name)
67                    and iterating_object.name == subscript.value.name
68                    or isinstance(subscript.value, nodes.Attribute)
69                    and iterating_object.attrname == subscript.value.attrname
70                ):
71                    self.add_message("consider-using-enumerate", node=node)
72                    return
            

Path 10: 1 calls (0.0)

For (1)

1def _check_consider_using_enumerate(self, node: nodes.For) -> None:
2        """Emit a convention whenever range and len are used for indexing."""
3        # Verify that we have a `range([start], len(...), [stop])` call and
4        # that the object which is iterated is used as a subscript in the
5        # body of the for.
6
7        # Is it a proper range call?
8        if not isinstance(node.iter, nodes.Call):
9            return
10        if not self._is_builtin(node.iter.func, "range"):
11            return
12        if not node.iter.args:
13            return
14        is_constant_zero = (
15            isinstance(node.iter.args[0], nodes.Const) and node.iter.args[0].value == 0
16        )
17        if len(node.iter.args) == 2 and not is_constant_zero:
18            return
19        if len(node.iter.args) > 2:
20            return
21
22        # Is it a proper len call?
23        if not isinstance(node.iter.args[-1], nodes.Call):
24            return
25        second_func = node.iter.args[-1].func
26        if not self._is_builtin(second_func, "len"):
27            return
28        len_args = node.iter.args[-1].args
29        if not len_args or len(len_args) != 1:
30            return
31        iterating_object = len_args[0]
32        if isinstance(iterating_object, nodes.Name):
33            expected_subscript_val_type = nodes.Name
34        elif isinstance(iterating_object, nodes.Attribute):
35            expected_subscript_val_type = nodes.Attribute
36        else:
37            return
38        # If we're defining __iter__ on self, enumerate won't work
39        scope = node.scope()
40        if (
41            isinstance(iterating_object, nodes.Name)
42            and iterating_object.name == "self"
43            and scope.name == "__iter__"
44        ):
45            return
46
47        # Verify that the body of the for loop uses a subscript
48        # with the object that was iterated. This uses some heuristics
49        # in order to make sure that the same object is used in the
50        # for body.
51        for child in node.body:
52            for subscript in child.nodes_of_class(nodes.Subscript):
53                if not isinstance(subscript.value, expected_subscript_val_type):
54                    continue
55
56                value = subscript.slice
57                if not isinstance(value, nodes.Name):
58                    continue
59                if subscript.value.scope() != node.scope():
60                    # Ignore this subscript if it's not in the same
61                    # scope. This means that in the body of the for
62                    # loop, another scope was created, where the same
63                    # name for the iterating object was used.
64                    continue
65                if value.name == node.target.name and (
66                    isinstance(subscript.value, nodes.Name)
67                    and iterating_object.name == subscript.value.name
68                    or isinstance(subscript.value, nodes.Attribute)
69                    and iterating_object.attrname == subscript.value.attrname
70                ):
71                    self.add_message("consider-using-enumerate", node=node)
72                    return
            

Path 11: 1 calls (0.0)

For (1)

1def _check_consider_using_enumerate(self, node: nodes.For) -> None:
2        """Emit a convention whenever range and len are used for indexing."""
3        # Verify that we have a `range([start], len(...), [stop])` call and
4        # that the object which is iterated is used as a subscript in the
5        # body of the for.
6
7        # Is it a proper range call?
8        if not isinstance(node.iter, nodes.Call):
9            return
10        if not self._is_builtin(node.iter.func, "range"):
11            return
12        if not node.iter.args:
13            return
14        is_constant_zero = (
15            isinstance(node.iter.args[0], nodes.Const) and node.iter.args[0].value == 0
16        )
17        if len(node.iter.args) == 2 and not is_constant_zero:
18            return
19        if len(node.iter.args) > 2:
20            return
21
22        # Is it a proper len call?
23        if not isinstance(node.iter.args[-1], nodes.Call):
24            return
25        second_func = node.iter.args[-1].func
26        if not self._is_builtin(second_func, "len"):
27            return
28        len_args = node.iter.args[-1].args
29        if not len_args or len(len_args) != 1:
30            return
31        iterating_object = len_args[0]
32        if isinstance(iterating_object, nodes.Name):
33            expected_subscript_val_type = nodes.Name
34        elif isinstance(iterating_object, nodes.Attribute):
35            expected_subscript_val_type = nodes.Attribute
36        else:
37            return
38        # If we're defining __iter__ on self, enumerate won't work
39        scope = node.scope()
40        if (
41            isinstance(iterating_object, nodes.Name)
42            and iterating_object.name == "self"
43            and scope.name == "__iter__"
44        ):
45            return
46
47        # Verify that the body of the for loop uses a subscript
48        # with the object that was iterated. This uses some heuristics
49        # in order to make sure that the same object is used in the
50        # for body.
51        for child in node.body:
52            for subscript in child.nodes_of_class(nodes.Subscript):
53                if not isinstance(subscript.value, expected_subscript_val_type):
54                    continue
55
56                value = subscript.slice
57                if not isinstance(value, nodes.Name):
58                    continue
59                if subscript.value.scope() != node.scope():
60                    # Ignore this subscript if it's not in the same
61                    # scope. This means that in the body of the for
62                    # loop, another scope was created, where the same
63                    # name for the iterating object was used.
64                    continue
65                if value.name == node.target.name and (
66                    isinstance(subscript.value, nodes.Name)
67                    and iterating_object.name == subscript.value.name
68                    or isinstance(subscript.value, nodes.Attribute)
69                    and iterating_object.attrname == subscript.value.attrname
70                ):
71                    self.add_message("consider-using-enumerate", node=node)
72                    return
            

Path 12: 1 calls (0.0)

For (1)

None (1)

1def _check_consider_using_enumerate(self, node: nodes.For) -> None:
2        """Emit a convention whenever range and len are used for indexing."""
3        # Verify that we have a `range([start], len(...), [stop])` call and
4        # that the object which is iterated is used as a subscript in the
5        # body of the for.
6
7        # Is it a proper range call?
8        if not isinstance(node.iter, nodes.Call):
9            return
10        if not self._is_builtin(node.iter.func, "range"):
11            return
12        if not node.iter.args:
13            return
14        is_constant_zero = (
15            isinstance(node.iter.args[0], nodes.Const) and node.iter.args[0].value == 0
16        )
17        if len(node.iter.args) == 2 and not is_constant_zero:
18            return
19        if len(node.iter.args) > 2:
20            return
21
22        # Is it a proper len call?
23        if not isinstance(node.iter.args[-1], nodes.Call):
24            return
25        second_func = node.iter.args[-1].func
26        if not self._is_builtin(second_func, "len"):
27            return
28        len_args = node.iter.args[-1].args
29        if not len_args or len(len_args) != 1:
30            return
31        iterating_object = len_args[0]
32        if isinstance(iterating_object, nodes.Name):
33            expected_subscript_val_type = nodes.Name
34        elif isinstance(iterating_object, nodes.Attribute):
35            expected_subscript_val_type = nodes.Attribute
36        else:
37            return
38        # If we're defining __iter__ on self, enumerate won't work
39        scope = node.scope()
40        if (
41            isinstance(iterating_object, nodes.Name)
42            and iterating_object.name == "self"
43            and scope.name == "__iter__"
44        ):
45            return
46
47        # Verify that the body of the for loop uses a subscript
48        # with the object that was iterated. This uses some heuristics
49        # in order to make sure that the same object is used in the
50        # for body.
51        for child in node.body:
52            for subscript in child.nodes_of_class(nodes.Subscript):
53                if not isinstance(subscript.value, expected_subscript_val_type):
54                    continue
55
56                value = subscript.slice
57                if not isinstance(value, nodes.Name):
58                    continue
59                if subscript.value.scope() != node.scope():
60                    # Ignore this subscript if it's not in the same
61                    # scope. This means that in the body of the for
62                    # loop, another scope was created, where the same
63                    # name for the iterating object was used.
64                    continue
65                if value.name == node.target.name and (
66                    isinstance(subscript.value, nodes.Name)
67                    and iterating_object.name == subscript.value.name
68                    or isinstance(subscript.value, nodes.Attribute)
69                    and iterating_object.attrname == subscript.value.attrname
70                ):
71                    self.add_message("consider-using-enumerate", node=node)
72                    return
            

Path 13: 1 calls (0.0)

For (1)

1def _check_consider_using_enumerate(self, node: nodes.For) -> None:
2        """Emit a convention whenever range and len are used for indexing."""
3        # Verify that we have a `range([start], len(...), [stop])` call and
4        # that the object which is iterated is used as a subscript in the
5        # body of the for.
6
7        # Is it a proper range call?
8        if not isinstance(node.iter, nodes.Call):
9            return
10        if not self._is_builtin(node.iter.func, "range"):
11            return
12        if not node.iter.args:
13            return
14        is_constant_zero = (
15            isinstance(node.iter.args[0], nodes.Const) and node.iter.args[0].value == 0
16        )
17        if len(node.iter.args) == 2 and not is_constant_zero:
18            return
19        if len(node.iter.args) > 2:
20            return
21
22        # Is it a proper len call?
23        if not isinstance(node.iter.args[-1], nodes.Call):
24            return
25        second_func = node.iter.args[-1].func
26        if not self._is_builtin(second_func, "len"):
27            return
28        len_args = node.iter.args[-1].args
29        if not len_args or len(len_args) != 1:
30            return
31        iterating_object = len_args[0]
32        if isinstance(iterating_object, nodes.Name):
33            expected_subscript_val_type = nodes.Name
34        elif isinstance(iterating_object, nodes.Attribute):
35            expected_subscript_val_type = nodes.Attribute
36        else:
37            return
38        # If we're defining __iter__ on self, enumerate won't work
39        scope = node.scope()
40        if (
41            isinstance(iterating_object, nodes.Name)
42            and iterating_object.name == "self"
43            and scope.name == "__iter__"
44        ):
45            return
46
47        # Verify that the body of the for loop uses a subscript
48        # with the object that was iterated. This uses some heuristics
49        # in order to make sure that the same object is used in the
50        # for body.
51        for child in node.body:
52            for subscript in child.nodes_of_class(nodes.Subscript):
53                if not isinstance(subscript.value, expected_subscript_val_type):
54                    continue
55
56                value = subscript.slice
57                if not isinstance(value, nodes.Name):
58                    continue
59                if subscript.value.scope() != node.scope():
60                    # Ignore this subscript if it's not in the same
61                    # scope. This means that in the body of the for
62                    # loop, another scope was created, where the same
63                    # name for the iterating object was used.
64                    continue
65                if value.name == node.target.name and (
66                    isinstance(subscript.value, nodes.Name)
67                    and iterating_object.name == subscript.value.name
68                    or isinstance(subscript.value, nodes.Attribute)
69                    and iterating_object.attrname == subscript.value.attrname
70                ):
71                    self.add_message("consider-using-enumerate", node=node)
72                    return
            

Path 14: 1 calls (0.0)

For (1)

None (1)

1def _check_consider_using_enumerate(self, node: nodes.For) -> None:
2        """Emit a convention whenever range and len are used for indexing."""
3        # Verify that we have a `range([start], len(...), [stop])` call and
4        # that the object which is iterated is used as a subscript in the
5        # body of the for.
6
7        # Is it a proper range call?
8        if not isinstance(node.iter, nodes.Call):
9            return
10        if not self._is_builtin(node.iter.func, "range"):
11            return
12        if not node.iter.args:
13            return
14        is_constant_zero = (
15            isinstance(node.iter.args[0], nodes.Const) and node.iter.args[0].value == 0
16        )
17        if len(node.iter.args) == 2 and not is_constant_zero:
18            return
19        if len(node.iter.args) > 2:
20            return
21
22        # Is it a proper len call?
23        if not isinstance(node.iter.args[-1], nodes.Call):
24            return
25        second_func = node.iter.args[-1].func
26        if not self._is_builtin(second_func, "len"):
27            return
28        len_args = node.iter.args[-1].args
29        if not len_args or len(len_args) != 1:
30            return
31        iterating_object = len_args[0]
32        if isinstance(iterating_object, nodes.Name):
33            expected_subscript_val_type = nodes.Name
34        elif isinstance(iterating_object, nodes.Attribute):
35            expected_subscript_val_type = nodes.Attribute
36        else:
37            return
38        # If we're defining __iter__ on self, enumerate won't work
39        scope = node.scope()
40        if (
41            isinstance(iterating_object, nodes.Name)
42            and iterating_object.name == "self"
43            and scope.name == "__iter__"
44        ):
45            return
46
47        # Verify that the body of the for loop uses a subscript
48        # with the object that was iterated. This uses some heuristics
49        # in order to make sure that the same object is used in the
50        # for body.
51        for child in node.body:
52            for subscript in child.nodes_of_class(nodes.Subscript):
53                if not isinstance(subscript.value, expected_subscript_val_type):
54                    continue
55
56                value = subscript.slice
57                if not isinstance(value, nodes.Name):
58                    continue
59                if subscript.value.scope() != node.scope():
60                    # Ignore this subscript if it's not in the same
61                    # scope. This means that in the body of the for
62                    # loop, another scope was created, where the same
63                    # name for the iterating object was used.
64                    continue
65                if value.name == node.target.name and (
66                    isinstance(subscript.value, nodes.Name)
67                    and iterating_object.name == subscript.value.name
68                    or isinstance(subscript.value, nodes.Attribute)
69                    and iterating_object.attrname == subscript.value.attrname
70                ):
71                    self.add_message("consider-using-enumerate", node=node)
72                    return
            

Path 15: 1 calls (0.0)

For (1)

None (1)

1def _check_consider_using_enumerate(self, node: nodes.For) -> None:
2        """Emit a convention whenever range and len are used for indexing."""
3        # Verify that we have a `range([start], len(...), [stop])` call and
4        # that the object which is iterated is used as a subscript in the
5        # body of the for.
6
7        # Is it a proper range call?
8        if not isinstance(node.iter, nodes.Call):
9            return
10        if not self._is_builtin(node.iter.func, "range"):
11            return
12        if not node.iter.args:
13            return
14        is_constant_zero = (
15            isinstance(node.iter.args[0], nodes.Const) and node.iter.args[0].value == 0
16        )
17        if len(node.iter.args) == 2 and not is_constant_zero:
18            return
19        if len(node.iter.args) > 2:
20            return
21
22        # Is it a proper len call?
23        if not isinstance(node.iter.args[-1], nodes.Call):
24            return
25        second_func = node.iter.args[-1].func
26        if not self._is_builtin(second_func, "len"):
27            return
28        len_args = node.iter.args[-1].args
29        if not len_args or len(len_args) != 1:
30            return
31        iterating_object = len_args[0]
32        if isinstance(iterating_object, nodes.Name):
33            expected_subscript_val_type = nodes.Name
34        elif isinstance(iterating_object, nodes.Attribute):
35            expected_subscript_val_type = nodes.Attribute
36        else:
37            return
38        # If we're defining __iter__ on self, enumerate won't work
39        scope = node.scope()
40        if (
41            isinstance(iterating_object, nodes.Name)
42            and iterating_object.name == "self"
43            and scope.name == "__iter__"
44        ):
45            return
46
47        # Verify that the body of the for loop uses a subscript
48        # with the object that was iterated. This uses some heuristics
49        # in order to make sure that the same object is used in the
50        # for body.
51        for child in node.body:
52            for subscript in child.nodes_of_class(nodes.Subscript):
53                if not isinstance(subscript.value, expected_subscript_val_type):
54                    continue
55
56                value = subscript.slice
57                if not isinstance(value, nodes.Name):
58                    continue
59                if subscript.value.scope() != node.scope():
60                    # Ignore this subscript if it's not in the same
61                    # scope. This means that in the body of the for
62                    # loop, another scope was created, where the same
63                    # name for the iterating object was used.
64                    continue
65                if value.name == node.target.name and (
66                    isinstance(subscript.value, nodes.Name)
67                    and iterating_object.name == subscript.value.name
68                    or isinstance(subscript.value, nodes.Attribute)
69                    and iterating_object.attrname == subscript.value.attrname
70                ):
71                    self.add_message("consider-using-enumerate", node=node)
72                    return
            

Path 16: 1 calls (0.0)

For (1)

None (1)

1def _check_consider_using_enumerate(self, node: nodes.For) -> None:
2        """Emit a convention whenever range and len are used for indexing."""
3        # Verify that we have a `range([start], len(...), [stop])` call and
4        # that the object which is iterated is used as a subscript in the
5        # body of the for.
6
7        # Is it a proper range call?
8        if not isinstance(node.iter, nodes.Call):
9            return
10        if not self._is_builtin(node.iter.func, "range"):
11            return
12        if not node.iter.args:
13            return
14        is_constant_zero = (
15            isinstance(node.iter.args[0], nodes.Const) and node.iter.args[0].value == 0
16        )
17        if len(node.iter.args) == 2 and not is_constant_zero:
18            return
19        if len(node.iter.args) > 2:
20            return
21
22        # Is it a proper len call?
23        if not isinstance(node.iter.args[-1], nodes.Call):
24            return
25        second_func = node.iter.args[-1].func
26        if not self._is_builtin(second_func, "len"):
27            return
28        len_args = node.iter.args[-1].args
29        if not len_args or len(len_args) != 1:
30            return
31        iterating_object = len_args[0]
32        if isinstance(iterating_object, nodes.Name):
33            expected_subscript_val_type = nodes.Name
34        elif isinstance(iterating_object, nodes.Attribute):
35            expected_subscript_val_type = nodes.Attribute
36        else:
37            return
38        # If we're defining __iter__ on self, enumerate won't work
39        scope = node.scope()
40        if (
41            isinstance(iterating_object, nodes.Name)
42            and iterating_object.name == "self"
43            and scope.name == "__iter__"
44        ):
45            return
46
47        # Verify that the body of the for loop uses a subscript
48        # with the object that was iterated. This uses some heuristics
49        # in order to make sure that the same object is used in the
50        # for body.
51        for child in node.body:
52            for subscript in child.nodes_of_class(nodes.Subscript):
53                if not isinstance(subscript.value, expected_subscript_val_type):
54                    continue
55
56                value = subscript.slice
57                if not isinstance(value, nodes.Name):
58                    continue
59                if subscript.value.scope() != node.scope():
60                    # Ignore this subscript if it's not in the same
61                    # scope. This means that in the body of the for
62                    # loop, another scope was created, where the same
63                    # name for the iterating object was used.
64                    continue
65                if value.name == node.target.name and (
66                    isinstance(subscript.value, nodes.Name)
67                    and iterating_object.name == subscript.value.name
68                    or isinstance(subscript.value, nodes.Attribute)
69                    and iterating_object.attrname == subscript.value.attrname
70                ):
71                    self.add_message("consider-using-enumerate", node=node)
72                    return