tabnanny no Python: corrija indentação

Publicado em: 04/08/2026
Tempo de leitura: 7 minutos
Editor de código representando correção de tabs e espaços com tabnanny no Python

Python usa indentação para definir blocos, por isso tabs e espaços misturados podem produzir erros difíceis de perceber. Um arquivo pode parecer alinhado em um editor e formar níveis diferentes em outro, dependendo da largura configurada para a tabulação. O módulo tabnanny no Python analisa arquivos e diretórios para localizar indentação ambígua antes que ela cause falhas ou comportamentos inconsistentes.

Neste guia, você aprenderá a executar o módulo pela terminal, verificar projetos recursivamente, integrar check() e process_tokens() a ferramentas e criar uma política confiável de whitespace. O conteúdo complementa nossos artigos sobre tokenize no Python, IndentationError, TabError, bytecode com dis e boas práticas em scripts.

Por que tabs e espaços causam problemas

Um caractere tab não representa uma quantidade fixa de espaços na tela. Editores podem exibi-lo com largura 2, 4 ou 8. Duas linhas visualmente alinhadas podem conter sequências diferentes.

if ativo:
	processar()
    finalizar()

Dependendo das colunas efetivas, o interpretador pode emitir TabError, IndentationError ou interpretar os blocos de modo diferente do esperado.

O que tabnanny detecta

Tabnanny procura indentação cuja interpretação depende do tamanho atribuído às tabs. Ele não é um formatador e não reescreve o arquivo. Seu objetivo é apontar linhas ambíguas para que o desenvolvedor corrija a origem.

A documentação oficial de tabnanny informa que o módulo é pensado principalmente para execução como script, embora possa ser importado por IDEs.

Verificar um arquivo

Execute o módulo com -m e informe o caminho.

python -m tabnanny programa.py

Quando não há problemas, normalmente nenhuma mensagem é exibida. Se uma ambiguidade for encontrada, o diagnóstico inclui arquivo, linha e informações sobre a indentação problemática.

Verificar um diretório

Ao receber um diretório, tabnanny percorre recursivamente sua árvore e analisa arquivos com extensão .py.

python -m tabnanny src

Diretórios que são links simbólicos não são percorridos como diretórios comuns. Ainda assim, projetos grandes devem controlar o ponto inicial para evitar analisar ambientes virtuais, dependências copiadas e diretórios gerados.

Modo verboso

A opção -v aumenta as mensagens de progresso.

python -m tabnanny -v src

Repetir a opção pode incrementar o nível interno de verbosidade. Use em diagnósticos locais; em integração contínua, uma saída curta costuma ser mais útil.

Mostrar somente nomes

A opção -q ativa o modo que imprime apenas nomes de arquivos com problemas.

python -m tabnanny -q src

Esse formato pode alimentar scripts que agregam resultados, mas perde detalhes de linha. Para correção manual, execute novamente sem -q.

Usar check() programaticamente

tabnanny.check() aceita um arquivo ou diretório.

import tabnanny

tabnanny.check("src")

As mensagens são impressas em saída padrão por meio de print(). A função não foi desenhada como uma API estruturada moderna, então capturar resultados exige redirecionar a saída ou usar as funções internas com cuidado.

Capturar a saída

from contextlib import redirect_stdout
from io import StringIO
import tabnanny

saida = StringIO()

with redirect_stdout(saida):
    tabnanny.check("src")

relatorio = saida.getvalue()
print(relatorio)

O redirecionamento de stdout afeta o processo e não é ideal em múltiplas threads. Em ferramentas concorrentes, execute a verificação em subprocesso.

Processar tokens diretamente

process_tokens() recebe tokens produzidos pelo módulo tokenize.

import tabnanny
import tokenize

with open("programa.py", "rb") as arquivo:
    tokens = tokenize.tokenize(arquivo.readline)
    tabnanny.process_tokens(tokens)

Ao detectar ambiguidade, a função gera NannyNag. check() captura essa exceção e imprime o diagnóstico.

Capturar NannyNag

try:
    with open("programa.py", "rb") as arquivo:
        tokens = tokenize.tokenize(arquivo.readline)
        tabnanny.process_tokens(tokens)
except tabnanny.NannyNag as erro:
    print("Indentação ambígua:", erro)

A exceção carrega informações usadas pelo diagnóstico, mas essa superfície pode mudar. A documentação alerta que a API do módulo não é estável entre releases.

API sujeita a mudanças

Tabnanny é antigo e orientado à linha de comando. Ferramentas que importam seus detalhes internos devem fixar versões, criar testes de compatibilidade e oferecer uma alternativa.

Para um produto que precisa de dados estruturados estáveis, considere chamar python -m tabnanny em subprocesso ou implementar uma regra própria baseada nos tokens INDENT e DEDENT.

tabnanny versus TabError

TabError ocorre quando o próprio interpretador encontra uso inconsistente de tabs e espaços durante a compilação. Tabnanny permite verificar uma árvore inteira sem importar ou executar os módulos.

Assim, ele funciona como inspeção preventiva em commits, builds e editores.

tabnanny versus IndentationError

IndentationError abrange problemas mais gerais, como bloco ausente, recuo inesperado ou dedent incompatível.

if ativo:
print("faltou recuo")

Tabnanny tem foco específico em ambiguidades relacionadas a whitespace. Um projeto deve também compilar ou analisar a sintaxe para descobrir os demais erros.

Integrar à integração contínua

Um job simples pode verificar a pasta do projeto.

python -m tabnanny src tests

Antes de usar, confirme o código de saída da versão e do ambiente escolhidos. Como a ferramenta foi desenhada para imprimir diagnósticos, pipelines mais robustos podem executar uma pequena camada que captura saída e retorna status não zero quando encontra mensagens.

import subprocess
import sys

resultado = subprocess.run(
    [sys.executable, "-m", "tabnanny", "src"],
    capture_output=True,
    text=True,
)

if resultado.stdout.strip() or resultado.stderr.strip():
    print(resultado.stdout)
    print(resultado.stderr)
    raise SystemExit(1)

Teste esse wrapper com um arquivo propositalmente ambíguo.

Git pre-commit

A verificação pode rodar antes do commit, preferencialmente apenas nos arquivos Python alterados.

python -m tabnanny arquivo1.py arquivo2.py

Como a interface padrão recebe caminhos, um script pode invocá-la uma vez por arquivo. Não inclua ambientes virtuais ou artefatos gerados.

Corrigir o problema

A correção mais segura é converter a indentação para espaços, normalmente quatro por nível, sem alterar alinhamentos internos em strings.

Use o comando de conversão de tabs do editor, revise o diff e execute testes. Não faça substituição global de \t em todo o arquivo, pois tabs dentro de strings e dados podem ser intencionais.

Configurar o editor

Ative:

  • inserção de espaços ao pressionar Tab;
  • largura visual de quatro espaços;
  • exibição de caracteres invisíveis;
  • remoção de whitespace no fim da linha;
  • detecção de indentação por arquivo.

Arquivos de configuração como .editorconfig ajudam a compartilhar a política entre IDEs.

Formatadores e linters

Ferramentas como Black geralmente normalizam indentação em código válido. Linters podem detectar tabs e inconsistências adicionais. Tabnanny continua útil por fazer parte da biblioteca padrão e exigir nenhuma dependência.

A ordem recomendada é: detectar sintaxe inválida, corrigir ambiguidade, formatar e executar testes.

Arquivos gerados e dependências

Não altere automaticamente código de terceiros dentro de um ambiente virtual. Exclua diretórios como .venv, build, dist e caches ao escolher a raiz de verificação.

Se um arquivo gerado precisa ser analisado, corrija o gerador, não apenas o resultado.

Encoding

Tabnanny usa tokenize, que respeita BOM e cookies de encoding. Um problema de encoding pode surgir antes da análise de indentação.

Abra e salve projetos modernos em UTF-8 e mantenha testes para arquivos legados que usam outra codificação.

Código temporariamente incompleto

Durante a digitação, um arquivo pode conter strings ou parênteses abertos. A tokenização pode gerar TokenError. IDEs devem esperar um pequeno intervalo ou analisar somente após salvar.

Não transforme cada estado intermediário em um alerta persistente.

Exemplo de verificador isolado

from pathlib import Path
import subprocess
import sys


def verificar(caminho: Path) -> list[str]:
    resultado = subprocess.run(
        [sys.executable, "-m", "tabnanny", str(caminho)],
        capture_output=True,
        text=True,
        timeout=30,
    )
    linhas = []
    linhas.extend(resultado.stdout.splitlines())
    linhas.extend(resultado.stderr.splitlines())
    return [linha for linha in linhas if linha.strip()]

O timeout evita uma varredura sem controle em árvores inesperadamente grandes.

Segurança

A ferramenta lê código sem executá-lo, o que é mais seguro que importar módulos. Contudo, caminhos não confiáveis podem apontar para árvores enormes ou arquivos especiais.

Resolva a raiz permitida, recuse caminhos fora dela, limite quantidade e tamanho dos arquivos e execute com permissões mínimas.

Erros frequentes

  • Esperar que tabnanny reformate o código.
  • Verificar toda a pasta do ambiente virtual.
  • Capturar stdout globalmente em servidor multithread.
  • Depender de detalhes internos sem fixar a versão.
  • Substituir tabs dentro de strings.
  • Confundir qualquer IndentationError com ambiguidade de tabs.
  • Ignorar arquivos gerados pelo projeto.
  • Usar uma árvore de entrada sem limites.

Boas práticas

  • Padronize quatro espaços.
  • Execute tabnanny em arquivos alterados e na CI.
  • Combine com parser, formatter e testes.
  • Exclua dependências e artefatos.
  • Use subprocesso para integração concorrente.
  • Teste a compatibilidade da versão.
  • Corrija o gerador quando o arquivo for gerado.
  • Proteja a raiz e limite recursos.

Conclusão

O módulo tabnanny no Python detecta indentação ambígua causada pela combinação de tabs e espaços. Ele pode analisar um arquivo ou percorrer diretórios, tornando-se uma verificação leve para editores, hooks e pipelines.

Seu escopo é específico e sua API programática pode mudar, mas a utilidade é clara: localizar problemas de whitespace antes da execução. Com uma política de quatro espaços, visualização de caracteres invisíveis, formatador e testes, tabnanny ajuda a manter blocos Python previsíveis em qualquer editor.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    Código-fonte e sintaxe representando análise lexical com tokenize no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    tokenize no Python: analise código-fonte

    Aprenda tokenize no Python para analisar tokens, comentários, encoding, posições e reconstruir código-fonte com segurança.

    Ler mais

    Tempo de leitura: 6 minutos
    04/08/2026
    Terminal de programação representando compilação de entradas interativas com codeop no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    codeop no Python: compile entradas interativas

    Aprenda codeop no Python para detectar entradas completas, compilar comandos de REPL e preservar __future__ com segurança.

    Ler mais

    Tempo de leitura: 6 minutos
    04/08/2026
    Desenvolvedor analisando estrutura de código e tabelas de símbolos com symtable no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    symtable no Python: escopos e símbolos

    Aprenda symtable no Python para analisar escopos, símbolos, globals, nonlocals, closures, imports, annotations e type parameters.

    Ler mais

    Tempo de leitura: 7 minutos
    03/08/2026
    Monitor com código binário representando análise de bytecode com dis no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    dis no Python: entenda o bytecode

    Aprenda dis no Python para desmontar bytecode, analisar instruções, caches adaptativos, posições, tracebacks e detalhes do CPython.

    Ler mais

    Tempo de leitura: 7 minutos
    03/08/2026
    Tela de erro representando diagnóstico de crashes e deadlocks com faulthandler no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    faulthandler no Python: diagnostique travamentos

    Aprenda faulthandler no Python para diagnosticar crashes, deadlocks e timeouts com pilhas de threads e código nativo.

    Ler mais

    Tempo de leitura: 8 minutos
    03/08/2026
    Notebook com código representando análise de traceback e depuração no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    traceback no Python: erros e pilha

    Aprenda traceback no Python para capturar, formatar e registrar pilhas de erro com segurança, sem vazar dados ou reter memória.

    Ler mais

    Tempo de leitura: 6 minutos
    03/08/2026