the_big_blackbox
the_big_blackbox

Reputation: 1196

windows vs ubuntu NameError: global name is not defined

Hi please can someone help. I have a ubuntu server(python 2.7.12) and a windows server(python 2.7.13). The code below runs perfectly on the ubuntu box however i receive an error on windows server.

import multiprocessing
import time

check="h"

def run(check):
    return test.validityCheck(check)

class t:

    def validityCheck(self,check):
        time.sleep(4)
        print(check)
        errorStatus=str("error")
        return ("error state: "+errorStatus)

    def valid(self,check):
        print 'starting....'
        pool = multiprocessing.Pool(1)
        res = pool.apply_async(run, [check])
        try:
            print res.get(timeout=5)
        except multiprocessing.TimeoutError:
            error=1
        print 'end'

    def valid1(self, check):
        self.valid(check)

if __name__=='__main__':
    test=t()
    test.valid1(check)

Traceback (most recent call last):
File "C:/scripts/m1.py", line 32, in test.valid1(check)
File "C:/scripts/m1.py", line 28, in valid1 self.valid(check)
File "C:/scripts/m1.py", line 22, in valid print res.get(timeout=5)
File "C:\Python27\lib\multiprocessing\pool.py", line 567, in get raise self._value
NameError: global name 'test' is not defined

Upvotes: 0

Views: 838

Answers (1)

Mike
Mike

Reputation: 3950

The problem is that your test variable isn't defined when your script spawns another process and executes the run function. Your test variable was only set when the __name__ variable set as "__main__". The interpreter changes the __name__ value to "__parents_main__" in a spawned process so test won't be defined. As you figured out, removing the if statement sets the variable since that is no longer contingent on __name__ being set to '__main__' but as pointed out in the comments below, this will lead to self-replicating worker threads and lead to errors.

Add:

if __name__=='__main__' or __name__=='__parents_main__':
    test=t()
# Updated as per comments below. Only run this function in the original process,
# not a spawned worker thread
if __name__=='main':
    test.valid1(check)

to your code and it will work fine. You could also just define test outside the bottom if __name__=='main' conditional and have the same effect.

Upvotes: 1

Related Questions