Search code examples
pythonpython-2.7python-3.ximportrelative-import

How to use relative import without doing python -m?


I have a folder like this

/test_mod
    __init__.py
    A.py
    test1.py
    /sub_mod
        __init__.py
        B.py
        test2.py

And I want to use relatives imports in test1 and test2 like this

#test1.py
from . import A
from .sub_mod import B
...

#test2.py
from .. import A
from . import B
...

While I develop test1 or test2 I want that those imports to work while I am in the IDLE, that is if I press F5 while working in test2 that every work fine, because I don't want to do python -m test_mod.sub_mod.test2 for instance.

I already check this python-relative-imports-for-the-billionth-time

Looking at that, I tried this:

if __name__ == "__main__" and not __package__:
    __package__ = "test_mod.sub_mod"
from .. import A
from . import B

But that didn't work, it gave this error:

SystemError: Parent module 'test_mod.sub_mod' not loaded, cannot perform relative import

Solution

  • in the end I found this solution

    #relative_import_helper.py
    import sys, os, importlib
    
    def relative_import_helper(path,nivel=1,verbose=False): 
        namepack = os.path.dirname(path)
        packs = []
        for _ in range(nivel):
            temp = os.path.basename(namepack)
            if temp:
                packs.append( temp )
                namepack = os.path.dirname(namepack)
            else:
                break
        pack = ".".join(reversed(packs))
        sys.path.append(namepack)
        importlib.import_module(pack)
        return pack
    

    and I use as

    #test2.py
    if __name__ == "__main__" and not __package__:
        print("idle trick")
        from relative_import_helper import relative_import_helper
        __package__ = relative_import_helper(__file__,2)
    
    from .. import A
    ...
    

    then I can use relatives import while working in the IDLE.