Search code examples
pythonfunctionvariablespycharmlocal

PyCharm warns local variable might be referenced


Why does PyCharm highlight the boolean variable nearby the return with Local variable "boolean" might be referenced before assignment?

This code checks whether a number is prime or not:

import random
import math
import time
def prime_t(x):
    print x
    if x < 2:
        return False
    if x == 2:
        return True
    if x == 3:
        return True
    for i in range(2, int(math.sqrt(x))+1):
        if x % i == 0:
            boolean = False
            break
        else:
            boolean = True
    return boolean
random.seed()
how_much = input()
start = time.time()
for i in range(0, how_much):
    print(prime_t(random.randint(0, 1000)))
print time.time()-start

I've read that might be some problem with global variables, but there's no ones which might be used in prime_t(). I had similar thing - exception while executing the code, but I think it has been eliminated with if x == 2 and if x == 3.

What else might be the problem?


Solution

  • PyCharm is not certain that boolean will be set. It is not smart enough to work out the flow of your code, so it doesn't know that your for loop will always have at least 1 iteration (since x > 3 is true by that point, provided x is an integer, of course).

    Instead, it assumes that variables bound in a for loop could potentially never be set, and thus raises this warning.

    The work-around is of course to set boolean = False before the loop, just to shut it up. It is only a warning, you could also just ignore it as the IDE is trying to help you but misunderstood.

    Alternatively, instead of using a flag variable, you can use return False inside the for loop where you now use break, and return True at the end of your function:

    def prime_t(x):
        if x < 2:
            return False
        if x in {2, 3}:
            return True
        for i in range(2, int(math.sqrt(x))+1):
            if x % i == 0:
                return False
        return True