python
error-handling
importerror
programming
troubleshooting

ModuleNotFoundError What does it mean __main__ is not a package?

Interview Questions practice on Codemia

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

Browse interview questions

Introduction

The error ModuleNotFoundError: __main__ is not a package occurs when you use a relative import (like from .module import something) inside a script that Python is running directly as the entry point. Python treats directly-executed scripts as the __main__ module, which has no package context, so relative imports cannot be resolved. The fix is to restructure your imports to be absolute, or run the module using python -m package.module instead of python module.py.

The Error

python
1# my_package/utils.py
2def helper():
3    return "I'm a helper"
4
5# my_package/main.py
6from .utils import helper  # Relative import
7
8print(helper())
bash
$ python my_package/main.py
# ModuleNotFoundError: attempted relative import with no known parent package
# Or: __main__ is not a package

Why This Happens

When you run python my_package/main.py, Python sets main.py as the __main__ module. The __main__ module has no parent package, so the dot in from .utils has nowhere to resolve to.

Relative imports use the __package__ attribute to determine the current module's position in the package hierarchy. For directly-executed scripts, __package__ is None, making relative imports impossible.

python
1# When run directly: python main.py
2print(__name__)     # "__main__"
3print(__package__)  # None — no package context
4
5# When run as module: python -m my_package.main
6print(__name__)     # "__main__"
7print(__package__)  # "my_package" — package context exists

Fix 1: Use Absolute Imports

Replace relative imports with absolute imports that use the full package path:

python
1# my_package/main.py
2
3# Instead of:  from .utils import helper
4# Use:
5from my_package.utils import helper
6
7print(helper())
bash
# Run from the directory CONTAINING my_package/
$ python my_package/main.py
# Works if my_package's parent directory is in sys.path

Absolute imports are clearer and work regardless of how the script is executed.

Fix 2: Run with python -m

The -m flag tells Python to run the module within its package context, which enables relative imports:

python
1# my_package/main.py
2from .utils import helper  # Relative import works now
3
4print(helper())
bash
# Run from the directory CONTAINING my_package/
$ python -m my_package.main
# Works — Python sets __package__ = "my_package"

The directory structure must include __init__.py:

 
1project/
2├── my_package/
3│   ├── __init__.py    # Required — marks directory as a package
4│   ├── main.py
5│   └── utils.py
6└── run.py             # Optional external entry point

Fix 3: Create an External Entry Point

Move the entry point outside the package so all internal imports can be relative:

python
1# project/run.py (outside the package)
2from my_package.main import main
3main()
4
5# my_package/main.py
6from .utils import helper
7
8def main():
9    print(helper())
10
11# my_package/utils.py
12def helper():
13    return "I'm a helper"
bash
$ python run.py
# Works — my_package is imported as a package, relative imports resolve

This is the standard pattern for Python applications. The entry point script imports the package rather than being part of it.

Fix 4: Modify sys.path (Last Resort)

python
1# my_package/main.py
2import sys
3import os
4sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
5
6from my_package.utils import helper
7print(helper())

This works but is fragile and not recommended. It hard-codes path assumptions and breaks if the directory structure changes.

Understanding Relative vs Absolute Imports

python
1# Absolute import — full path from project root
2from my_package.utils import helper
3from my_package.sub.module import func
4
5# Relative import — relative to current module's package
6from .utils import helper          # Same package
7from ..other_pkg import something  # Parent package's sibling
8from . import utils                # Import sibling module

Relative imports only work when the module has a package context (__package__ is set). This requires either running with -m or importing the module from another script.

The init.py Requirement

 
1# This structure supports relative imports:
2my_package/
3├── __init__.py        # Can be empty — just marks it as a package
4├── main.py
5├── utils.py
6└── sub/
7    ├── __init__.py    # Also required for sub-packages
8    └── module.py

Without __init__.py, Python 3 still recognizes namespace packages, but relative imports require regular packages with __init__.py files.

Common Pitfalls

  • Running python file.py inside a package directory: This executes the file as __main__ with no package context. Use python -m package.module from the parent directory instead.
  • Missing __init__.py: Without this file, the directory is not a regular package and relative imports fail. Add an empty __init__.py to every package directory.
  • Running from the wrong directory: python -m my_package.main must be run from the directory that contains my_package/, not from inside my_package/.
  • Mixing relative and absolute imports inconsistently: Pick one style per project. Absolute imports are generally preferred because they work regardless of execution context.
  • Using relative imports in top-level scripts: If a file is meant to be run directly (like manage.py or setup.py), never use relative imports in it. Only use relative imports in library/package modules.

Summary

  • The error occurs because directly-executed scripts have no package context for resolving relative imports
  • Use absolute imports (from package.module import func) for the simplest fix
  • Use python -m package.module to run scripts with package context, enabling relative imports
  • Create an external entry point script that imports your package for the cleanest architecture
  • Every package directory needs an __init__.py file for relative imports to work

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.