"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "pylint/checkers/refactoring/refactoring_checker.py" between
pylint-2.14.1.tar.gz and pylint-2.14.2.tar.gz

About: pylint analyzes Python source code looking for bugs and signs of poor quality.

refactoring_checker.py  (pylint-2.14.1):refactoring_checker.py  (pylint-2.14.2)
skipping to change at line 1915 skipping to change at line 1915
if ( if (
isinstance(node.iter, nodes.Call) isinstance(node.iter, nodes.Call)
and isinstance(node.iter.func, nodes.Attribute) and isinstance(node.iter.func, nodes.Attribute)
and node.iter.func.attrname == "items" and node.iter.func.attrname == "items"
): ):
inferred = utils.safe_infer(node.iter.func) inferred = utils.safe_infer(node.iter.func)
if not isinstance(inferred, astroid.BoundMethod): if not isinstance(inferred, astroid.BoundMethod):
return return
iterating_object_name = node.iter.func.expr.as_string() iterating_object_name = node.iter.func.expr.as_string()
# Store potential violations. These will only be reported if we don'
t
# discover any writes to the collection during the loop.
messages = []
# Verify that the body of the for loop uses a subscript # Verify that the body of the for loop uses a subscript
# with the object that was iterated. This uses some heuristics # with the object that was iterated. This uses some heuristics
# in order to make sure that the same object is used in the # in order to make sure that the same object is used in the
# for body. # for body.
children = ( children = (
node.body if isinstance(node, nodes.For) else node.parent.get_ch node.body
ildren() if isinstance(node, nodes.For)
else list(node.parent.get_children())
)
# Check if there are any for / while loops within the loop in questi
on;
# If so, we will be more conservative about reporting errors as we
# can't yet do proper control flow analysis to be sure when
# reassignment will affect us
nested_loops = itertools.chain.from_iterable(
child.nodes_of_class((nodes.For, nodes.While)) for child in chil
dren
) )
has_nested_loops = next(nested_loops, None) is not None
for child in children: for child in children:
for subscript in child.nodes_of_class(nodes.Subscript): for subscript in child.nodes_of_class(nodes.Subscript):
if not isinstance(subscript.value, (nodes.Name, nodes.Attrib ute)): if not isinstance(subscript.value, (nodes.Name, nodes.Attrib ute)):
continue continue
value = subscript.slice value = subscript.slice
if isinstance(node, nodes.For) and _is_part_of_assignment_ta rget( if isinstance(node, nodes.For) and _is_part_of_assignment_ta rget(
subscript subscript
): ):
skipping to change at line 1962 skipping to change at line 1978
if ( if (
isinstance(node, nodes.For) isinstance(node, nodes.For)
and value.lookup(value.name)[1][-1].lineno > node.li neno and value.lookup(value.name)[1][-1].lineno > node.li neno
): ):
# Ignore this subscript if it has been redefined aft er # Ignore this subscript if it has been redefined aft er
# the for loop. This checks for the line number usin g .lookup() # the for loop. This checks for the line number usin g .lookup()
# to get the line number where the iterating object was last # to get the line number where the iterating object was last
# defined and compare that to the for loop's line nu mber # defined and compare that to the for loop's line nu mber
continue continue
self.add_message( if has_nested_loops:
"unnecessary-dict-index-lookup", messages.append(
node=subscript, {
args=(node.target.elts[1].as_string()), "node": subscript,
) "variable": node.target.elts[1].as_string(),
}
)
else:
self.add_message(
"unnecessary-dict-index-lookup",
node=subscript,
args=(node.target.elts[1].as_string(),),
)
# Case where .items is assigned to single var (i.e., for ite m in d.items()) # Case where .items is assigned to single var (i.e., for ite m in d.items())
elif isinstance(value, nodes.Subscript): elif isinstance(value, nodes.Subscript):
if ( if (
not isinstance(node.target, nodes.AssignName) not isinstance(node.target, nodes.AssignName)
or not isinstance(value.value, nodes.Name) or not isinstance(value.value, nodes.Name)
or node.target.name != value.value.name or node.target.name != value.value.name
or iterating_object_name != subscript.value.as_strin g() or iterating_object_name != subscript.value.as_strin g()
): ):
continue continue
skipping to change at line 1993 skipping to change at line 2017
# Ignore this subscript if it has been redefined aft er # Ignore this subscript if it has been redefined aft er
# the for loop. This checks for the line number usin g .lookup() # the for loop. This checks for the line number usin g .lookup()
# to get the line number where the iterating object was last # to get the line number where the iterating object was last
# defined and compare that to the for loop's line nu mber # defined and compare that to the for loop's line nu mber
continue continue
# check if subscripted by 0 (key) # check if subscripted by 0 (key)
inferred = utils.safe_infer(value.slice) inferred = utils.safe_infer(value.slice)
if not isinstance(inferred, nodes.Const) or inferred.val ue != 0: if not isinstance(inferred, nodes.Const) or inferred.val ue != 0:
continue continue
self.add_message(
"unnecessary-dict-index-lookup", if has_nested_loops:
node=subscript, messages.append(
args=("1".join(value.as_string().rsplit("0", maxspli {
t=1)),), "node": subscript,
) "variable": "1".join(
value.as_string().rsplit("0", maxsplit=1
)
),
}
)
else:
self.add_message(
"unnecessary-dict-index-lookup",
node=subscript,
args=(
"1".join(value.as_string().rsplit("0", maxsp
lit=1)),
),
)
for message in messages:
self.add_message(
"unnecessary-dict-index-lookup",
node=message["node"],
args=(message["variable"],),
)
def _check_unnecessary_list_index_lookup( def _check_unnecessary_list_index_lookup(
self, node: nodes.For | nodes.Comprehension self, node: nodes.For | nodes.Comprehension
) -> None: ) -> None:
if ( if (
not isinstance(node.iter, nodes.Call) not isinstance(node.iter, nodes.Call)
or not isinstance(node.iter.func, nodes.Name) or not isinstance(node.iter.func, nodes.Name)
or not node.iter.func.name == "enumerate" or not node.iter.func.name == "enumerate"
or not node.iter.args or not node.iter.args
or not isinstance(node.iter.args[0], nodes.Name) or not isinstance(node.iter.args[0], nodes.Name)
skipping to change at line 2023 skipping to change at line 2067
return return
if not isinstance(node.target.elts[1], nodes.AssignName): if not isinstance(node.target.elts[1], nodes.AssignName):
# The value is not being assigned to a single variable, e.g. being # The value is not being assigned to a single variable, e.g. being
# destructured, so we can't necessarily use it. # destructured, so we can't necessarily use it.
return return
iterating_object_name = node.iter.args[0].name iterating_object_name = node.iter.args[0].name
value_variable = node.target.elts[1] value_variable = node.target.elts[1]
# Store potential violations. These will only be reported if we don't
# discover any writes to the collection during the loop.
bad_nodes = []
children = ( children = (
node.body if isinstance(node, nodes.For) else node.parent.get_childr node.body
en() if isinstance(node, nodes.For)
else list(node.parent.get_children())
) )
# Check if there are any for / while loops within the loop in question;
# If so, we will be more conservative about reporting errors as we
# can't yet do proper control flow analysis to be sure when
# reassignment will affect us
nested_loops = itertools.chain.from_iterable(
child.nodes_of_class((nodes.For, nodes.While)) for child in children
)
has_nested_loops = next(nested_loops, None) is not None
for child in children: for child in children:
for subscript in child.nodes_of_class(nodes.Subscript): for subscript in child.nodes_of_class(nodes.Subscript):
if isinstance(node, nodes.For) and _is_part_of_assignment_target ( if isinstance(node, nodes.For) and _is_part_of_assignment_target (
subscript subscript
): ):
# Ignore this subscript if it is the target of an assignment # Ignore this subscript if it is the target of an assignment
# Early termination; after reassignment index lookup will be necessary # Early termination; after reassignment index lookup will be necessary
return return
if isinstance(subscript.parent, nodes.Delete): if isinstance(subscript.parent, nodes.Delete):
skipping to change at line 2064 skipping to change at line 2124
if ( if (
isinstance(node, nodes.For) isinstance(node, nodes.For)
and index.lookup(value_variable.name)[1][-1].lineno and index.lookup(value_variable.name)[1][-1].lineno
> node.lineno > node.lineno
): ):
# The variable holding the value from iteration has been # The variable holding the value from iteration has been
# reassigned on a later line, so it can't be used. # reassigned on a later line, so it can't be used.
continue continue
self.add_message( if has_nested_loops:
"unnecessary-list-index-lookup", # Have found a likely issue, but since there are nested
node=subscript, # loops we don't want to report this unless we get to th
args=(node.target.elts[1].name,), e
confidence=HIGH, # end of the loop without updating the collection
) bad_nodes.append(subscript)
else:
self.add_message(
"unnecessary-list-index-lookup",
node=subscript,
args=(node.target.elts[1].name,),
confidence=HIGH,
)
for subscript in bad_nodes:
self.add_message(
"unnecessary-list-index-lookup",
node=subscript,
args=(node.target.elts[1].name,),
confidence=HIGH,
)
 End of changes. 9 change blocks. 
15 lines changed or deleted 77 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)