Search code examples
pythonunit-testingpytestpython-importlib

Possible to reload imported dictionaries?


from module import _dict -> _dict['new_key'] = 1 - and now, the same import in another file imports _dict with a previously non-existent key. This is a problem with pytest that runs several test*.py files, each mutating _dict - so e.g. test_b imports _dict modified by test_a.

A workaround is _dict = copy.deepcopy(_dict) before mutating - but suppose that isn't desired. importlib.reload(module) will not reload _dict - this said, is there any way to ensure the original module._dict is always imported?


Example (also runnable code, without pytest).

# configs.py
_dict = {'a': 1, 'b': 2}
# non_test.py
from configs import _dict

class SomeClass():
   def __init__(self, a=None, b=None):
        self.a = a or _dict['a']
        self.b = b or _dict['b']
        del _dict['a']
# test_a.py
def test_class():
    SomeClass()
# test_b.py
def test_class():
    SomeClass()

Each test*.py has the following 'header' & 'footer':

import pytest
from non_test import SomeClass
# test_*()
if __name__ == '__main__':
    pytest.main([__file__, "-s"])

Note: the example isn't reflective of the actual context, within which I have a lot less flexibility. I'm not asking for a solution to 'the problem' itself - what I ask is right in the question's title. If it's "impossible" or there's nothing close to it, then that is the answer.


Solution

  • You can use the importlib.reload function to reload a module. Since _dict from configs is imported into module non_test, which is then imported into test_b, you should reload both non_test and configs to be able to both re-instantiate a new configs._dict and have it re-imported into non_test:

    # test_b.py
    import non_test
    import configs
    import importlib
    importlib.reload(non_test)
    importlib.reload(configs)
    
    def test_class():
        SomeClass()
    

    Demo: https://repl.it/@blhsing/SaneDesertedMode