O que é o PyPI e por que essa mudança importa
O PyPI (Python Package Índex) e o repositório oficial de pacotes Python. E nele que você pública e instala bibliotecas com o famoso pip install nome-pacote. Em julho de 2026, o time do PyPI anunciou uma mudança importante: releases publicadas ha mais de 14 dias não aceitam mais a adição de novos arquivos.
Na prática, isso significa que se você publicou a versão 1.2.0 do seu pacote e, duas semanas depois, quiser adicionar um wheel novo, o PyPI vai rejeitar o upload. A única saída e publicar uma versão nova, como 1.2.1 ou 1.2.0.post1.
A mudança entrou em vigor de forma imediata e rapidamente virou um dos posts mais comentados do Hacker News. A maioria dos desenvolvedores aprovou, mas também gerou duvidas sobre como adaptar os workflows existentes.
Como funciona a nova política
A regra e simples: cada release no PyPI tem uma janela de 14 dias após a data de criação para receber novos arquivos. Passado esse prazo, a release fica bloqueada para adições. Você ainda pode fazer yank (marcar como não recomendada) ou deletar a release inteira, mas não pode adicionar arquivos novos.
O bloqueio se aplica a todos os tipos de artefato: wheels (.whl), source distributions (.tar.gz) e qualquer outro arquivo associado a release. Não ha exceção por tipo, tamanho ou popularidade do pacote.
A regra vale tanto para o PyPI oficial (pypi.org) quanto para o ambiente de testes (test.pypi.org). Use o test.pypi.org para validar seus artefatos antes da publicação definitiva.
Quando você tenta fazer upload de um arquivo para uma release com mais de 14 dias, o PyPI retorna um erro HTTP 400 com uma mensagem clara indicando que a release esta encerrada. O comportamento e consistente via interface web e via linha de comando com twine.
Principais impactos para desenvolvedores
A mudança afeta principalmente quem tinha o hábito de publicar releases de forma incremental, adicionando wheels para diferentes plataformas ao longo de dias ou semanas. Isso era comum em projetos com extensões nativas (C, Rust, Fortran) que precisam compilar para Linux, macOS e Windows separadamente.
Outros cenários afetados incluem: adicionar suporte a uma nova versão do Python em uma release existente, corrigir um arquivo de source distribution com problema e publicar wheels para arquiteturas emergentes (como ARM64) após a release inicial.
Se você mantem um pacote popular com suporte a múltiplas plataformas, esta e a hora certa para revisar seu pipeline de CI/CD e garantir que todos os artefatos sejam gerados antes da publicação.
Para pacotes puré Python (sem extensões nativas), a mudança tem impacto menor. Esses pacotes geralmente tem apenas um wheel universal e um source distribution, publicados de uma vez.
Como adaptar seu workflow de publicação
O ajuste mais importante e centralizar a publicação. Você precisa garantir que todos os artefatos estejam prontos antes de criar a release no PyPI. O campo needs: build no GitHub Actions garante que o job de publish só roda depois que todos os builds terminaram com sucesso:
jobs:
build:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, Windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Build wheel
run: pip wheel . -w dist/
- uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.os }}
path: dist/*.whl
publish:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
with:
pattern: wheels-*
merge-multiple: true
path: dist/
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1Assim, o upload acontece em uma única etapa com todos os wheels disponíveis, sem risco de release parcial.
Exemplo prático com cibuildwheel
Para pacotes com extensões nativas, o cibuildwheel e a ferramenta padrão para gerar wheels para múltiplas plataformas e versões do Python. Com a nova política do PyPI, o workflow ideal combina cibuildwheel com upload único:
# Instalar cibuildwheel
pip install cibuildwheel
# Construir wheels para a plataforma atual
Python -m cibuildwheel --output-dir wheelhouse
# Validar os artefatos antes de publicar
twine check wheelhouse/*.whl dist/*.tar.gz
# Publicar tudo de uma vez
twine upload wheelhouse/*.whl dist/*.tar.gzConfigure o job de publish para rodar apenas quando uma tag de versão for criada (on: push: tags: v*). Isso evita publicações acidentais e garante um processo de release consistente e automatizado.
O repositório oficial do cibuildwheel no GitHub tem exemplos completos de workflows para os principais casos de uso. Vale a pena conferir mesmo que você não use extensões nativas.
Comparação com outras plataformas de pacotes
O PyPI era, na prática, mais permissivo que a maioria dos repositórios de pacotes. Outros ecossistemas já adotam imutabilidade ha anos: o npm (JavaScript) não permite modificar o conteúdo de uma versão publicada; o crates.io (Rust) também é completamente imutável; o Maven Central (Java) exige imutabilidade total antes mesmo do lançamento.
A nova política coloca o PyPI em linha com esses ecossistemas. A diferença e que o PyPI ainda permite adições dentro da janela de 14 dias, o que é um equilíbrio razoável entre flexibilidade para correções rápidas e segurança a longo prazo.
Para pacotes internos, ferramentas como Artifactory, Nexus ou o CodeArtifact da AWS permitem configurar suas próprias políticas de imutabilidade independentemente desta mudança.
Pontos positivos e limitações
A principal vantagem da mudança e a segurança. Releases imutáveis eliminam a janela de ataque de substituição de artefato, onde um arquivo malicioso poderia ser adicionado a uma versão confiável depois da publicação. Para empresas que precisam de reproducibilidade de builds, releases com histórico auditavel são muito mais confiáveis.
A limitação mais sentida e para projetos menores, com poucos mantenedores, que adicionavam suporte a novas plataformas de forma incremental. Esses projetos precisarão ajustar o workflow ou aceitar publicar versões de patch mais frequentemente.
Não crie versões idênticas com números diferentes apenas para adicionar artefatos. Isso confunde usuários e ferramentas de lockfile como pip-tools e Poetry, que podem instalar a versão errada.
O mecanismo de yanking continua funcionando normalmente. Marcar uma versão como yanked não adiciona arquivos, apenas sinaliza que aquela versão não e recomendada. Isso não e afetado pela nova política.
Casos de uso reais
Desenvolvedor de biblioteca open source com extensões C: você mantem uma biblioteca com wheels para Linux, macOS e Windows. Antes, publicava o wheel Linux no dia 1 e adicionava os outros ao longo da semana. Agora, você precisa gerar todos antes de publicar. A solução e um workflow de CI que faz tudo em paralelo.
Time de DevOps em empresa: você tem um pacote interno publicado em um repositório privado. A nova política não afeta repositórios privados diretamente, mas e uma boa oportunidade para revisar o processo de release interno também.
Contribuidor ocasional: você publicou uma versão e depois percebeu que esqueceu um wheel para Python 3.13. Se ainda estiver dentro do prazo de 14 dias, você pode adicionar. Se não, publique uma versão .post1.
Mantenedor de pacote científico: pacotes como numpy e scipy geram wheels para muitas combinações de plataforma e versão do Python. Para esses projetos, o cibuildwheel rodando em CI já era o padrão, então a mudança tem impacto mínimo.
Dicas e boas práticas
Use o comando twine check dist/* antes de publicar para validar todos os artefatos. Ele verifica o conteúdo dos wheels e source distributions sem precisar fazer upload.
Configure o MANIFEST.in corretamente para garantir que o source distribution inclua todos os arquivos necessários. Muitos problemas de release poderiam ser evitados com uma validação local antes de publicar.
Verifique se seu workflow atual tem etapas que adicionam arquivos a uma release existente dias depois da publicação. Esses passos precisam ser migrados para antes do upload inicial.
Use o PyPI Test para fazer um dry run completo antes de publicar no PyPI oficial. Assim você valida que todos os artefatos fazem upload corretamente antes de criar a release definitiva.
Vale a pena?
A mudança do PyPI e positiva para o ecossistema como um todo. A imutabilidade de releases e uma prática consagrada em outros gerenciadores de pacotes, e o Python estava atrasado nesse ponto. Para a maioria dos projetos, o ajuste necessário e pequeno: centralizar o upload no momento da release.
Para quem ainda não usa CI/CD para publicação de pacotes, esta e uma boa oportunidade para adotar. Ferramentas como cibuildwheel, twine e GitHub Actions tornam o processo simples e reproducivel.
O próximo passo e revisar o workflow de CI/CD do seu pacote e garantir que todos os artefatos sejam gerados e publicados em uma única etapa. Se você ainda não tem um workflow automatizado, o repositório do cibuildwheel no GitHub tem exemplos prontos para os principais casos de uso.
Comentários
Deixar um comentárioVocê precisa ter uma conta no Do Zero ao Junior para comentar.