Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A relative import in Python specifies a module or package to be imported relative to the current module’s location within a package hierarchy, rather than specifying its absolute path from the project root. It utilizes dot notation to traverse the directory structure. Relative imports strictly require the from <module> import <resource> syntax. Using the standard import <module> syntax with dot notation will raise a SyntaxError.

Dot Notation Syntax

The dots indicate the directory level relative to the file containing the import statement:
  • . (Single dot): The current package.
  • .. (Double dot): The parent package.
  • ... (Triple dot): The grandparent package.

Syntax Visualization

Consider the following package hierarchy:
my_package/
├── __init__.py
├── subpackage_a/
│   ├── __init__.py
│   ├── module_x.py
│   └── module_y.py
└── subpackage_b/
    ├── __init__.py
    └── module_z.py
If you are writing code inside my_package/subpackage_a/module_x.py, relative imports are structured as follows:

# Imports a class from a module in the same directory (subpackage_a)
from .module_y import MyClass


# Imports a function from the parent directory's __init__.py (my_package)
from .. import some_function


# Imports a variable from a sibling package (subpackage_b)
from ..subpackage_b.module_z import SOME_CONSTANT

Internal Mechanics

In modern Python (since PEP 451), the import system relies primarily on the module’s __spec__ attribute—specifically __spec__.parent—to resolve relative imports. Older attributes like __package__ are officially deprecated for this purpose. When Python encounters a relative import, it calculates the target module’s absolute name by traversing up the package hierarchy. It strips levels from the current module’s package name (__spec__.parent) based on the number of leading dots, and then appends the target module name to construct the absolute import path.
  • 1 dot (.): Strips 0 levels from the parent package.
  • 2 dots (..): Strips 1 level from the parent package.
  • 3 dots (...): Strips 2 levels from the parent package.

# Inside my_package/subpackage_a/module_x.py
print(__spec__.parent)  # Output: 'my_package.subpackage_a'

from .module_y import MyClass

# Python resolves '.' to the current package: 'my_package.subpackage_a'

# The absolute import executed internally is:

# from my_package.subpackage_a.module_y import MyClass

from ..subpackage_b.module_z import SOME_CONSTANT

# Python resolves '..' by stripping one level from the current package, yielding 'my_package'

# It then appends the target to form the absolute import:

# from my_package.subpackage_b.module_z import SOME_CONSTANT

Execution Constraints

Because relative imports depend on the __spec__.parent attribute to determine the package context, they cannot be used in a module that is executed directly as a top-level script. If a file is executed directly (e.g., python module_x.py), Python treats it as the __main__ module. In this context, the module’s __spec__ attribute is None. Without a __spec__ to provide the parent package hierarchy, the import system cannot resolve the dot notation, resulting in an ImportError:
ImportError: attempted relative import with no known parent package
To execute a module containing relative imports, it must be run as a module within its package using the -m flag. This ensures the Python interpreter constructs the proper __spec__ before execution:
python -m my_package.subpackage_a.module_x
Master Python with Deep Grasping Methodology!Learn More