Python
Relative Imports
ModuleNotFoundError
Python Modules
ImportError

Relative imports - ModuleNotFoundError No module named x

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

ModuleNotFoundError: No module named x around relative imports usually means Python does not know your file is part of a package in the way you think it is. The import statement itself may be correct, but the execution context is wrong. In practice, the most common cause is running a package module as a plain script instead of running it as a module inside its package.

What relative imports actually mean

Relative imports use dots to refer to the current package position:

  • 'from . import utils means "import a sibling module"'
  • 'from ..core import config means "go to the parent package, then import core.config"'

Example package layout:

text
1myapp/
2    __init__.py
3    api/
4        __init__.py
5        views.py
6        utils.py

Inside views.py, this is a relative import:

python
from . import utils

That line is valid only when Python is treating views.py as part of the myapp.api package.

Why the error happens

A very common failure pattern is running the file directly:

bash
python myapp/api/views.py

When you do that, Python treats views.py as a top-level script, not as myapp.api.views. In that context, a relative import such as from . import utils no longer has a package anchor, so import resolution fails.

The code is not necessarily wrong. The way it was launched is wrong for relative imports.

The correct way to run a package module

Run the module with -m from the project root so Python keeps the package structure intact:

bash
python -m myapp.api.views

That tells Python to execute views as a module inside the myapp.api package. Now from . import utils has a well-defined meaning.

This is one of the most important fixes for relative-import errors.

Absolute imports are often simpler

If relative imports keep causing confusion, use absolute imports:

python
from myapp.api import utils

Absolute imports are often easier to understand in larger codebases because they show the full module path explicitly. Relative imports are useful inside packages, but they are not mandatory.

As a practical rule:

  • use absolute imports when clarity matters most
  • use relative imports when the local package relationship is the main point

Check the project root and import path

Even with absolute imports, Python still needs the project root to be importable. That usually means running commands from the repository root or installing the package in editable mode during development.

For example:

bash
pip install -e .
python -m myapp.api.views

This gives Python a stable package view and avoids a lot of ad hoc path manipulation.

__init__.py is not the whole story

Older advice often says "just add __init__.py everywhere." That may help in traditional package layouts, but it is not a universal fix. The bigger issue is still execution context and import path.

So if you already have a real package and still see ModuleNotFoundError, do not stop at package files. Check how the module is being run.

Common Pitfalls

The biggest mistake is executing a package module as a standalone script and then expecting relative imports to work.

Another issue is mixing absolute and relative imports inconsistently without understanding the package root. That can make the same module behave differently depending on how it is launched.

Developers also sometimes "fix" the problem by mutating sys.path inside application code. That is usually a sign the package structure or run command should be corrected instead.

Finally, relative imports work only inside packages. If the file is truly just a loose script, relative import syntax is the wrong tool.

Summary

  • Relative imports depend on the module being executed inside a package context.
  • 'ModuleNotFoundError often comes from running the file directly instead of with python -m.'
  • 'from . import x is valid only when Python knows the current package.'
  • Absolute imports are often simpler and clearer in larger projects.
  • Fix the package execution model before reaching for sys.path hacks.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.