Pylint: undefined-loop-variable false positive related to for with "else" that raises an exception

Created on 23 Nov 2016  路  5Comments  路  Source: PyCQA/pylint

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)]

topic-control-flow

Most helpful comment

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)]

All 5 comments

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)

Was this page helpful?
0 / 5 - 0 ratings