False positive undefined name, which is defined in branch

Bug #1612066 reported by afg984
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Pyflakes
New
Undecided
Unassigned

Bug Description

this code gives: undefined name 'j'

for i in range(10):
    if i % 3 == 0:
        j += i
    else:
        j = 0
    print(j)

while the following emits nothing

for i in range(10):
    if not i % 3 == 0:
        j = 0
    else:
        j += i
    print(j)

pyflakes --version
1.2.3

I'm creating a new report besides #1431099 and #1308508 because this is not related to the del statement

afg984 (afg984)
description: updated
Revision history for this message
Phil Frost (bitglue) wrote :

Pyflakes ignores conditional branches, since short of being a Python interpreter it can't really know if they will branch or not. So all pyflakes sees is this:

j += 1
j = 0
print(j)

j = 0
j += 1
print(j)

Can you think of a way to handle this situation which doesn't involve running the code, and which does not generate false positives?

Revision history for this message
asmeurer (asmeurer) wrote :

I think false positives come from names that aren't defined in conditionals that are used afterwords, like

if something:
    i = 0
else:
    # i not defined
if something:
    f(i)
else:
    # code that doesn't use i

If Pyflakes warned that the first else block didn't define i it would be a false positive, because i is never accessed when the code reaches that control flow.

But in this case, the variable is not defined *in* the conditional block. I don't see how that could be a false positive. So it's a distinction between

- Variables defined in only a subset of conditionals, and used below (fine)
- Variables used in a conditional that aren't defined above (not fine)

Revision history for this message
afg984 (afg984) wrote :

In a loop body, conditionals below does not always run before conditionals above

for example: statement_2 does not necessarily run after statement_1

while condition_1:
    if condition_2:
        statement_1
    else:
        statement_2

@bitglue
I think treating all variables defined in other branches as defined can silence the warning.
I have no opinions on whether doing this can be justified by the reported case, though.

@asmeurer
I said false positive because Pyflakes warned of code that can be run in the python interpreter. Maybe I have used the term incorrectly.

Also, at least to me, the problem seems to be more clear now. I can update the original report if needed.

Revision history for this message
afg984 (afg984) wrote :

Edit:
In a loop body, conditionals below does not always run before conditionals above
Should be
In a loop body, conditionals below does not always run *after* conditionals above

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.