The following code produces an undefined-loop-variable false positive:
for x in some_iterable:
if matches(x):
break
else:
raise Exception
Since the "else" clause unconditionally raises an exception, the loop variable will never be undefined if it is used later. This is a common pattern in for loops that are searching for an item in an operable. This is similar to an earlier fix for a false positive in pylint which handles the case of the index variable being assigned in the "else" clause.
Here's my pylint --version output:
pylint-3.5 1.5.6,
astroid 1.4.6
Python 3.5.2 (default, Oct 11 2016, 15:01:25)
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.38)]
Hello @ronf, your example is not an MCVE (Minimal, Complete, and Verifiable Example). You should add at least a usage of x after the loop, because your presented code doesn't raise any warning.
The above was meant as pseudo-code to illustrate a block of code where the error is raised. Here's an actual complete working example:
"""Undefined loop variable example"""
for x in [1, 2, 3]:
if x == 2:
break
else:
raise ValueError('Value not found')
print(x)
Here's the output from Pylint:
************* Module t
W: 9, 6: Using possibly undefined loop variable 'x' (undefined-loop-variable)
Report
======
5 statements analysed.
Statistics by type
------------------
+---------+-------+-----------+-----------+------------+---------+
|type |number |old number |difference |%documented |%badname |
+=========+=======+===========+===========+============+=========+
|module |1 |1 |= |100.00 |0.00 |
+---------+-------+-----------+-----------+------------+---------+
|class |0 |0 |= |0 |0 |
+---------+-------+-----------+-----------+------------+---------+
|method |0 |0 |= |0 |0 |
+---------+-------+-----------+-----------+------------+---------+
|function |0 |0 |= |0 |0 |
+---------+-------+-----------+-----------+------------+---------+
Raw metrics
-----------
+----------+-------+------+---------+-----------+
|type |number |% |previous |difference |
+==========+=======+======+=========+===========+
|code |7 |63.64 |7 |= |
+----------+-------+------+---------+-----------+
|docstring |1 |9.09 |1 |= |
+----------+-------+------+---------+-----------+
|comment |0 |0.00 |0 |= |
+----------+-------+------+---------+-----------+
|empty |3 |27.27 |3 |= |
+----------+-------+------+---------+-----------+
Duplication
-----------
+-------------------------+------+---------+-----------+
| |now |previous |difference |
+=========================+======+=========+===========+
|nb duplicated lines |0 |0 |= |
+-------------------------+------+---------+-----------+
|percent duplicated lines |0.000 |0.000 |= |
+-------------------------+------+---------+-----------+
Messages by category
--------------------
+-----------+-------+---------+-----------+
|type |number |previous |difference |
+===========+=======+=========+===========+
|convention |0 |0 |= |
+-----------+-------+---------+-----------+
|refactor |0 |0 |= |
+-----------+-------+---------+-----------+
|warning |1 |1 |= |
+-----------+-------+---------+-----------+
|error |0 |0 |= |
+-----------+-------+---------+-----------+
Messages
--------
+------------------------+------------+
|message id |occurrences |
+========================+============+
|undefined-loop-variable |1 |
+------------------------+------------+
Global evaluation
-----------------
Your code has been rated at 8.00/10 (previous run: 8.00/10, +0.00)
@PCManticore another one to label as control_flow
The same situation with with return.
$ pylint --version
pylint 2.1.1
astroid 2.0.4
Python 3.7.0 (default, Jun 28 2018, 06:05:58)
[Clang 9.0.0 (clang-900.0.39.2)]
Is there a solution for this? I'm currently having to do something like this before all of my loops
value = {} # https://github.com/PyCQA/pylint/issues/1175
Either that or doing a pylint-disable on each reference to the variable (rather than just once somewhere on the loop)
Most helpful comment
The same situation with with
return.