O que é e por que você se importa
Um chapéu de jiboia [1], conhecido tecnicamente como arquivo wheel (.whl), é um formato empacotado de distribuição de pacotes Python. Foi introduzido no PEP 427 para substituir os arquivos egg, que eram inconsistentes e causavam problemas reais de instalação. Se você já tentou instalar um pacote usando setup.py e viu aquela avalanche de erros de compilação, já sofreu com o problema que o wheel resolve. A nomenclatura do arquivo segue um padrão específico: nome_do_pacote-versão-python_tag-abi_tag-platform_tag.whl. Por exemplo, numpy-1.26.0-cp311-cp311-win_amd64.whl. O nome "jiboia" surgiu da comunidade brasileira porque a quantidade de travessões e underlines se parece visualmente com o formato de um chapéu. Não é um termo oficial, mas é amplamente usado em fóruns e lists de discussão.
Como criar um chapéu de jiboia [1] do seu projeto
O processo começa com a configuração correta do pyproject.toml. Você precisa especificar as metadadas básicas, os arquivos de origem e, se o seu pacote contiver código C ou Rust, as ferramentas de build. Aqui está uma configuração mínima funcional: pyproject.toml:
[build-system]
requires = ["setuptools>=68", "wheel"]
build-backend = "setuptools.build_meta" [project]
name = "meu_pacote"
version = "0.1.0"
dependencies = ["requests>=2.28"]
Depois disso, rode pip install build no diretório do projeto. O comando gera um diretório dist/ com o arquivo .whl dentro. Se o seu pacote tiver extensões nativas, o build vai compilar o código para a plataforma atual. Isso é importante: o wheel gerado localmente só funciona no sistema operacional e na arquitetura onde foi construído. Um wheel compilado no seu macOS ARM não vai instalar em um servidor Linux x86_64. Uma coisa que muita gente esquece é o campo classifiers do pyproject.toml. Ele não afeta a funcionalidade, mas define quais plataformas e versões do Python são anunciadas como compatíveis. Sem isso, ferramentas como pip podem fazer downgrade de versão ou rejeitar a instalação em plataformas não listadas. Adicione classifiers para Python :: 3 :: Only, Python :: 3.9, Python :: 3.10, Python :: 3.11, Operating System :: POSIX :: Linux, Operating System :: MacOS :: MacOS X, Operating System :: Microsoft :: Windows. Isso evita headaches futuros.
👉 Clique no botão abaixo para saber mais sobre o assunto!
Instalação e uso prático
Instalar um wheel é simples: pip install nome_do_arquivo.whl. Você pode apontar para um arquivo local ou para uma URL. O pip resolve as dependências automaticamente se elas estiverem listadas nos metadados do wheel. Se alguma dependência faltar, o pip tenta buscar no PyPI ou no índice configurado. O problema que eu enfrentei na prática foi com wheels que tinham tags de platform incorretas. Eu estava distribuindo um pacote com extensões C para um cliente que usava Alpine Linux com musl libc. O wheel foi construído corretamente no ambiente de desenvolvimento (Debian com glibc), mas a tag de platform estava genérica demais. Quando o cliente tentou instalar, o import falhava silenciosamente porque a biblioteca compartilhada procurava símbolos do glibc que não existem no musl. A solução foi usar auditwheel repair no ambiente Linux para reparar as tags e garantir a compatibilidade. Levei cerca de duas horas para identificar o problema porque o erro não aparecia na instalação — aparecia apenas no runtime, quando o import libminhaextenso.so falhava.
Outro detalhe importante: wheels podem ser binários ou source. Um source wheel (tag cp311-none-any) não tem código compilado e roda em qualquer plataforma com o Python correspondente. Um binary wheel (tag cp311-cp311-linux_x86_64) é específico. O pip preferencialmente instala binary wheels porque são mais rápidos. Se você quiser forçar uma fonte específica, use --no-binary :all: ou --only-binary :none:. Isso é útil em CI/CD onde você quer garantir que o código esteja sendo compilado no ambiente de destino.
Pegadinhas que ninguém conta
Primeiro, o wheel armazena os arquivos com caminhos absolutos internos. Se você extrair um .whl com unzip e inspecionar o conteúdo, vai ver que cada arquivo tem um caminho relativo à raiz do pacote. Mudar o diretório de instalação manualmente depois da extração pode quebrar imports. Segundo, wheels não suportam edit mode nativamente. Se você precisa desenvolver ativamente, use pip install -e . em vez de depender do wheel. Terceiro, o campo entry_points no setup.py ou pyproject.toml cria scripts executáveis na instalação. Eu já vi wheels que criavam dezenas de scripts desnecessários porque o autor não filtrou os entry points. Isso ocupa espaço e polui o PATH. Se o seu pacote depende de bibliotecas nativas externas (como libffi, OpenSSL, ou CUDA), o wheel por si só não resolve. Você precisa garantir que essas dependências estejam disponíveis no sistema de destino. Ferramentas como pip-tools ou conda help com isso, mas têm custos próprios. Conda empacota dependências binárias, mas é mais lento e pesado. pip com wheels é mais leve, mas exige que o ambiente do usuário tenha as bibliotecas corretas.
Quando um wheel não é a resposta
Se o seu projeto é puramente Python e não tem dependências binárias, um wheel funciona bem. Se tem extensões C/Rust compiladas, ainda funciona, mas você precisa gerar wheels multiplataforma. Se o projeto depende de um ambiente complexo (banco de dados, servidores, configurações de sistema), considere usar containers ou scripts de setup em vez de depender exclusivamente do wheel. Wheels resolvem distribuição de código Python, não infraestrutura. Para projetos grandes com muitas extensões, o tempo de build pode ser significativo. Build wheels para Linux x86_64, ARM64, Windows e macOS aumenta o tempo de CI. Uso GitHub Actions com matrix build e upload para um repositório privado. O processo leva cerca de 45 minutos em vez de 8 minutos de build único. Vale a pena se você distribui para múltiplas plataformas. Não vale a pena se seu público usa apenas um sistema.