unable to import parallel modules in python

Viewed 71

I did some research and tried to apply it but failed. I have a project structured like so using python 3.10:

└── project
    ├── main
    │   └── main.py
    └── pkg1
        └── module.py

module.py and main.py are nothing fancy:

#module1.py
def hello():
    print('hello')

yet in main.py all imports fail (obviously i call only one of the 3).

#main.py
from pkg1.module import hello
from .pkg1.module import hello
from ..pkg1.module import hello

hello()

For any of the tried imports I get:

ImportError: attempted relative import with no known parent package

How do I import the module? And yes, I have to keep the file/folder structure as is because of constraints.

2 Answers

I suggest you create a parent package and you put your entrypoint main.py at the root of that package.

project ( your actual project root)
    |_project/ (your package root)
        |_ __init__.py (empty)
        |_ __main__.py (contents: from pkg1.module import hello; hello())
        |_ pkg1/
            |_ __init__.py (empty)
            |_ module.py (content: def hello: ...)

Edit:

From that structure, if you have a scenario where a package must use a sibling package, you will have solve the parent package problem

for example, import pkg2 from pkg1. No problem if you run from top level module.

project
    |_project/
        |_ __init__.py
        |_ __main__.py (contents: from pkg1.module import hello; hello())
        |_ pkg1/
            |_ __init__.py
            |_ module.py (content:from pkg2.module import hi; def hello: hi())
        |_ pkg2/
            |_ __init__.py
            |_ module.py (content: def hi: ...)

You can invoke the main module via the -m switch from the parent directory of project and then use from ..pkg1.module import hello. This way the .. can be resolved as there is a parent package (namely project):

python -m project.main.main

An alternative is to extend sys.path and add the project directory to the search path in main.py:

import sys
sys.path.append('/path/to/project')

from pgk1.module import hello

Then you can invoked the main script from within the main directory using python main.py.

If you are invoking it from within project, via python main/main.py, then you don't even need the path modification as the current working directory will be added to the search path automatically.

Related