Programação na Prática09/09/2026Redação de Tecnologia e Desenvolvimento10 min de leituraAtualizado em 15/09/2026

Python 3.15: APIs removidas que podem quebrar extensões e checklist de portabilidade antes de 1º de outubro

Veja quais APIs Python e C foram removidas no 3.15, quais substitutos usar e como testar extensões e código antes do lançamento final previsto para 1º de outubro.

Estação de desenvolvimento com símbolo do Python ao centro, erros em vermelho à esquerda e verificações de compatibilidade em verde à direita.

Python 3.15.0rc2 foi publicado em 1º de setembro de 2026 como o último candidato planejado, e o Python 3.15.0 final está previsto para 1º de outubro. A partir da fase de release candidate, o projeto informa que não haverá novas mudanças de ABI na série 3.15 e que alterações de código devem ficar restritas a correções claras. Para quem mantém bibliotecas ou extensões nativas, isso transforma o RC2 na melhor janela para descobrir incompatibilidades antes da versão final.

O risco não está apenas em “compilar ou não compilar”. Há símbolos removidos da C API, APIs Python que desapareceram ou ficaram mais estritas e mudanças de comportamento que podem quebrar testes sem causar erro de importação. O roteiro abaixo separa esses três grupos e, para cada item com impacto de portabilidade, indica a migração recomendada e um teste mínimo.

RC2 é a janela de teste que importa

O RC2 de 1º de setembro é o último candidato planejado. O cronograma oficial mantém o Python 3.15.0 final para 1º de outubro de 2026. A página do RC2 também afirma que não haverá mudanças de ABI daqui até o final da série 3.15, salvo o objetivo geral de reduzir mudanças ao mínimo. Isso não torna o RC2 uma versão recomendada para produção, mas torna seus resultados de compatibilidade especialmente úteis.

O foco aqui é portabilidade de código e extensões, não empacotamento de wheels. O teste essencial é executar a suíte no 3.15 RC2 e, quando houver C ou C++, reconstruir a extensão a partir do código-fonte contra os headers do 3.15.

APIs Python removidas ou endurecidas

Área O que muda no 3.15 Substituto ou ajuste Teste mínimo
ast Construtores de nós passam a levantar TypeError quando faltam campos obrigatórios ou aparecem nomes que não correspondem a campos válidos. Instancie o nó com todos os campos obrigatórios e apenas argumentos documentados. Rode os testes que criam ou transformam AST e force a execução das rotas de geração de código.
collections.abc.ByteString ByteString saiu de collections.abc.__all__; o símbolo continua descontinuado e tem remoção prevista para 3.17. Para protocolo de buffer em runtime, use collections.abc.Buffer; para tipos, use Buffer ou uma união explícita como bytes | bytearray | memoryview. Teste imports explícitos e qualquer import com asterisco que esperava receber ByteString.
ctypes.SetPointerType() A função não documentada foi removida. Não há substituto 1:1 documentado; prefira APIs públicas de ponteiros, como ctypes.POINTER(T), e elimine dependência de detalhes internos. Importe o módulo que monta tipos ctypes e exercite criação, leitura e escrita dos ponteiros usados pela biblioteca.
datetime.strptime() Formato com %d sem diretiva de ano agora pode levantar ValueError. Inclua o ano na entrada e na string de formato quando o dia do mês fizer parte do parsing. Adicione caso de teste com o formato antigo e confirme que a entrada real agora inclui ano.
glob.glob0()/glob.glob1() As funções internas não documentadas foram removidas. Use glob.glob() e passe root_dir quando precisar limitar a busca a um diretório. Compare o conjunto de caminhos retornados antes e depois da migração em uma árvore temporária.
http.server CGI CGIHTTPRequestHandler e a opção --cgi de python -m http.server foram removidos. Não existe substituto CGI 1:1 na biblioteca padrão; remova essa dependência e execute a aplicação em uma solução de servidor apropriada. Faça um smoke test do comando de desenvolvimento/integração que antes iniciava o modo CGI.
importlib loaders Loader.load_module() e implementações correspondentes foram removidos do protocolo usado pelo sistema de importação. Implemente exec_module(); quando necessário, implemente também create_module() conforme o protocolo moderno. Instale o finder/loader personalizado em sys.meta_path ou sys.path_hooks e importe/recarregue um módulo real.
importlib.resources.files() O parâmetro nomeado package foi removido. Passe anchor, de preferência posicionalmente. Para uma interface compatível com Pythons antigos, a documentação sugere importlib_resources >= 5.10. Execute a leitura de um recurso do pacote usando exatamente a chamada usada em produção.
pathlib.PurePath.is_reserved() O método foi removido. Use os.path.isreserved(). Teste nomes reservados e nomes comuns, especialmente no Windows.
platform.java_ver() A função foi removida; era voltada ao suporte a Jython e tinha API considerada confusa e pouco testada. Não há substituto direto no CPython; remova a dependência ou obtenha os dados do runtime Java pela plataforma que realmente os fornece. Procure chamadas no código e execute a inicialização em qualquer ambiente Java/Jython ainda suportado pelo projeto.
sre_compile, sre_constants, sre_parse Os módulos internos sre_* foram removidos. Migre para APIs públicas de re, como re.compile(), Pattern e funções documentadas. Não trate a estrutura interna do parser como contrato estável. Rode testes de compilação e introspecção de expressões regulares que importavam sre_* diretamente.
sysconfig.is_python_build(check_home=...) O parâmetro check_home foi removido. Chame sysconfig.is_python_build() sem esse argumento e ajuste a lógica do chamador se ela dependia do comportamento antigo. Teste a detecção em uma árvore de build e em uma instalação normal.
threading.RLock() A implementação em C não aceita mais argumentos posicionais ou nomeados arbitrários que antes eram ignorados. Instancie RLock() sem argumentos. Procure RLock( em fábricas e wrappers e execute o caminho que cria cada lock.
types.CodeType.co_lnotab O atributo co_lnotab foi removido. Use code.co_lines() para mapear intervalos de bytecode para linhas; use APIs documentadas de posição quando precisar de dados mais ricos. Rode profilers, tracers, coverage ou ferramentas de inspeção que leem metadados de objetos de código.
typing.ByteString ByteString saiu de typing.__all__; continua descontinuado e com remoção prevista para 3.17. Use collections.abc.Buffer ou tipos explícitos adequados ao contrato da função. Teste imports com asterisco e execute o verificador de tipos adotado pelo projeto.
typing.NamedTuple A sintaxe não documentada NamedTuple("Point", x=int, y=int) deixou de ser aceita. Use a sintaxe baseada em classe ou a sintaxe funcional documentada. Importe todos os módulos que definem NamedTuple em runtime e instancie cada tipo.
typing.TypedDict TypedDict("TD") e TypedDict("TD", None) para zero campos não são mais aceitos. Use class TD(TypedDict): pass ou TypedDict("TD", {}). Importe os módulos de tipos em runtime e execute o type checker para garantir equivalência.
typing.no_type_check_decorator O decorador foi removido. Quando realmente necessário, aplique typing.no_type_check diretamente à função ou classe que deve ter anotações ignoradas. Procure o nome removido no código e execute import + checagem estática do módulo migrado.
wave getmark()/setmark()/getmarkers() Os métodos de compatibilidade com o antigo aifc foram removidos. Não há substituto equivalente; elimine chamadas que dependiam desses marcadores. Leia e escreva um WAV representativo e confirme que nenhuma rota chama os métodos removidos.
zipimport.zipimporter.load_module() O método foi removido. Use exec_module() no fluxo moderno de importação. Crie um arquivo ZIP de teste com um módulo e valide importação e recarga pelo loader usado pelo projeto.

C API: símbolos que deixam de compilar

Nas extensões C/C++, o primeiro sinal costuma ser erro de compilação ou link. As remoções abaixo estão documentadas no “What’s New” do 3.15. Em chamadas que devolvem objetos, revise também as regras de referência do substituto: por exemplo, PyWeakref_GetRef() entrega uma referência forte nova quando o alvo está vivo.

API removida Substituto oficial Teste mínimo
PyUnicode_AsDecodedObject() / PyUnicode_AsDecodedUnicode() PyCodec_Decode(). Compile do zero e teste pelo menos um codec textual e qualquer codec que possa devolver bytes.
PyUnicode_AsEncodedObject() / PyUnicode_AsEncodedUnicode() PyCodec_Encode(). Compile do zero e valide o tipo retornado para os codecs usados pela extensão.
PyImport_ImportModuleNoBlock() PyImport_ImportModule(). Importe o módulo dependente durante a inicialização normal da extensão e confirme propagação de erro.
PyWeakref_GetObject() / PyWeakref_GET_OBJECT PyWeakref_GetRef(). Para Pythons antigos, a documentação aponta pythoncapi-compat. Teste weakref vivo, weakref morto e caminho de erro, conferindo INCREF/DECREF da nova referência.
PySys_ResetWarnOptions() Limpe sys.warnoptions e warnings.filters, conforme a orientação oficial. Configure filtros, invoque a rotina migrada e confirme o estado final e os avisos emitidos.
Py_GetExecPrefix() PyConfig_Get("base_exec_prefix"); use "exec_prefix" quando o ambiente virtual precisar ser considerado. Compare o resultado com sys.base_exec_prefix e sys.exec_prefix em instalação normal e venv.
Py_GetPath() PyConfig_Get("module_search_paths"). Compare a lista com sys.path depois da inicialização do interpretador.
Py_GetPrefix() PyConfig_Get("base_prefix"); use "prefix" para refletir venv. Compare com sys.base_prefix e sys.prefix em venv e fora dele.
Py_GetProgramFullPath() / Py_GetProgramName() PyConfig_Get("executable"). Valide o caminho retornado no executável incorporador e no interpretador padrão.
Py_GetPythonHome() PyConfig_Get("home") ou a variável PYTHONHOME. Teste com e sem PYTHONHOME e confirme o valor após a inicialização.

PyConfig_Get() é uma API de configuração em runtime: a documentação exige um thread state anexado e informa que ela não pode ser chamada antes da inicialização nem depois da finalização. Se o seu embedder consultava os antigos Py_Get* antes de inicializar o Python, a migração precisa rever a fase de configuração usando as APIs modernas de inicialização, e não apenas trocar o nome da função.

Duas mudanças de C API que também merecem busca estática

  • Se um tipo define Py_TPFLAGS_MANAGED_DICT ou Py_TPFLAGS_MANAGED_WEAKREF, também precisa definir Py_TPFLAGS_HAVE_GC. Faça um teste que cria, referencia, coleta e destrói instâncias do tipo.
  • PyDateTime_IMPORT agora é thread-safe. Código que verificava PyDateTimeAPI diretamente contra NULL deve chamar PyDateTime_IMPORT. Exercite import e uso da DateTime C API no caminho real da extensão.

Mudanças de comportamento que podem quebrar testes

Área Mudança Como testar
sqlite3 Em sqlite3.connect(), todos os parâmetros exceto database são keyword-only; em create_function() e create_aggregate(), os três primeiros são positional-only; set_authorizer(), set_progress_handler() e set_trace_callback() também endureceram a posição do primeiro argumento. Rode testes que constroem conexões e registram callbacks usando exatamente as assinaturas públicas do projeto.
resource resource.RLIM_INFINITY agora é sempre positivo; valores negativos equivalentes ao valor antigo entram em descontinuação. Compare limites obtidos e definidos na plataforma suportada e pare de gravar -1/-3 como sentinelas portáveis.
mmap mmap.mmap.resize() não existe mais em plataformas sem suporte à chamada de sistema subjacente, em vez de existir e falhar com SystemError. Use hasattr() na plataforma alvo e teste o fallback da aplicação quando resize não estiver disponível.
ElementTree.iterparse() Um iterador que abriu arquivo e não foi fechado pode emitir ResourceWarning. Execute testes com warnings tratados como erro e feche explicitamente o iterador com close() ou contextlib.closing().
argparse Com opção curta e opção longa de um hífen, como -f e -foo, dest passa a ser inferido de -foo. Asserte o Namespace final; se precisar do comportamento antigo, forneça dest explicitamente.
base64 urlsafe_b64decode() não exige mais padding de entrada. Teste entradas com e sem padding; se o produto exige padding, use padded=True ou b64decode(..., altchars=b'-_').
unittest assertWarns() e assertWarnsRegex() não descartam mais avisos não correspondentes, então avisos antes mascarados podem escapar do bloco. Rode a suíte com filtros de warnings mais estritos e trate cada aviso esperado explicitamente.
Extensões nativas e frame pointers O CPython passa a ser compilado com frame pointers habilitados por padrão. Bibliotecas nativas com build customizado devem manter a cadeia de unwinding intacta. Em builds próprios, use flags equivalentes às documentadas pelo CPython e valide backtraces/crash handlers em uma build 3.15.

Checklist de portabilidade antes de 1º de outubro

  1. Faça busca estática pelos nomes removidos. Inclua sre_, load_module, co_lnotab, package= em importlib.resources.files, Py_Get*, PyWeakref_GetObject e as funções PyUnicode removidas.
  2. Rode a suíte no Python 3.15 RC2. Ative também DeprecationWarning no CI para capturar o que ainda não quebra no 3.15, mas já anuncia trabalho para 3.16–3.20.
  3. Recompile extensões C/C++ a partir de uma árvore limpa. Não reutilize objetos compilados com headers antigos; o objetivo é fazer o compilador revelar referências removidas.
  4. Tenha um smoke test de importação. Importe todos os módulos públicos e os módulos opcionais que carregam bibliotecas nativas, loaders personalizados, ctypes ou recursos de pacote.
  5. Teste contratos, não só exceções. Confirme tipos retornados por codecs, ownership de referências C, valores de argparse.Namespace, callbacks sqlite3 e comportamento de warnings.
  6. Teste venv e embedding separadamente quando usar PyConfig. base_prefix/prefix e base_exec_prefix/exec_prefix não são equivalentes quando um ambiente virtual está ativo.
  7. Registre o baseline do RC2. Como a ABI não deve mudar entre RC2 e 3.15 final, uma suíte verde e uma compilação limpa agora reduzem bastante o risco da virada de 1º de outubro, embora correções de bugs ainda possam ocorrer.

Como separar quebra atual de aviso futuro

Uma remoção efetiva deve ser corrigida para o projeto funcionar no 3.15. Uma descontinuação nova, por outro lado, pode não quebrar hoje, mas vale entrar no backlog com a versão prevista de remoção. Essa separação evita duas falhas comuns: tratar todo warning como emergência ou, no extremo oposto, ignorar avisos até a API desaparecer.

Para bibliotecas com extensão nativa, mantenha duas verificações independentes: uma de compilação contra o 3.15 e outra funcional em runtime. Compilar prova que os símbolos e assinaturas usados ainda existem; os testes funcionais são o que revelam diferenças de referência, inicialização, callbacks e comportamento da biblioteca padrão.

Fontes oficiais

Tópicos deste artigoC APIcompatibilidade Pythonextensões Cportabilidade PythonPython 3.15Python 3.15 portabilidadeAPIs removidas Python 3.15C API Python 3.15extensão C PythonPython 3.15 RC2checklist de compatibilidade