Python ImportError: Relative Import with No Known Parent Package in Pytest

Imagen principal del artículo

Este error aparece cuando ejecutas pytest (o directamente python test_algo.py) sobre un archivo que usa imports relativos, pero Python no reconoce ese archivo como parte de un paquete. Sin un __init__.py y sin la configuración correcta de pytest, el intérprete trata el módulo como script de nivel superior y los imports relativos fallan.

El Problema

my_project/
├── utils.py
└── tests/
    └── test_utils.py   ← ejecutado con: python tests/test_utils.py
# ❌ Bad Code — tests/test_utils.py
from ..utils import add  # import relativo sin paquete padre conocido

def test_add():
    assert add(1, 2) == 3

Error al ejecutar python tests/test_utils.py:

ImportError: attempted relative import with no known parent package

La Solución

my_project/
├── pyproject.toml       ← configuración de pytest
├── utils.py
├── __init__.py          ← convierte my_project en paquete
└── tests/
    ├── __init__.py      ← convierte tests/ en subpaquete
    └── test_utils.py
# ✅ Good Code — pyproject.toml
[tool.pytest.ini_options]
pythonpath = ["."]       # añade el raíz del proyecto al sys.path
# ✅ Good Code — tests/test_utils.py
from utils import add    # import absoluto desde la raíz del proyecto

def test_add():
    assert add(1, 2) == 3
# Ejecutar siempre desde la raíz del proyecto:
pytest

Por qué funciona

Los imports relativos (..module) solo son válidos cuando Python conoce el "parent package", es decir, cuando el archivo forma parte de un paquete importado (no ejecutado como __main__). pytest por defecto añade el directorio del test al sys.path, lo que rompe la jerarquía de paquetes. La solución canónica es usar imports absolutos y configurar pythonpath = ["."] en pyproject.toml (o pytest.ini), que instruye a pytest a añadir el raíz del proyecto al path antes de colectar tests. Los archivos __init__.py en cada directorio confirman la estructura de paquete. Nunca ejecutes los test files directamente con python; delega siempre en el runner de pytest.