Search code examples
pythonpython-3.xpython-importpython-module

Import package from within package directory


I'm currently working with the following directory structure:

package/
    __init__.py
    MainModule.py
    Module2.py
    run.py

Using Python 3, I've learned that in order for MainModule to import Module2, I need to use an explicit relative import (i.e., import .Module2). However, previously I was testing these files by running MainModule as a script, in which case I get

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

From this answer, I understand that running a module as a script is kind of hackish and unpythonic, according to Guido. So instead, I've added run.py, which is simply:

import sys
sys.path.append('/path/to/package-superdirectory')
from package.MainModule import main

main()

For some reason, when I run run.py, I'm getting

ImportError: No module named 'package.MainModule'; 'package' is not a package

Is there a way I can run MainModule using a script from within package/? I need the script within the package/ directory for organizational purposes, and I need MainModule to be able to use explicit relative imports. These files will go in a library, but they are not on PYTHONPATH currently, so to my knowledge python3 -m won't work here.

Update:

I need to run this particular script from a specific directory, /other/dir, so the answer needs to be able to run run.py (or MainModule) from anywhere.


Solution

  • So I've figured out how to get this to work. Since there is a package in my environment (it's the stable version of the same package), I had to add the path above package's superdirectory. So my run.py now looks like:

    #!/usr/bin/env python3
    import sys
    sys.path.append('/path/to')
    from package-superdirectory.package.MainModule import main
    
    main()
    

    Provided all the modules in package are using explicit relative imports (i.e. import .Module2), calling ./run.py will run MainModule properly.