"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "pylint/checkers/variables.py" between
pylint-2.13.7.tar.gz and pylint-2.13.8.tar.gz

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

variables.py  (pylint-2.13.7):variables.py  (pylint-2.13.8)
skipping to change at line 2191 skipping to change at line 2191
) )
def _loopvar_name(self, node: astroid.Name) -> None: def _loopvar_name(self, node: astroid.Name) -> None:
# filter variables according to node's scope # filter variables according to node's scope
astmts = [s for s in node.lookup(node.name)[1] if hasattr(s, "assign_typ e")] astmts = [s for s in node.lookup(node.name)[1] if hasattr(s, "assign_typ e")]
# If this variable usage exists inside a function definition # If this variable usage exists inside a function definition
# that exists in the same loop, # that exists in the same loop,
# the usage is safe because the function will not be defined either if # the usage is safe because the function will not be defined either if
# the variable is not defined. # the variable is not defined.
scope = node.scope() scope = node.scope()
if isinstance(scope, nodes.FunctionDef) and any( # FunctionDef subclasses Lambda due to a curious ontology. Check both.
# See https://github.com/PyCQA/astroid/issues/291
# pylint: disable-next=fixme
# TODO: Revisit when astroid 3.0 includes the change
if isinstance(scope, nodes.Lambda) and any(
asmt.scope().parent_of(scope) for asmt in astmts asmt.scope().parent_of(scope) for asmt in astmts
): ):
return return
# Filter variables according to their respective scope. Test parent # Filter variables according to their respective scope. Test parent
# and statement to avoid #74747. This is not a total fix, which would # and statement to avoid #74747. This is not a total fix, which would
# introduce a mechanism similar to special attribute lookup in # introduce a mechanism similar to special attribute lookup in
# modules. Also, in order to get correct inference in this case, the # modules. Also, in order to get correct inference in this case, the
# scope lookup rules would need to be changed to return the initial # scope lookup rules would need to be changed to return the initial
# assignment (which does not exist in code per se) as well as any later # assignment (which does not exist in code per se) as well as any later
# modifications. # modifications.
skipping to change at line 2235 skipping to change at line 2239
if len(astmts) != 1: if len(astmts) != 1:
return return
assign = astmts[0].assign_type() assign = astmts[0].assign_type()
if not ( if not (
isinstance(assign, (nodes.For, nodes.Comprehension, nodes.GeneratorE xp)) isinstance(assign, (nodes.For, nodes.Comprehension, nodes.GeneratorE xp))
and assign.statement(future=True) is not node.statement(future=True) and assign.statement(future=True) is not node.statement(future=True)
): ):
return return
# For functions we can do more by inferring the length of the itered obj ect
if not isinstance(assign, nodes.For): if not isinstance(assign, nodes.For):
self.add_message("undefined-loop-variable", args=node.name, node=nod e) self.add_message("undefined-loop-variable", args=node.name, node=nod e)
return return
if any(
isinstance(else_stmt, (nodes.Return, nodes.Raise))
for else_stmt in assign.orelse
):
return
# For functions we can do more by inferring the length of the itered obj ect
try: try:
inferred = next(assign.iter.infer()) inferred = next(assign.iter.infer())
except astroid.InferenceError: except astroid.InferenceError:
self.add_message("undefined-loop-variable", args=node.name, node=nod e) self.add_message("undefined-loop-variable", args=node.name, node=nod e)
else: else:
if ( if (
isinstance(inferred, astroid.Instance) isinstance(inferred, astroid.Instance)
and inferred.qname() == BUILTIN_RANGE and inferred.qname() == BUILTIN_RANGE
): ):
# Consider range() objects safe, even if they might not yield an y results. # Consider range() objects safe, even if they might not yield an y results.
skipping to change at line 2799 skipping to change at line 2808
consumed = [] # [(scope_locals, consumed_key)] consumed = [] # [(scope_locals, consumed_key)]
metaclass = klass.metaclass() metaclass = klass.metaclass()
name = None name = None
if isinstance(klass._metaclass, nodes.Name): if isinstance(klass._metaclass, nodes.Name):
name = klass._metaclass.name name = klass._metaclass.name
elif isinstance(klass._metaclass, nodes.Attribute) and klass._metaclass. expr: elif isinstance(klass._metaclass, nodes.Attribute) and klass._metaclass. expr:
attr = klass._metaclass.expr attr = klass._metaclass.expr
while not isinstance(attr, nodes.Name): while not isinstance(attr, nodes.Name):
attr = attr.expr attr = attr.expr
name = attr.name name = attr.name
elif isinstance(klass._metaclass, nodes.Call) and isinstance(
klass._metaclass.func, nodes.Name
):
name = klass._metaclass.func.name
elif metaclass: elif metaclass:
name = metaclass.root().name name = metaclass.root().name
found = False found = False
name = METACLASS_NAME_TRANSFORMS.get(name, name) name = METACLASS_NAME_TRANSFORMS.get(name, name)
if name: if name:
# check enclosing scopes starting from most local # check enclosing scopes starting from most local
for scope_locals, _, _, _ in self._to_consume[::-1]: for scope_locals, _, _, _ in self._to_consume[::-1]:
found_nodes = scope_locals.get(name, []) found_nodes = scope_locals.get(name, [])
for found_node in found_nodes: for found_node in found_nodes:
 End of changes. 5 change blocks. 
2 lines changed or deleted 15 lines changed or added

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