Question
Relative Imports in Python 3: Why They Work Sometimes and Fail Other Times
Question
I want to import a function from another Python file in the same directory.
Usually, one of these import statements works:
from .mymodule import myfunction
or
from mymodule import myfunction
But the other form often fails with one of these errors:
ImportError: attempted relative import with no known parent package
ModuleNotFoundError: No module named 'mymodule'
SystemError: Parent module '' not loaded, cannot perform relative import
Why does this happen, and how does Python decide which import style is valid?
Short Answer
By the end of this page, you will understand the difference between relative imports and absolute imports in Python 3, why they behave differently depending on how a file is run, and how to structure your code so imports work reliably in real projects.
Concept
In Python, imports are not based only on file location. They also depend on how Python sees your code at runtime.
There are two common styles involved here:
from mymodule import myfunction
This is usually treated as an absolute import. Python looks for mymodule in places such as:
- the current import path (
sys.path) - installed packages
- the project root, depending on how the program was started
And:
from .mymodule import myfunction
This is a relative import. The dot means:
- "start from the current package"
- import
mymodulefrom the same package as this file
The key idea is that relative imports only work when the file is part of a package.
Why this matters
In real programs, Python modules are often organized into packages:
project/
├── app/
│ ├── __init__.py
│ ├── main.py
│ └── mymodule.py
If main.py is imported as part of package app, then this works:
Mental Model
Think of Python imports like giving directions to a building.
- An absolute import is like giving the full street address.
- Example: "Go to
app.mymodule."
- Example: "Go to
- A relative import is like saying, "From where I am now, go next door."
- Example:
from .mymodule import myfunction
- Example:
The problem is that "next door" only makes sense if Python knows where you currently are in the package structure.
If a file is run directly, Python often says, in effect:
- "I know this is a script"
- "I do not know its package neighborhood"
So a relative import like .mymodule becomes meaningless.
A useful rule of thumb:
- Relative imports need package context
- Absolute imports need a correct import path
Syntax and Examples
Core syntax
Absolute import
from mymodule import myfunction
Or, inside a package-based project:
from app.mymodule import myfunction
Relative import
from .mymodule import myfunction
Parent-package relative import
from ..utils import helper
This means "go up one package level, then import utils."
Example project
project/
├── app/
│ ├── __init__.py
│ ├── main.py
│ └── mymodule.py
mymodule.py:
def myfunction():
return "Hello from mymodule"
main.py:
Step by Step Execution
Consider this structure:
project/
├── app/
│ ├── __init__.py
│ ├── main.py
│ └── mymodule.py
mymodule.py:
def myfunction():
return 42
main.py:
from .mymodule import myfunction
result = myfunction()
print(result)
What happens when you run this?
Case 1: Run directly
python app/main.py
Step by step:
- Python starts
main.pyas the top-level script. - Its module name becomes something like
__main__. - Python does not treat it as part of package
app. - The statement
from .mymodule import myfunctionasks for a relative import. - Relative import needs a known parent package.
- No parent package is known.
- Python raises:
Real World Use Cases
Package-based applications
Large Python applications are usually split into packages:
- API routes
- database code
- utility modules
- configuration modules
Relative imports can help connect modules inside the same package.
Reusable libraries
When building a library, modules often import nearby helpers:
from .helpers import parse_data
from .config import DEFAULT_TIMEOUT
This makes it clear those modules belong to the same package.
Command-line tools
CLI tools often fail with import errors when developers run a file directly instead of running the package correctly.
For example, this may fail:
python tool/main.py
while this works:
python -m tool.main
Test suites
Tests often expose import problems because they may run from a different working directory. Using a clean package structure and consistent imports helps avoid environment-specific bugs.
Web applications
Framework-based apps often rely on package imports across folders such as:
modelsservices
Real Codebase Usage
In real codebases, developers usually avoid import confusion by following a few practical patterns.
1. Use a clear package structure
project/
├── myapp/
│ ├── __init__.py
│ ├── api.py
│ ├── services.py
│ └── utils.py
Then import using package-aware paths.
2. Prefer absolute imports for readability
Many teams prefer:
from myapp.utils import helper
because it is explicit and easier to understand in larger projects.
3. Use relative imports for closely related modules
Some projects use relative imports within a package:
from .utils import helper
This can be convenient when refactoring package names, but it depends on code being run inside package context.
4. Avoid running package files directly
Instead of:
python myapp/api.py
use:
python -m myapp.api
This is a very common real-project rule.
5. Keep entry points separate
A common pattern is to have a top-level runner file:
Common Mistakes
1. Running a package module as a plain script
Broken example:
python app/main.py
with:
from .mymodule import myfunction
Why it fails:
- Python does not know
main.pybelongs to packageapp
Better:
python -m app.main
2. Assuming "same directory" is enough
Broken thinking:
- "These files are next to each other, so import should always work."
In Python, imports depend on module/package context, not just physical file placement.
3. Using absolute imports without the package name
Broken example:
from mymodule import myfunction
inside a package where the correct import should be:
from app.mymodule import myfunction
Why it fails:
Comparisons
| Concept | Example | When it works | Main advantage | Main risk |
|---|---|---|---|---|
| Absolute import | from app.mymodule import myfunction | When app is on the import path | Clear and explicit | Can fail if project root is not used correctly |
| Simple top-level import | from mymodule import myfunction | When mymodule is directly discoverable on sys.path | Short syntax | Ambiguous in larger projects |
| Relative import | from .mymodule import myfunction | Only when current file is part of a package | Good for nearby modules | Fails when file is run directly |
Cheat Sheet
# Absolute import
from app.mymodule import myfunction
# Relative import: same package
from .mymodule import myfunction
# Relative import: parent package
from ..utils import helper
Rules to remember
.means "current package"..means "parent package"- Relative imports work only inside a package context
- Running a file directly usually removes that package context
python -m package.modulepreserves package context
Common errors
ImportError: attempted relative import with no known parent package
- You used a relative import in a file Python is treating as a standalone script.
ModuleNotFoundError: No module named 'mymodule'
- Python cannot find
mymoduleon the import path.
SystemError: Parent module '' loaded, cannot perform relative
FAQ
Why does from .mymodule import myfunction fail when I run the file directly?
Because relative imports require Python to know the module's parent package. When you run a file directly, Python usually treats it as a standalone script, not as part of a package.
Why does from mymodule import myfunction sometimes work?
It works when mymodule is available on Python's import path. That can depend on your current working directory, project layout, or environment.
Should I use relative or absolute imports in Python?
Both are valid. Absolute imports are often clearer in larger projects. Relative imports are useful for closely related modules inside a package.
What does python -m app.main do differently?
It runs main as a module inside the app package, so Python keeps package context and relative imports can work.
Do I need __init__.py?
In many beginner-friendly package layouts, yes, it helps make package structure explicit and avoids confusion.
Why does my import work in my IDE but fail in the terminal?
Your IDE may set a different working directory or modify the import path. The terminal may be running the file in a different context.
Can I fix this by changing sys.path manually?
You can, but it is usually not the best solution. It makes code harder to understand and less portable. A proper package structure is usually better.
Mini Project
Description
Build a small Python package with two modules where one module imports a function from the other. This project demonstrates the difference between package-aware execution and direct script execution, which is the root cause of many relative import errors.
Goal
Create a package that prints a greeting by importing a helper function correctly using package-aware imports.
Requirements
- Create a package folder named
app. - Add a module named
helpers.pywith one function that returns a greeting. - Add a module named
main.pythat imports and prints the greeting. - Make the import work using proper package execution.
- Run the program from the project root.
Keep learning
Related questions
@staticmethod vs @classmethod in Python Explained
Learn the difference between @staticmethod and @classmethod in Python with clear examples, use cases, mistakes, and a mini project.
Call a Function by Name in a Python Module
Learn how to call a function by name in a Python module using strings, getattr, and safe patterns for dynamic function dispatch.
Catch Multiple Exceptions in One except Block in Python
Learn how to catch multiple exceptions in one Python except block using tuples, with examples, mistakes, and real-world usage.