No module named 'common'
(and later 'util'
)When you run
python -m main
from inside app/
, Python sets sys.path[0]
to app/
itself. So common/
(a sibling of main.py
) is visible and from common.do_common import foo
works.
But when you call
from common.do_common import foo
inside do_common.py
and then call foo()
, Python still considers app/
the top‐level package. It never adds app/..
to the search path, so util/
(another sibling of main.py
) isn’t on sys.path
→ you get ModuleNotFoundError: No module named 'util'
.
Relative imports (with leading dots) only work inside packages, and your “main” script isn’t actually being run as part of the app
package (its name is __main__
) Python documentation.
Re‐structure your invocation so that app
is a true package:
project/
└── app/
├── __init__.py
├── main.py
├── common/
│ ├── __init__.py
│ └── do_common.py
└── util/
├── __init__.py
└── do_util.py
Then, from the project/
directory run:
python -m app.main
Now app/
is on sys.path
, so both:
from common.do_common import foo
from util.do_util import bar
resolve correctly Real Python.
app
prefixIf you keep running python -m main
from inside app/
, change your imports to:
# in main.py
from app.common.do_common import foo
# in do_common.py
from app.util.do_util import bar
This works because you’re explicitly naming the top‐level package (app
), and avoids any reliance on relative‐import magic Real Python.
PYTHONPATH
or sys.path
If you really want to keep from common…
/ from util…
without any prefix:
export PYTHONPATH="/path/to/project/app":$PYTHONPATH
python -m main
main.py
): import sys from pathlib import Path
# add project/app to the import search path
sys.path.insert(0, str(Path(__file__).resolve().parent))
Either way, you’re telling Python “look in app/
for top‐level modules,” so both common
and util
become importable without dots Stack Overflow.
Create a minimal setup.py
in the project/
root:
# setup.py
from setuptools import setup, find_packages
setup(
name="my_app",
version="0.1",
packages=find_packages(),
)
Then, from project/
run:
pip install -e .
Now everywhere you run Python (inside or outside of app/
), common
and util
are found as part of your installed package, and you can continue writing:
fromcommon.do_common import foo
from util.do_util import bar
—no more ModuleNotFoundError
.
If you just want the quickest fix and don’t mind changing your working directory, go with (1) and run python -m app.main
from the project root.
If you prefer clarity and PEP 8’s recommendation of absolute imports, use (2) to always name your top‐level package.
For scripts that must remain portable without changing how you invoke them, (3) (adjusting PYTHONPATH
or sys.path
) works fine.
For larger projects you plan to publish or reuse elsewhere, (4) (making it installable) is the most scalable, robust solution.
All of these remove the need to prepend a dot for every import and will eliminate the ModuleNotFoundError
once and for all.