Skip to content

Como atualizar para o Python 3.15: instalar com uv, usar imports preguiçosos (lazy imports) e checar seus pacotes

Atualizado em

Instale o Python 3.15 com um comando do uv e veja se numpy, pandas, PyTorch, DuckDB e Polars instalam nele. Testado no macOS: tabela de compatibilidade de wheels, lazy imports que reduziram a inicialização de um script de 2.7 s para 0.01 s, os três casos em que lazy import dá SyntaxError e o build free-threaded.

Resposta curta: o Python 3.15.0 foi lançado em 9 de outubro de 2026. Se você usa o uv (opens in a new tab), atualize o uv primeiro e depois instale:

uv self update
uv python install 3.15

Em seguida, crie um projeto de teste e experimente suas dependências reais antes de migrar qualquer coisa importante:

uv init --python 3.15 py315-test
cd py315-test
uv add numpy pandas scikit-learn matplotlib

O stack científico principal já instala a partir de wheels prontos. PyTorch e TensorFlow não instalam. O DuckDB compila a partir do código-fonte. Se o seu projeto depende de algum deles, fique no 3.14 por enquanto (uv python pin 3.14).

O recurso que justifica a atualização são os imports preguiçosos (lazy imports). Uma única palavra-chave, lazy import pandas as pd, levou o caminho --help de um script de teste de 2.7 segundos para 0.01 segundo.

O que foi testado: tudo o que aparece como "testado" abaixo foi executado em 11 de outubro de 2026, em um Apple M4 Max (macOS), com uv 0.13.0 e CPython 3.15.0 / 3.15.0t instalados via uv python install. O comportamento no Windows e no Linux, o instalador do python.org, o pyenv e o conda vêm da documentação oficial e não foram testados.

O que muda no 3.15 e você vai notar

O changelog é longo. Se você escreve scripts de dados ou CLIs, estas são as cinco mudanças que vão aparecer no seu dia a dia:

MudançaO que significa para vocêO que fazer
Lazy imports (PEP 810)lazy import x adia o carregamento até o primeiro usoUse em CLIs, scripts e apps que demoram para iniciar
UTF-8 é a codificação padrão (PEP 686)open("file.txt") agora lê e grava em UTF-8 em qualquer sistemaNo Windows, com arquivos cp1252 / cp932 / GBK: passe encoding= explicitamente
uv 0.13 usa o 3.15 por padrãoProjetos novos do uv sem versão fixada recebem o 3.15 automaticamenteFixe o 3.14 onde suas dependências ainda não estão prontas
O build free-threaded ganha ABI estável (PEP 803)python3.15t executa threads em paralelo, mas a maioria dos pacotes ainda não publica wheels com ABI estável para eleEspere builds a partir do código-fonte no 3.15t
Built-ins frozendict e sentinel, pacote profilingNovos tipos nativos e o profiler por amostragem TachyonOpcional; nada quebra se você ignorar

A lista completa está no What's New in Python 3.15 oficial (opens in a new tab). O restante deste guia cobre as tarefas: instalar, checar compatibilidade, usar lazy imports, lidar com a mudança de codificação e decidir sobre o free-threading.

Passo 1: instalar o Python 3.15

Com uv (testado)

Atualize o uv antes de instalar. Pular esta etapa é o erro mais fácil de cometer nesta semana. Um uv antigo só conhece as versões alpha. No uv 0.9.25 que já tínhamos instalado, uv python list 3.15 mostrava apenas cpython-3.15.0a4. Rodar uv python install 3.15 ali instalaria uma alpha, não a versão final.

uv self update          # needs 0.13.0 or newer
uv --version
uv python install 3.15

O uv 0.13.0 instalou o build normal e o free-threaded em 24.8 segundos:

uv python install 3.15 3.15t
Installed 2 versions in 24.83s
 + cpython-3.15.0+freethreaded-macos-aarch64-none (python3.15t)
 + cpython-3.15.0-macos-aarch64-none (python3.15)

Se você instalou o uv com Homebrew, pip ou pipx, uv self update não funciona. Atualize do mesmo jeito que instalou (brew upgrade uv, pipx upgrade uv).

O uv 0.13 também muda o padrão. As notas de versão do uv 0.13.0 (opens in a new tab) dizem que uv python install sem versão agora baixa o 3.15. Um uv venv ou uvx python novo baixa o 3.15 se não houver um Python compatível instalado. Instalações existentes continuam sendo usadas. Para manter um projeto no 3.14, registre isso:

uv python pin 3.14

Esse comando grava o arquivo .python-version, que o uv lê sempre que roda naquela pasta.

Outras formas (da documentação oficial, não testadas aqui)

  • Instalador do python.org (Windows, macOS): baixe o 3.15.0 em python.org/downloads (opens in a new tab). Segundo as notas de versão, o instalador oficial para macOS agora instala o suporte a free-threading por padrão, e os binários de 64 bits para Windows usam o novo interpretador com tail calls.
  • pyenv: pyenv update e depois pyenv install 3.15.0. Espere até que a sua versão do pyenv liste o 3.15.0.
  • conda: crie um ambiente com python=3.15 quando o conda-forge publicar a versão. Confira antes de planejar uma migração em torno dele.

Se você quer a visão geral de como trocar de versão do Python em cada sistema, nosso guia de como atualizar o Python e a comparação de gerenciadores de versão do Python continuam válidos. Esta página cobre o que é específico do 3.15.

Passo 2: checar se seus pacotes instalam

É este passo que decide se você pode atualizar hoje. Criamos um projeto 3.15 limpo, instalamos um stack típico de ciência de dados e consultamos o PyPI para os pacotes mais procurados.

Tabela de compatibilidade (testada em 11 de outubro de 2026)

Pacote (versão)Python 3.15Python 3.15t (free-threaded)Observações
numpy 2.5.4WheelWheel
pandas 3.0.6WheelWheel
scipy 1.18.1WheelWheel
scikit-learn 1.9.1WheelWheel
matplotlib 3.11.2WheelWheel
pyarrow 26.0.0WheelWheel
polars 2.0.0Wheel (abi3)Compila do código-fonteO runtime só publica wheels cp310-abi3, que o Python free-threaded não consegue usar. O build em Rust levou 6 min 51 s
ipykernel 9.17.1 (pyzmq, psutil, debugpy)WheelNão testadoKernels do Jupyter funcionam no 3.15
duckdb 1.5.6Compila do código-fonteNão testadoOs wheels param no cp314. O build em C++ levou cerca de 2.5 min
pygwalker 0.5.0.1FuncionaNão testadoDepende do duckdb, então herda o build a partir do código-fonte
torch 2.14.1Não instalaNão instalaSó há wheels de cp310 a cp314 e cp314t
tensorflow 2.21.0Não instalaNão instalaSó há wheels de cp310 a cp313

Instalar numpy, pandas, scipy, scikit-learn, matplotlib, pyarrow e polars levou 71 segundos no 3.15, com download incluído e sem compilação. O mesmo conjunto no 3.15t levou 6 minutos e 51 segundos, quase todo esse tempo compilando o Polars.

Quando um pacote não tem wheel, o uv diz exatamente o motivo. Veja como fica o PyTorch no 3.15:

hint: You require CPython 3.15 (`cp315`), but we only found wheels for `torch`
(v2.14.1) with the following Python ABI tags: `cp310`, `cp311`, `cp312`, `cp313`, `cp314`, `cp314t`

Cheque seu próprio projeto em um minuto

Você não precisa instalar nada para descobrir. Faça um dry run contra um ambiente 3.15:

uv venv --python 3.15 .venv315
uv pip install --dry-run --python .venv315/bin/python -r requirements.txt

Se resolver, está tudo certo. Se aparecer a dica cp315 acima, esse pacote é o seu bloqueio.

Um build a partir do código-fonte não é uma falha, mas é lento e exige um compilador (Rust para o Polars, C++ para o DuckDB). No CI, isso pode transformar um job de um minuto em um de dez. Fixe o 3.14 no CI até os wheels saírem.

Passo 3: usar lazy imports para scripts iniciarem mais rápido

Na minha opinião, os imports preguiçosos são o melhor motivo para migrar para o 3.15. O problema que eles resolvem é conhecido.

Um script de linha de comando costuma importar tudo no topo. Até my_tool.py --help paga o custo completo de carregar pandas, matplotlib e scikit-learn, mesmo sem usar nenhum deles.

Antes e depois (testado)

A versão com imports imediatos (eager):

import sys
import pandas as pd
import matplotlib.pyplot as plt
import sklearn.linear_model
 
if len(sys.argv) > 1 and sys.argv[1] == "--help":
    print("usage: tool [--help] file.csv")
    sys.exit(0)

A versão preguiçosa só acrescenta a palavra-chave lazy:

import sys
lazy import pandas as pd
lazy import matplotlib.pyplot as plt
lazy from sklearn import linear_model
 
if len(sys.argv) > 1 and sys.argv[1] == "--help":
    print("usage: tool [--help] file.csv")
    sys.exit(0)
 
df = pd.DataFrame({"x": [1, 2, 3], "y": [2, 4, 6]})
model = linear_model.LinearRegression().fit(df[["x"]], df["y"])
print(model.coef_)

Resultados na nossa máquina, cinco execuções de python script.py --help para cada versão:

VersãoTempoLinhas em -X importtime
Imports imediatos2.69 a 2.74 s1,747
lazy import0.01 s27

O caminho completo continua funcionando: a versão preguiçosa ajustou a regressão e imprimiu 2.0. O pandas é carregado na linha que usa pd pela primeira vez.

Seus números absolutos vão ser diferentes. Neste ambiente, só import sklearn.linear_model levou 2.2 s e import pandas levou 0.86 s. O padrão vale para qualquer ramo do programa que não toque em uma biblioteca pesada.

Veja o que os lazy imports estão fazendo

Um nome preguiçoso é um proxy até você usá-lo. Dá para ver isso:

import sys
lazy import json
 
print(type(globals()["json"]))   # <class 'lazy_import'>
print("json" in sys.modules)     # False
json.dumps(1)
print(type(globals()["json"]), "json" in sys.modules)   # <class 'module'> True

Para descobrir quais imports são lentos, rode python -X importtime your_script.py 2> imports.log e ordene pela segunda coluna.

Três lugares em que lazy dá SyntaxError (testado)

lazy só funciona no nível do módulo. Encontramos os três erros abaixo:

OndeMensagem de erro
Dentro de uma funçãoSyntaxError: lazy import not allowed inside functions
Dentro de try / exceptSyntaxError: lazy import not allowed inside try/except blocks
Import com asteriscoSyntaxError: lazy from ... import * is not allowed

A regra do try/except é a que mais pesa. Um código como try: import ujson as json except ImportError: import json não pode virar lazy. Mantenha o fallback imediato ou mova-o para um módulo pequeno que você importa de forma preguiçosa.

A documentação oficial acrescenta que corpos de classe e imports from __future__ também não podem ser lazy.

Os erros passam para o primeiro uso

Um módulo inexistente não falha mais no topo do arquivo:

lazy import not_a_real_module
print("defined ok")          # this prints
not_a_real_module.x          # ModuleNotFoundError is raised here

Isso é prático para dependências opcionais. Mas também significa que um erro de digitação em um import pode ficar escondido até um caminho de código raramente usado rodar. Mantenha pelo menos um teste que exercite cada lazy import.

Deixar tudo lazy sem editar o código

Você pode ativar lazy imports no programa inteiro pela linha de comando:

python -X lazy_imports=all my_tool.py --help
# or
PYTHON_LAZY_IMPORTS=all python my_tool.py --help

Nosso script eager, sem nenhuma alteração, caiu para 0.01 s dessa forma. Cuidado, porém, com módulos que fazem trabalho no momento do import. Criamos um módulo de plugin minúsculo que imprime uma mensagem e se registra ao ser importado. Com lazy_imports=all, o registro nunca aconteceu, porque o programa nunca tocou no nome do módulo:

normal:   plugin registered / main done
all:      main done

Bibliotecas que registram plugins, codecs ou backends do matplotlib no import podem quebrar do mesmo jeito. Use =all para medir o ganho possível e depois adicione lazy à mão nos imports que você sabe que são seguros. Para um controle mais fino, a documentação descreve sys.set_lazy_imports_filter().

Suportar 3.14 e 3.15 no mesmo arquivo

A palavra-chave lazy é erro de sintaxe no 3.14 e anteriores. Se o seu código precisa rodar nos dois, use a lista __lazy_modules__ no nível do módulo. Versões antigas a ignoram, e o 3.15 trata esses imports como lazy:

__lazy_modules__ = ["pandas"]
 
import sys
import pandas as pd          # lazy on 3.15, eager on 3.14
 
print("pandas" in sys.modules)   # False on 3.15 until pd is used

Confirmamos que, com esse padrão, o pandas ficou fora de sys.modules no 3.15.

Passo 4: lidar com o UTF-8 como padrão

No 3.15, open() sem o argumento encoding usa UTF-8 em todas as plataformas. Confirmamos sys.flags.utf8_mode == 1 por padrão e 0 com PYTHONUTF8=0.

No macOS e no Linux isso quase não muda nada. No Windows, muda o comportamento de qualquer código que lê arquivos legados sem informar a codificação: exportações CSV do Excel em cp1252, arquivos japoneses em Shift-JIS (cp932) ou arquivos chineses em GBK. Essas leituras agora podem gerar UnicodeDecodeError ou texto embaralhado.

A solução é ser explícito:

import pandas as pd
 
df = pd.read_csv("export.csv", encoding="cp932")      # Japanese Excel export
with open("legacy.txt", encoding="locale") as f:      # old behavior: system locale
    text = f.read()

Para encontrar o código afetado antes de atualizar, rode seus testes no Python atual com -X warn_default_encoding. Para voltar temporariamente ao comportamento antigo, defina PYTHONUTF8=0.

Passo 5: decidir sobre o build free-threaded (3.15t)

O Python free-threaded remove o GIL, então threads em Python puro podem usar vários núcleos de CPU. Rodamos um loop pesado de CPU quatro vezes, primeiro em sequência e depois em quatro threads:

BuildSequencial4 threadsAceleração
Python 3.150.72 s0.71 s1.0×
Python 3.15t0.65 s0.19 s3.4×

O GIL continuou desligado depois de importar numpy, pandas, scikit-learn, polars, matplotlib e pyarrow (sys._is_gil_enabled() retornou False).

Use o 3.15t se você roda código Python puro pesado de CPU em threads e suas dependências têm wheels cp315t. Deixe de lado se você depende de Polars, DuckDB ou bibliotecas de deep learning. Deixe de lado também se o trabalho pesado já roda dentro do NumPy ou do pandas, que liberam o GIL por conta própria.

Vale atualizar agora?

Sua situaçãoRecomendação
Scripts, CLIs e automação com o stack numpy / pandas / sklearnAtualize. Os lazy imports são um ganho real
Notebooks Jupyter para análiseAtualize em um ambiente novo; mantenha o kernel antigo por algumas semanas
Projetos com PyTorch ou TensorFlowFique no 3.14 (uv python pin 3.14)
DuckDB ou Polars no 3.15t em CIEspere os wheels ou aceite o tempo de compilação e um compilador no CI
Código Windows que lê arquivos com codificação legadaAdicione encoding= explícito primeiro e depois atualize

Usando o 3.15 no Jupyter

O ipykernel instala e funciona no 3.15. Para registrar um kernel 3.15 a partir de um projeto uv:

uv add ipykernel
uv run python -m ipykernel install --user --name py315 --display-name "Python 3.15"

Se você trabalha com notebooks, o RunCell (opens in a new tab) roda como um agente de IA dentro do Jupyter e enxerga o estado do kernel ao vivo. Isso ajuda a testar se um notebook existente ainda roda no kernel novo. O PyGWalker (opens in a new tab) também funciona no 3.15 (testado: pyg.to_html() renderizou um DataFrame), com a compilação do DuckDB mencionada acima.

Solução de problemas

SintomaCausaSolução
uv python install 3.15 instala 3.15.0a4O uv é anterior ao 0.13uv self update, ou atualize pelo Homebrew / pipx
No solution found … no wheels with a matching Python ABI tag (cp315)O pacote ainda não tem wheel para 3.15 (torch, tensorflow)uv python pin 3.14 nesse projeto
A instalação trava por minutos no duckdb ou no polars-runtimeBuild a partir do código-fonte, porque não existe wheel compatívelEspere (exige compilador C++ ou Rust) ou use 3.14 / o 3.15 normal no lugar do 3.15t
SyntaxError: lazy import not allowed …lazy dentro de função, try ou classeMova o import para o nível do módulo ou mantenha-o eager
Um plugin ou backend para de se registrar-X lazy_imports=all pulou um import com efeitos colateraisRemova o =all; use lazy só em imports escolhidos
UnicodeDecodeError no Windows depois de atualizarUTF-8 agora é a codificação padrãoPasse encoding="cp1252" / "cp932" / "gbk" ou encoding="locale"
Projeto uv novo cai no 3.15 sem você esperarO uv 0.13 mudou o padrãouv python pin 3.14
SyntaxWarning: 'return' in a 'finally' block vindo de uma dependênciaA biblioteca tem código antigo sinalizado pelo Python mais novoInofensivo; vem da biblioteca, não do seu código

Perguntas frequentes

Quando o Python 3.15 foi lançado? O Python 3.15.0 foi lançado em 9 de outubro de 2026.

Como instalar o Python 3.15 com uv? Atualize o uv para a versão 0.13.0 ou mais nova e rode uv python install 3.15. Versões antigas do uv só conhecem as builds alpha do 3.15.

O pandas funciona no Python 3.15? Sim. O pandas 3.0.6 publica wheels cp315 e cp315t, assim como numpy, scipy, scikit-learn, matplotlib e pyarrow.

O PyTorch suporta o Python 3.15? Ainda não. Em 11 de outubro de 2026, o torch 2.14.1 só tem wheels até cp314 e cp314t, então não instala no 3.15.

O que são lazy imports no Python 3.15? Escrever lazy import module faz o Python criar um proxy leve e carregar o módulo só quando o nome é usado pela primeira vez. Isso reduz o tempo de inicialização nos caminhos de código que nunca tocam no módulo.

Dá para usar lazy imports e continuar suportando o Python 3.14? Sim. Defina __lazy_modules__ = ["module_name"] no topo do módulo. O Python 3.15 trata esses imports como lazy, e as versões antigas ignoram a lista.

Como manter um projeto no Python 3.14? Rode uv python pin 3.14 na pasta do projeto. O comando grava um arquivo .python-version que o uv respeita.

Guias relacionados