Advertencias y Deprecaciones
El módulo warnings señala problemas recuperables y deprecaciones de API sin lanzar excepciones. Configure filtros para mostrar, ignorar o escalar advertencias; las bibliotecas usan DeprecationWarning para eliminaciones programadas.
Receta
import warnings
warnings.warn("old_api está obsoleto; use new_api", DeprecationWarning, stacklevel=2)Cuándo usar esto:
- Para marcar funciones/clases como obsoletas antes de su eliminación.
- Notificaciones en tiempo de ejecución sobre usos subóptimos (no errores).
- Los mantenedores de bibliotecas advierten sin romper inmediatamente a los llamadores.
- CI
-W errorconvierte las advertencias en fallos de prueba. - Distinguir el código del usuario (
UserWarning) del interno (DeprecationWarning).
Ejemplo Funcional
import warnings
warnings.simplefilter("default", DeprecationWarning)
def old_price(amount: float) -> float:
warnings.warn(
"old_price está obsoleto; use compute_price",
DeprecationWarning,
stacklevel=2,
)
return amount * 1.1
def compute_price(amount: float) -> float:
return amount * 1.1
warnings.filterwarnings("once", category=UserWarning, module=__name__)
def maybe_risky(flag: bool) -> None:
if flag:
warnings.warn("ruta experimental habilitada", UserWarning, stacklevel=2)
old_price(10)
maybe_risky(True)
maybe_risky(True) # el filtro "once" suprime duplicadosLo que esto demuestra:
stacklevel=2apunta la advertencia al llamador, no al envoltorio.- Categoría
DeprecationWarningpara el fin de vida de la API. filterwarnings("once")evita el spam en el registro.- Filtros con alcance por categoría y módulo.
Profundización
Cómo Funciona
warnings.warn(message, category, stacklevel)emiteWarningMessage.- Por defecto: muestra cada advertencia una vez por ubicación a
stderr. warnings.filterwarnings(action, category, ...)controla el comportamiento.pytest.warnsafirma advertencias en las pruebas.- Decorador
@warnings.deprecated(3.13+) para funciones.
Categorías Comunes
| Categoría | Audiencia |
|---|---|
DeprecationWarning | Desarrolladores (oculto a los usuarios por defecto) |
UserWarning | Usuarios finales de la API |
PendingDeprecationWarning | Aviso temprano |
Errores Comunes
stacklevelincorrecto: la advertencia culpa a la línea de la biblioteca. Solución: incrementarstacklevelpor cada capa de envoltorio.DeprecationWarninginvisible en REPL: los filtros por defecto lo ocultan de lo que no es__main__. Solución: documentarwarnings.simplefilterpara la entrada de la aplicación o ejecutar pruebas con-W default::DeprecationWarning.- Usar advertencias para flujo de control: no son excepciones, fáciles de pasar por alto. Solución: usar advertencias solo para deprecaciones, no para lógica de negocio.
- Romper CI sin política:
-W errorfalla ante cualquier advertencia. Solución: tratar las deprecaciones como errores, permitir temporalmente el ruido de terceros. - Sin línea de tiempo de eliminación en el mensaje: los usuarios no pueden planificar. Solución: incluir la versión de eliminación objetivo en el texto de la advertencia.
Alternativas
| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
| Lanzar excepción | Cambio disruptivo inmediato | Se necesita migración gradual |
| Solo registro (logging) | Eventos de operaciones | Deprecación de contrato de API |
Anotaciones de tipo @deprecated | Pistas de análisis estático | Se requiere aviso en tiempo de ejecución |
Preguntas Frecuentes
¿Cómo pruebo las deprecaciones?
pytest.deprecated_call() o with warnings.catch_warnings(record=True).
¿Deberían las deprecaciones ser errores en CI?
Sí, para tu código: PYTHONWARNINGS=error::DeprecationWarning captura los rezagados antes de la eliminación.
¿Qué es `warnings.deprecated`?
Decorador de Python 3.13+ que marca llamables como obsoletos con mensajes consistentes.
¿Cuánto tiempo mantener las API obsoletas?
Documentar la política (por ejemplo, dos lanzamientos menores) y registrar métricas de uso si es posible.
¿Las advertencias van al registro (logging)?
logging.captureWarnings(True) redirige las advertencias al subsistema de registro.
¿Cómo silencio las advertencias de terceros?
filterwarnings("ignore", module="noisy_lib") - acotar el alcance, añadir un comentario con un enlace al problema.
¿`DeprecationWarning` vs `FutureWarning`?
FutureWarning para cambios de comportamiento visibles para el usuario final; DeprecationWarning para API de desarrolladores.
¿Puedo advertir desde `__init_subclass__`?
Sí, advierte cuando las subclases anulan métodos eliminados.
¿Cómo se relaciona esto con PEP 702?
PEP 702 formaliza metadatos @deprecated para verificadores de tipos y en tiempo de ejecución en 3.13+.
¿Deberían las bibliotecas configurar filtros?
Las bibliotecas advierten; las aplicaciones configuran filtros. Nunca uses simplefilter("ignore") globalmente en bibliotecas.
Relacionado
- El Módulo Logging - integración de
captureWarnings - Jerarquías de Excepciones Personalizadas - cambios disruptivos vs advertencias suaves
- Mejores Prácticas de Errores y Registro - política de deprecación
- Lanzamiento y Encadenamiento - cuándo lanzar en su lugar
Versiones de Pila: Esta página fue escrita para Python 3.14.0 (estable 3.14, mantenimiento 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, y uv 0.6+.