4

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

Community
  • 1
  • 1
Jimbo
  • 4,352
  • 3
  • 27
  • 44

1 Answers1

7

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.

Anshul Goyal
  • 73,278
  • 37
  • 149
  • 186
  • 2
    Okay, thanks, so it is because PyLint doesn't inspect the `range` function (I understand it *could* return an empty list - in my particular case it does not) or other built-in functions to figure it out. Thanks. – Jimbo Mar 27 '15 at 11:07