O módulo trace no Python acompanha a execução de instruções, conta quantas vezes cada linha foi executada, lista funções chamadas e mostra relações entre callers e callees. Ele pode ser usado pela linha de comando ou dentro de outra aplicação para diagnosticar fluxos difíceis de reproduzir e gerar uma cobertura simples.
O recurso é leve em configuração, mas não em overhead: rastrear cada linha altera significativamente o desempenho. Use-o em desenvolvimento, testes e cenários controlados, nunca como monitoramento permanente de produção sem medir o impacto.
Conte linhas executadas
A opção --count executa um script e gera arquivos .cover anotados.
python -m trace --count -C cobertura aplicacao.pyCada linha executável recebe um contador. Linhas sem número podem ser comentários, docstrings, declarações não rastreáveis ou código não alcançado.
Marque linhas ausentes
--missing marca com >>>>>> as linhas que poderiam ser executadas, mas não foram.
python -m trace \
--count \
--missing \
--summary \
-C cobertura \
aplicacao.pyO resumo por arquivo ajuda a identificar módulos pouco exercitados, mas cobertura de linha não garante cobertura de condições, combinações ou comportamento.
Mostre cada linha em tempo real
--trace imprime as linhas à medida que são executadas.
python -m trace --trace tarefa.pyA saída pode ser enorme. Filtre bibliotecas padrão e dependências para concentrar o relatório no código da aplicação.
Inclua tempo relativo
--timing adiciona o tempo desde o início antes de cada linha rastreada.
python -m trace --trace --timing tarefa.pyOs valores ajudam a perceber pausas, mas não substituem profiling. O custo do próprio tracer interfere nos intervalos. Para análise de tempo por função, use o conjunto de pstats no Python com cProfile.
Liste funções executadas
--listfuncs mostra as funções encontradas durante a execução.
python -m trace --listfuncs aplicacao.pyEssa opção é mutuamente exclusiva com --trace e --count. Ela é útil para confirmar quais handlers, callbacks e caminhos foram realmente usados.
Rastreie relações de chamadas
--trackcalls mostra quem chamou quem.
python -m trace --trackcalls aplicacao.pyO relatório é mais simples que um profiler completo, mas ajuda a visualizar acoplamentos e caminhos inesperados entre módulos.
Ignore módulos
--ignore-module aceita nomes separados por vírgula e pode ser repetido.
python -m trace \
--count \
--ignore-module=urllib,json \
-C cobertura \
aplicacao.pyIgnorar dependências reduz ruído. Não exclua código apenas para melhorar a porcentagem do relatório; documente a política.
Ignore diretórios
--ignore-dir exclui módulos localizados em diretórios informados.
python -m trace \
--count \
--ignore-dir=.venv \
-C cobertura \
aplicacao.pyEm múltiplos diretórios, use o separador de caminhos do sistema operacional. Resolva caminhos para evitar que um nome relativo ignore mais arquivos que o esperado.
Acumule várias execuções
--file armazena contadores para juntar cenários.
python -m trace --count --no-report \
--file contagens.dat teste_a.py
python -m trace --count --no-report \
--file contagens.dat teste_b.py
python -m trace --report \
--file contagens.dat \
-C cobertura--no-report evita gerar listagens intermediárias. O comando final produz um relatório agregado.
Não compartilhe arquivos simultaneamente
O arquivo de contagens não é um banco transacional. Vários processos gravando ao mesmo tempo podem perder ou corromper dados. Gere um arquivo por worker e consolide os resultados de maneira controlada.
Execute módulos
A opção --module permite executar um módulo em vez de um caminho de script.
python -m trace --count --module meu_pacote.cliIsso preserva melhor o contexto de imports relativos do pacote.
Use a API Trace
A classe trace.Trace oferece controle programático.
import sys
import trace
tracer = trace.Trace(
count=True,
trace=False,
ignoredirs=[sys.prefix, sys.exec_prefix],
)
tracer.runfunc(executar_cenario)
resultados = tracer.results()
resultados.write_results(
show_missing=True,
summary=True,
coverdir="cobertura",
)runfunc() é preferível a construir strings para run() quando você já possui uma função Python.
run, runctx e runfunc
run() recebe string ou objeto de código adequado a exec(). runctx() também aceita dicionários de globais e locais. runfunc() chama uma função com argumentos.
tracer.runctx(
"resultado = calcular(valor)",
{"calcular": calcular},
{"valor": 10},
)Nunca monte a string com entrada externa. run() e runctx() executam código real.
Configure o tipo de coleta
O construtor possui opções independentes:
countconta linhas.traceimprime linhas executadas.countfuncsregistra funções.countcallersregistra relações.timinginclui tempo relativo.
Ative apenas o necessário. Combinar saída linha a linha e contagem aumenta o overhead e o volume de dados.
Leia resultados acumulados
results() devolve CoverageResults sem resetar os dados.
r1 = tracer.results()
tracer.runfunc(outro_cenario)
r2 = tracer.results()O segundo resultado contém o acumulado. Crie outra instância quando precisar de isolamento.
Mescle CoverageResults
update() incorpora outro conjunto de resultados.
resultado_total.update(resultado_worker)Garanta que os arquivos se referem à mesma versão da fonte. Contagens de commits diferentes não devem ser agregadas.
Arquivos removidos
write_results() pode receber ignore_missing_files=True nas versões atuais.
resultados.write_results(
coverdir="cobertura",
ignore_missing_files=True,
)Use a opção em builds que limpam arquivos gerados. Em auditorias, uma fonte ausente pode ser sinal importante e não deve ser ocultada.
Cobertura não é prova de qualidade
Uma linha executada pode produzir resultado errado. Além disso, o módulo padrão não oferece os recursos avançados de branch coverage, contextos, HTML e plugins presentes no Coverage.py.
Use trace para inspeções rápidas, ferramentas educacionais e diagnósticos simples. Em projetos grandes, adote uma ferramenta de cobertura dedicada.
Trace versus traceback
traceback no Python formata pilhas depois de exceções. trace acompanha a execução normal linha a linha. Um responde “como chegamos ao erro”; o outro pode mostrar “quais linhas foram percorridas”.
Trace versus tracemalloc
tracemalloc no Python registra alocações de memória. Apesar do nome parecido, não mede cobertura nem fluxo de linhas.
Trace versus dis
dis no Python examina instruções compiladas sem necessariamente executar o código. trace observa eventos reais de uma execução específica. Os resultados se complementam.
Threads e processos
O tracing depende dos hooks do interpretador e pode não cobrir automaticamente todos os threads criados por bibliotecas. Processos filhos possuem runtimes separados. Execute a coleta em cada worker e consolide resultados.
Async e generators
Linhas de corrotinas e generators são registradas quando a execução entra nelas. Um objeto criado mas nunca aguardado ou iterado não contribui com contagens. Escreva cenários que realmente exercitam o fluxo assíncrono.
Segurança
- O tracer executa o programa alvo.
- Não rastreie código não confiável no processo principal.
- Os relatórios podem conter caminhos e fonte.
- Restrinja o diretório de saída.
- Não aceite expressões externas para
run(). - Use timeout e limite de recursos.
- Proteja arquivos de contagem.
Boas práticas
- Ignore biblioteca padrão e ambiente virtual.
- Use
--modulepara pacotes. - Separe contagens por commit.
- Não grave o mesmo arquivo em paralelo.
- Analise linhas ausentes, não apenas porcentagens.
- Combine com testes comportamentais.
- Meça o overhead.
- Use Coverage.py quando precisar de branches.
Conclusão
O trace no Python oferece rastreamento linha a linha, contagem de execução, listagem de funções e relações de chamadas sem dependências externas. Ele é valioso para diagnósticos rápidos e cobertura simples.
Consulte a documentação oficial do trace e a documentação oficial do Coverage.py.







