Method: pylint.checkers.refactoring.recommendation_checker.RecommendationChecker._check_consider_using_enumerate
Calls: 512, Exceptions: 0, Paths: 16Back
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