El módulo trace en Python sigue la ejecución de instrucciones, cuenta cuántas veces se ejecuta cada línea, enumera funciones alcanzadas y registra relaciones entre callers y callees. Puede utilizarse desde la línea de comandos o mediante una API programática, por lo que resulta útil para cobertura sencilla, herramientas educativas y diagnóstico de flujos difíciles de reproducir.
La configuración es simple, pero el costo de ejecución no lo es. Rastrear cada línea puede ralentizar notablemente un programa y generar una salida enorme. Úsalo en desarrollo, pruebas y escenarios controlados, no como monitorización permanente de producción sin medir su impacto.
Cuenta líneas ejecutadas
La opción --count ejecuta un script y genera archivos anotados con extensión .cover.
python -m trace --count -C cobertura aplicacion.pyLas líneas ejecutables reciben un contador. Las líneas sin número pueden ser comentarios, docstrings, declaraciones o instrucciones que no fueron alcanzadas durante ese escenario.
Marca líneas ausentes
--missing identifica con >>>>>> las líneas que podían ejecutarse pero no tuvieron visitas.
python -m trace \
--count \
--missing \
--summary \
-C cobertura \
aplicacion.pyEl resumen por archivo ayuda a localizar módulos poco ejercitados, pero la cobertura de líneas no demuestra que condiciones, combinaciones y resultados sean correctos.
Muestra cada línea durante la ejecución
--trace imprime las líneas a medida que se ejecutan.
python -m trace --trace tarea.pyLa salida se vuelve ruidosa cuando incluye la biblioteca estándar y dependencias. Aplica filtros de módulos y directorios para concentrarte en el código de la aplicación.
Añade tiempo relativo
--timing antepone el tiempo transcurrido desde el inicio a cada línea rastreada.
python -m trace --trace --timing tarea.pyLas pausas pueden hacerse visibles, pero el propio tracer altera los intervalos. Para analizar tiempo por función, utiliza pstats en Python junto con cProfile.
Lista las funciones ejecutadas
--listfuncs muestra las funciones alcanzadas durante el escenario.
python -m trace --listfuncs aplicacion.pyEsta opción es incompatible con --trace y --count. Es útil para confirmar qué handlers, callbacks y caminos de una funcionalidad realmente se utilizaron.
Rastrea relaciones de llamadas
--trackcalls registra quién llamó a quién.
python -m trace --trackcalls aplicacion.pyEl resultado es más sencillo que el de un profiler completo, pero ayuda a visualizar acoplamientos inesperados entre módulos y funciones.
Ignora módulos
--ignore-module acepta nombres separados por comas y puede repetirse.
python -m trace \
--count \
--ignore-module=urllib,json \
-C cobertura \
aplicacion.pyLos filtros reducen ruido. No excluyas código de la aplicación únicamente para mejorar una métrica; documenta la política de cobertura.
Ignora directorios
--ignore-dir excluye módulos ubicados bajo los directorios seleccionados.
python -m trace \
--count \
--ignore-dir=.venv \
-C cobertura \
aplicacion.pyPara varios directorios, utiliza el separador de rutas del sistema operativo. Resuelve rutas relativas para evitar que un patrón demasiado amplio oculte más archivos de los previstos.
Acumula varias ejecuciones
--file almacena contadores que pueden reutilizarse entre escenarios.
python -m trace --count --no-report \
--file contadores.dat prueba_a.py
python -m trace --count --no-report \
--file contadores.dat prueba_b.py
python -m trace --report \
--file contadores.dat \
-C cobertura--no-report evita generar listados intermedios. El último comando produce un reporte combinado.
Evita escrituras concurrentes
El archivo de contadores no es una base de datos transaccional. Varios procesos escribiendo simultáneamente pueden perder o corromper información. Da a cada worker su propio archivo y combina los resultados de forma controlada.
Ejecuta un módulo
La opción --module ejecuta un módulo en lugar de una ruta de script.
python -m trace --count --module mi_paquete.cliEsta modalidad conserva mejor el contexto de imports relativos del paquete.
Usa la clase Trace
La clase trace.Trace ofrece control programático.
import sys
import trace
tracer = trace.Trace(
count=True,
trace=False,
ignoredirs=[sys.prefix, sys.exec_prefix],
)
tracer.runfunc(ejecutar_escenario)
resultados = tracer.results()
resultados.write_results(
show_missing=True,
summary=True,
coverdir="cobertura",
)runfunc() es preferible a construir una string para run() cuando ya tienes una función Python.
run, runctx y runfunc
run() acepta texto o un objeto de código adecuado para exec(). runctx() también recibe diccionarios de globals y locals. runfunc() invoca un callable con sus argumentos.
tracer.runctx(
"resultado = calcular(valor)",
{"calcular": calcular},
{"valor": 10},
)Nunca interpolas entrada externa dentro del comando. run() y runctx() ejecutan código Python real.
Configura el tipo de recolección
El constructor permite activar funciones independientes:
countregistra contadores por línea.traceimprime líneas ejecutadas.countfuncsenumera funciones.countcallersregistra relaciones de llamada.timingmuestra tiempo relativo.
Activa únicamente lo necesario. Combinar varios modos aumenta el overhead y el volumen de información.
Lee resultados acumulados
results() devuelve un objeto CoverageResults sin reiniciar los datos.
primero = tracer.results()
tracer.runfunc(otro_escenario)
segundo = tracer.results()El segundo resultado contiene el acumulado. Crea otra instancia de Trace cuando necesites aislamiento.
Combina CoverageResults
update() incorpora otro conjunto de resultados.
resultado_total.update(resultado_worker)Combina únicamente datos generados con la misma versión del código. Los contadores de commits diferentes no tienen una interpretación fiable juntos.
Archivos fuente eliminados
En versiones actuales, write_results() acepta ignore_missing_files=True.
resultados.write_results(
coverdir="cobertura",
ignore_missing_files=True,
)Es útil cuando un build elimina archivos generados. En una auditoría, una fuente ausente puede ser una señal importante y no debería ocultarse.
Cobertura no significa corrección
Una línea ejecutada puede producir un resultado incorrecto. Además, el módulo estándar no ofrece branch coverage, contextos, HTML ni plugins avanzados como Coverage.py.
Usa trace para diagnósticos rápidos, enseñanza y reportes sencillos. En proyectos grandes, adopta una herramienta especializada de cobertura.
trace y traceback son diferentes
La guía de traceback en Python explica cómo formatear pilas después de una excepción. trace acompaña la ejecución normal línea a línea. Uno explica cómo se llegó a un error; el otro puede mostrar el recorrido completo.
trace y tracemalloc son diferentes
tracemalloc en Python registra asignaciones de memoria. El nombre parecido no implica cobertura de líneas ni seguimiento del flujo.
trace y dis se complementan
dis en Python examina instrucciones compiladas, a menudo sin ejecutar el código. trace observa una ejecución concreta en runtime.
Threads y procesos hijos
El tracing depende de hooks del intérprete y puede no cubrir automáticamente todos los threads creados por bibliotecas. Los procesos hijos tienen runtimes separados. Inicia la recolección en cada worker y consolida después.
Async y generadores
Las líneas de coroutines y generators se cuentan cuando la ejecución entra en ellas. Crear un awaitable o generator sin aguardarlo o recorrerlo no añade cobertura. Los escenarios deben ejercer el flujo real.
Seguridad
- El tracer ejecuta el programa objetivo.
- No rastrees código no confiable en el proceso principal.
- Los reportes pueden exponer rutas y fuente.
- Restringe el directorio de salida.
- No aceptes expresiones externas para
run(). - Aplica timeout y límites de recursos.
- Protege archivos de contadores y reportes.
Buenas prácticas
- Ignora la biblioteca estándar y el entorno virtual.
- Usa
--modulepara paquetes. - Separa contadores por commit.
- No compartas un archivo entre workers.
- Revisa líneas ausentes, no solo porcentajes.
- Combina cobertura con tests de comportamiento.
- Mide el overhead del tracer.
- Usa Coverage.py para branch coverage.
Conclusión
trace en Python proporciona seguimiento de líneas, contadores de ejecución, listado de funciones y relaciones de llamada sin dependencias externas. Es valioso para diagnósticos rápidos, enseñanza y cobertura sencilla.
Consulta la documentación oficial de trace y la documentación oficial de Coverage.py.







