Search code examples
pythonpython-3.xmultithreadingthread-safetyclass-variables

Is class variable initialization from an imported module thread safe in Python?


I am aware of the fact that class variables initialization happens at the time of the import. If that is the case, in the code below, does the class variable initialization of class A result in race conditions?

a.py:

class A:
    # Static code here...
    pass

b.py:

class B:
    def func(self):
        from a import A

c.py:

import threading
from b import B

b1 = B()
b2 = B()

t1 = threading.Thread(target=b1.func)
t2 = threading.Thread(target=b2.func)

t1.start()
t2.start()

t1.join()
t2.join()

Terminal:

$ python c.py

Solution

  • there's a thread lock on the C side in Cpython implementation of importlib, but just to be sure, I ran the following script:

    imported file:

    import time
    print('importing, in imported file')
    time.sleep(2) # drop the GIL
    print('finished importing, in imported file')
    

    importing file:

    import threading
    
    def import_other_file():
        print('going to import')
        import ex12
        print('finished importing')
    
    t1 = threading.Thread(target=import_other_file)
    t2 = threading.Thread(target=import_other_file)
    
    t1.start()
    t2.start()
    
    t1.join()
    t2.join()
    

    output:

    going to import
    going to import
    importing, in imported file
    finished importing, in imported file
    finished importing
    finished importing
    

    does the class variable initialization of class A result in race conditions?

    so NO, there will be no race condition due to the lock on the C side.