Search code examples
pythonpylint

PyLint: Using possibly undefined loop variable warning


Having read this question I can understand why this warning might be output, but I have a specific case when the loop variable can not be undefined...

for i in range(0, 2):
    print i

print i 

PyLinting the above I get

 W:  4,6: Using possibly undefined loop variable 'i'

Is PyLint not clever enough to note that the built in range() function will always produce a populated list in this case and so i will always be set for the last print statement? I can understand if it was a under-defined function, because PyLint could not possibly know what the function does... but in this case it is a well known function and surely this usage would be common?

If so, is it better to supress the warning or define i before the loop (which seems wasteful)?


Solution

  • This is because your range might be empty depending on the intermediate execution steps involved, or it may be have redefined within the code as pointed by @tobias_k (though that will throw an additional W: 1, 0: Redefining built-in 'range' (redefined-builtin)), and hence, variable i may not be defined.

    Note that pylint doesn't at all execute code, it just does static analysis, so it won't check the value within the range. So when it sees a variable defined within a for block being re-used possibly out of scope, it complains.

    Consider the examples below, where the same Warning is shown by pylint but one runs, while other throws an exception:

    W:  4, 6: Using possibly undefined loop variable 'i' (undefined-loop-variable)
    

    Example (Not Working):

    $ cat test.py 
    for i in range(0):
            print i        
    print i
    
    $ python test.py 
    Traceback (most recent call last):
      File "test.py", line 4, in <module>
        print i
    NameError: name 'i' is not defined
    

    Example (Working):

    $ cat test.py 
    for i in range(0, 2):
            print i
    print i
    
    $ python test.py 
    0
    1
    1
    

    As the answer to your question, is it better to suppress the warning, my answer would be no. If you do want to suppress it, make sure you re-enable it after the code block in question.