Python 3.13 e 3.14: as Novidades que Você Precisa Conhecer

Cansado de programar?

Conheça a melhor e mais completa formação de Python e Django e sinta-se um programador verdadeiramente competente. Além de Python e Django, você também vai aprender Banco de Dados, SQL, HTML, CSS, Javascript, Bootstrap e muito mais!

Quero aprender Python e Django de Verdade! Quero aprender!
Suporte

Tire suas dúvidas diretamente com o professor

Projetos práticos

Projetos práticos voltados para o mercado de trabalho

Prática profissional

Formação moderna com foco na prática profissional

Resposta rápida

O Python 3.13 (outubro de 2024) trouxe um REPL novo, mensagens de erro melhores, o modo free-threaded (sem GIL) e um JIT, ambos experimentais. O Python 3.14 (outubro de 2025) trouxe template strings (t"..."), anotações adiadas, except A, B: sem parênteses e tornou o free-threading oficialmente suportado.

1
2
3
4
5
# Python 3.14
nome = "Ana"
modelo = t"Olá, {nome}!"
print(type(modelo))  # <class 'string.templatelib.Template'>
print(modelo.values)  # ('Ana',)

Resumo em 30 segundos:

  • 3.13: REPL com edição multilinha, cores e exit sem parênteses.
  • 3.13: build experimental sem GIL (python3.13t) e JIT experimental.
  • 3.14: t-strings devolvem Template, não str.
  • 3.14: anotações não são mais avaliadas na definição (PEP 649).
  • 3.14: free-threading oficialmente suportado, mas ainda opcional.

Salve salve Pythonista!

Todo mês de outubro sai uma versão nova do Python, e cada uma traz um “What’s New” enorme, cheio de detalhes de implementação. Neste post filtramos o que interessa no dia a dia: o que mudou no Python 3.13 e no Python 3.14, com exemplos que você pode rodar.

Uma regra que seguimos aqui: tudo o que está neste post foi conferido nas páginas oficiais What’s New In Python 3.13 e What’s New in Python 3.14. Os exemplos foram executados no Python 3.13.12 e no Python 3.14.3 (e nas variantes free-threaded 3.13t e 3.14t), instalados com o uv. Se você quiser ver de onde viemos, temos também o post sobre as novidades do Python 3.10.

Então… Bora pro post! :rocket:

Vá Direto ao Assunto…

Como testar o Python 3.13 e o 3.14 sem mexer no seu sistema

Você não precisa trocar o Python da sua máquina para acompanhar este post. Com o uv instalado, cada comando baixa a versão pedida (se ainda não existir) e roda o script nela:

1
2
3
uv run --no-project --python 3.13 python script.py
uv run --no-project --python 3.14 python script.py
uv run --no-project --python 3.14t python script.py   # build free-threaded (sem GIL)

Uma mudança de calendário que vale saber: a partir do 3.13, cada versão tem dois anos de suporte completo (correções de bugs), seguidos de três anos só de correções de segurança. Até o 3.12, o suporte completo era de um ano e meio.

Python 3.13: um REPL novo

O que mudou no REPL do Python 3.13? O Python 3.13 trocou o interpretador interativo (o >>>) por um novo, baseado em código do projeto PyPy. Ele tem edição de blocos com várias linhas preservando o histórico, prompts e tracebacks coloridos, e comandos como exit, quit e help funcionando sem parênteses.

Quem já tentou corrigir uma linha no meio de uma função digitada no >>> sabe o sofrimento que era. Segundo o What’s New, o REPL novo suporta:

  • Edição multilinha com histórico: a seta para cima traz o bloco inteiro (a função toda), não linha por linha.
  • exit, quit e help sem parênteses. Antes, digitar exit só mostrava uma mensagem pedindo exit().
  • Cores nos prompts e nos tracebacks, ligadas por padrão.
  • F1 abre a ajuda interativa, F2 navega pelo histórico sem as saídas e os prompts, e F3 ativa o “modo colar”, que facilita colar blocos grandes de código.

No 3.14, o REPL ganhou mais dois presentes: realce de sintaxe enquanto você digita e autocompletar de imports (digite import co e aperte Tab para ver os módulos que começam com co).

Se algum recurso atrapalhar (em terminais antigos, por exemplo), a variável de ambiente PYTHON_BASIC_REPL volta para o REPL antigo, e as cores podem ser desligadas com NO_COLOR ou PYTHON_COLORS.

Mensagens de erro ainda melhores

Desde o 3.10, cada versão melhora as mensagens de erro, e essas duas não foram exceção. Além dos tracebacks coloridos, o 3.13 sugere o nome correto quando você erra um argumento nomeado:

1
"Better error messages!".split(max_split=1)

No Python 3.12, a última linha do traceback é:

1
TypeError: 'max_split' is an invalid keyword argument for split()

No Python 3.13 e no 3.14:

1
TypeError: split() got an unexpected keyword argument 'max_split'. Did you mean 'maxsplit'?

Outra melhoria do 3.13 acaba com um clássico de iniciante: criar um arquivo chamado random.py (ou json.py, math.py…) e depois não conseguir usar o módulo de verdade. Com este random.py:

1
2
import random
print(random.randint(1, 10))

O Python 3.10 dizia só AttributeError: partially initialized module 'random' has no attribute 'randint' (most likely due to a circular import). O 3.13 aponta a causa real (o caminho muda conforme a sua pasta):

1
AttributeError: module 'random' has no attribute 'randint' (consider renaming '/home/voce/projeto/random.py' since it has the same name as the standard library module named 'random' and prevents importing that standard library module)

O 3.14 foi além e passou a sugerir a palavra-chave certa quando você erra a digitação, entre outros casos. Comparando a última linha do erro em cada versão (todas executadas):

Código com erro Python 3.13 Python 3.14
whille True: SyntaxError: invalid syntax SyntaxError: invalid syntax. Did you mean 'while'?
elif depois de else SyntaxError: invalid syntax SyntaxError: 'elif' block follows an 'else' block
x = 1 if True else pass SyntaxError: invalid syntax SyntaxError: expected expression after 'else', but statement is given
alunos.add({"nome": "Ana"}) em um set TypeError: unhashable type: 'dict' TypeError: cannot use 'dict' as a set element (unhashable type: 'dict')
notas[[1, 2]] = 10 em um dict TypeError: unhashable type: 'list' TypeError: cannot use 'list' as a dict key (unhashable type: 'list')

Free-threading: Python sem GIL

O que é o free-threading do Python? É um modo de execução do CPython com o GIL (Global Interpreter Lock) desativado, o que permite que várias threads executem código Python em paralelo, em núcleos diferentes do processador. Ele surgiu como experimental no 3.13 (PEP 703) e virou oficialmente suportado, mas opcional, no 3.14 (PEP 779).

O GIL é uma trava que deixa apenas uma thread executar bytecode Python por vez. Por isso, até aqui, threads em Python ajudavam em tarefas de espera (rede, disco), mas não aceleravam cálculo pesado. Se esse assunto é novo para você, veja antes o nosso post sobre concorrência e paralelismo em Python.

Pontos importantes, direto do What’s New:

  • O modo sem GIL usa outro executável, normalmente chamado python3.13t ou python3.14t. O python3 comum continua com GIL.
  • No 3.13 ele era experimental, com “uma perda substancial de desempenho em código de uma thread só”. No 3.14 a implementação da PEP 703 foi concluída e essa perda caiu para cerca de 5% a 10%, dependendo da plataforma e do compilador.
  • Extensões em C precisam ser compiladas especificamente para esse build. Importar uma extensão que não declara suporte reativa o GIL.

Para saber em qual modo você está, use sys._is_gil_enabled() (novo no 3.13). O próprio python -VV também mostra a diferença:

1
2
Python 3.13.12 experimental free-threading build (main, Mar 20 2026, 00:34:39) [Clang 22.1.1 ]
Python 3.14.3 free-threading build (main, Mar 20 2026, 00:34:34) [Clang 22.1.1 ]

Repare que a palavra “experimental” sumiu no 3.14. Para ver o efeito na prática, rodamos o mesmo cálculo pesado (contar primos) em 4 threads:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import sys
import time
from concurrent.futures import ThreadPoolExecutor

def conta_primos(limite):
    total = 0
    for n in range(2, limite):
        if all(n % d for d in range(2, int(n ** 0.5) + 1)):
            total += 1
    return total

inicio = time.perf_counter()
with ThreadPoolExecutor(max_workers=4) as executor:
    resultados = list(executor.map(conta_primos, [200_000] * 4))
duracao = time.perf_counter() - inicio

print(f"GIL ativo: {sys._is_gil_enabled()}")
print(f"Resultados: {resultados}")
print(f"Tempo: {duracao:.2f} s")

Com uv run --no-project --python 3.14 python threads.py:

1
2
3
GIL ativo: True
Resultados: [17984, 17984, 17984, 17984]
Tempo: 2.03 s

Com uv run --no-project --python 3.14t python threads.py:

1
2
3
GIL ativo: False
Resultados: [17984, 17984, 17984, 17984]
Tempo: 0.56 s

Na nossa máquina (12 núcleos), as 4 threads rodaram de fato em paralelo e o tempo caiu para menos de um terço. Os números variam conforme o hardware, e código de uma thread só não fica mais rápido (fica um pouco mais lento). O ganho aparece em programas pensados para threads e com trabalho de CPU.

JIT experimental

O 3.13 adicionou um compilador JIT (just-in-time, PEP 744) que transforma trechos “quentes” do bytecode em código de máquina. No 3.13, porém, ele só existe se você compilar o CPython com a opção --enable-experimental-jit, e o What’s New descreve os ganhos como modestos.

No 3.14, os instaladores oficiais de Windows e macOS passaram a incluir o JIT, desligado por padrão. Ele é ativado com a variável de ambiente PYTHON_JIT=1, e o módulo sys._jit informa o estado:

1
2
3
import sys

print(sys._jit.is_available(), sys._jit.is_enabled())

No build do Python 3.14.3 que o uv instalou (Linux), a saída foi True False sem a variável e True True com PYTHON_JIT=1. Em um executável sem JIT, is_available() devolve False.

Expectativa realista: segundo o próprio What’s New do 3.14, o impacto vai de 10% mais lento a 20% mais rápido, conforme a carga, e o uso em produção não é recomendado. Os builds free-threaded não suportam o JIT.

Está curtindo esse conteúdo? :thumbsup:

Que tal receber 30 dias de conteúdo direto na sua Caixa de Entrada?

Sua assinatura não pôde ser validada.
Você fez sua assinatura com sucesso.

Assine as PyDicas e receba 30 dias do melhor conteúdo Python na sua Caixa de Entrada: direto e sem enrolação!

Python 3.14: template strings (t-strings)

O que são t-strings? Template strings (PEP 750) usam o prefixo t com a mesma sintaxe das f-strings, mas devolvem um objeto string.templatelib.Template, e não uma str. O objeto guarda separadas as partes fixas do texto e os valores interpolados, para que uma função decida como combiná-los.

Se você já domina as f-strings no Python, a sintaxe é a mesma. A diferença está no resultado:

1
2
3
4
5
6
7
8
9
nome = "Ana"
f = f"Olá, {nome}!"
t = t"Olá, {nome}!"

print(type(f))
print(type(t))
print(t.strings)
print(t.values)
print(list(t))
1
2
3
4
5
<class 'str'>
<class 'string.templatelib.Template'>
('Olá, ', '!')
('Ana',)
['Olá, ', Interpolation('Ana', 'nome', None, ''), '!']

Iterar um Template entrega, em ordem, os pedaços de texto (str) e as interpolações (Interpolation), que carregam o valor, a expressão original, a conversão e o formato.

Para que serve? Para processar os valores antes de montar o texto. O exemplo clássico é escapar HTML e evitar que um comentário malicioso vire código na página:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import html
from string.templatelib import Template, Interpolation

def html_seguro(template: Template) -> str:
    partes = []
    for parte in template:
        if isinstance(parte, Interpolation):
            partes.append(html.escape(str(parte.value)))
        else:
            partes.append(parte)
    return "".join(partes)

comentario = "<script>alert('hackeado')</script>"
print(f"<p>{comentario}</p>")
print(html_seguro(t"<p>{comentario}</p>"))
1
2
<p><script>alert('hackeado')</script></p>
<p>&lt;script&gt;alert(&#x27;hackeado&#x27;)&lt;/script&gt;</p>

Com a f-string, o valor já chega colado no texto e não há como separar o que é seu do que veio do usuário. Com a t-string, a função sabe exatamente o que é interpolação e escapa só isso. O What’s New cita esse mesmo caminho para sanitizar SQL, montar comandos de shell com segurança e melhorar logs.

Dois cuidados: str(t) não monta o texto (devolve a representação Template(strings=..., interpolations=...)), e o prefixo t não existe antes do 3.14: no 3.13, t"Olá, {nome}!" gera SyntaxError: invalid syntax.

Anotações adiadas (PEP 649 e PEP 749)

No 3.14, as anotações de funções, classes e módulos não são mais avaliadas na hora da definição. Elas ficam guardadas e só são calculadas quando alguém pede. Na prática, acabou a necessidade de usar aspas para referenciar uma classe que ainda não terminou de ser definida:

1
2
3
4
5
6
class No:
    def __init__(self, valor: int, proximo: No | None = None):
        self.valor = valor
        self.proximo = proximo

print(No.__init__.__annotations__)

No 3.14:

1
{'valor': <class 'int'>, 'proximo': __main__.No | None}

No 3.13, a mesma classe nem chega a ser criada:

1
NameError: name 'No' is not defined

Para inspecionar anotações, o 3.14 trouxe o módulo annotationlib, com três formatos: VALUE (avalia, como antes), FORWARDREF (troca nomes indefinidos por marcadores) e STRING (devolve o texto):

1
2
3
4
5
6
7
8
9
10
from annotationlib import get_annotations, Format

def func(arg: Indefinido) -> None:
    pass

print(get_annotations(func, format=Format.STRING))
try:
    get_annotations(func, format=Format.VALUE)
except NameError as erro:
    print("NameError:", erro)
1
2
{'arg': 'Indefinido', 'return': 'None'}
NameError: name 'Indefinido' is not defined

Repare que definir func com um nome inexistente na anotação não gerou erro: ele só aparece quando pedimos o formato VALUE. O from __future__ import annotations continua funcionando com o comportamento antigo dele.

except sem parênteses e SyntaxWarning em finally

A PEP 758 permite omitir os parênteses ao capturar várias exceções, desde que não haja as:

1
2
3
4
5
6
7
def converter(texto):
    try:
        return int(texto)
    except ValueError, TypeError:
        return None

print(converter("42"), converter("abc"), converter(None))
1
42 None None

No 3.13, o mesmo código falha com SyntaxError: multiple exception types must be parenthesized. E no 3.14, se você usar as sem parênteses, o erro é SyntaxError: multiple exception types must be parenthesized when using 'as'. Para revisar try/except, veja o nosso guia de tratamento de erros e exceções no Python.

Já a PEP 765 faz o compilador emitir SyntaxWarning quando return, break ou continue saem de um bloco finally, porque isso engole exceções sem avisar:

1
2
3
4
5
6
7
def dividir(a, b):
    try:
        return a / b
    finally:
        return "sempre isto"

print(dividir(10, 0))

Saída no 3.14 (o caminho do arquivo muda conforme a sua pasta):

1
2
3
/home/voce/projeto/fin.py:5: SyntaxWarning: 'return' in a 'finally' block
  return "sempre isto"
sempre isto

O ZeroDivisionError sumiu sem deixar rastro, e agora o Python avisa. No 3.13, o código imprime só sempre isto, em silêncio.

Acompanhar novidades da linguagem é ótimo, mas o que muda o seu dia a dia de verdade é dominar os fundamentos com prática real - é isso que a Jornada Python ensina, do básico ao avançado:

Outras novidades que valem conhecer

No Python 3.13:

  • copy.replace() cria uma cópia de um objeto trocando alguns campos. Funciona com vários tipos embutidos e com dataclasses: copy.replace(Ponto(1, 2), y=10) devolve Ponto(x=1, y=10).
  • 19 módulos antigos (“dead batteries”, PEP 594) foram removidos, entre eles cgi, cgitb, crypt, imghdr, pipes, telnetlib e uu. import cgi agora dá ModuleNotFoundError: No module named 'cgi'.
  • O módulo random ganhou linha de comando: python -m random 6 sorteia um número de 1 a 6.
  • iOS e Android passaram a ser plataformas oficialmente suportadas (tier 3).

No Python 3.14:

  • map() ganhou strict=True, como o zip() ganhou no 3.10: listas de tamanhos diferentes geram ValueError.
  • Novo pacote compression, com o módulo compression.zstd para o formato Zstandard.
  • concurrent.interpreters (PEP 734) expõe múltiplos interpretadores no mesmo processo, com paralelismo real e isolamento.
  • uuid.uuid7() (e também uuid6() e uuid8()) no módulo uuid.
  • python -m json passa a ser o jeito preferido de formatar JSON no terminal, no lugar de python -m json.tool.
  • python -m pdb -p PID conecta o depurador a um processo Python que já está rodando (PEP 768).

Uma nota para quem usa o 3.14 em produção: o coletor de lixo incremental que veio no 3.14.0 foi revertido no 3.14.5 para o coletor geracional do 3.13, por causa de relatos de alto consumo de memória. Mantenha o 3.14 atualizado com a última versão de correção.

Qual versão usar

Situação Recomendação
Projeto novo Python 3.14 (versão estável mais recente)
Projeto em produção no 3.12 ou 3.13 Atualize depois de testar: confira dependências e a seção “Porting” do What’s New
Quer usar t-strings, except A, B: ou anotações sem aspas Python 3.14 (não existem no 3.13)
Cálculo pesado com threads Teste o build 3.14t, se as suas bibliotecas em C já suportarem
Quer testar o JIT 3.14 com PYTHON_JIT=1, só para experimentar
Biblioteca que precisa suportar várias versões Evite sintaxe exclusiva do 3.14 (t-strings, except sem parênteses)

Erros comuns

Estes erros aparecem ao usar recursos novos na versão errada (ou do jeito errado). As mensagens são as reais.

Usar t-string no Python 3.13 ou anterior (SyntaxError)

1
2
nome = "Ana"
t = t"Olá, {nome}!"
1
SyntaxError: invalid syntax

Correção: t-strings exigem Python 3.14. Confira com python --version e, se precisar, rode com uv run --python 3.14.

except sem parênteses com as (SyntaxError)

1
2
3
4
try:
    x = 1
except ValueError, TypeError as erro:
    pass
1
SyntaxError: multiple exception types must be parenthesized when using 'as'

Correção: com as, os parênteses continuam obrigatórios: except (ValueError, TypeError) as erro:.

Importar um módulo removido no 3.13 (ModuleNotFoundError)

1
import cgi
1
ModuleNotFoundError: No module named 'cgi'

Correção: o cgi e outros 18 módulos, marcados como obsoletos desde o 3.11, foram removidos no 3.13. O What’s New indica substitutos para cada um: no caso do cgi.FieldStorage, urllib.parse.parse_qsl() para GET e o módulo email.message ou a biblioteca multipart para POST. Para aplicações web, o caminho natural é um framework como Django ou FastAPI.

Usar annotationlib antes do 3.14 (ModuleNotFoundError)

1
from annotationlib import get_annotations
1
ModuleNotFoundError: No module named 'annotationlib'

Correção: o módulo é novo no 3.14. Em versões anteriores, use inspect.get_annotations().

Esperar que str() monte o texto de uma t-string

1
2
nome = "Ana"
print(str(t"Olá, {nome}!"))
1
Template(strings=('Olá, ', '!'), interpolations=(Interpolation('Ana', 'nome', None, ''),))

Não há exceção, mas o resultado não é o texto. Correção: t-strings existem para serem processadas por uma função sua. Se você só quer o texto pronto, use uma f-string.

Exercícios resolvidos

Rode as soluções com uv run --no-project --python 3.14 python arquivo.py. Todas foram executadas no 3.14.3.

Exercício 1. Crie a t-string t"{produto} custa R$ {preco}" com produto = "Notebook" e preco = 3500. Mostre o nome do tipo, as partes fixas e os valores.

Ver solução
1
2
3
4
5
6
7
produto = "Notebook"
preco = 3500
modelo = t"{produto} custa R$ {preco}"

print(type(modelo).__name__)
print(modelo.strings)
print(modelo.values)

Saída:

1
2
3
Template
('', ' custa R$ ', '')
('Notebook', 3500)

Como o template começa e termina com interpolação, strings tem strings vazias nas pontas: sempre há uma parte fixa a mais que o número de interpolações.

Exercício 2. Escreva destacar(template) que devolva o texto com os valores interpolados em MAIÚSCULAS e as partes fixas intactas. Teste com t"Entrega para {cidade}/{estado} confirmada".

Ver solução
1
2
3
4
5
6
7
8
9
10
11
12
13
14
from string.templatelib import Interpolation

def destacar(template):
    partes = []
    for parte in template:
        if isinstance(parte, Interpolation):
            partes.append(str(parte.value).upper())
        else:
            partes.append(parte)
    return "".join(partes)

cidade = "recife"
estado = "pe"
print(destacar(t"Entrega para {cidade}/{estado} confirmada"))

Saída: Entrega para RECIFE/PE confirmada

O isinstance() separa as interpolações das partes fixas, que é exatamente a informação que uma f-string não preserva.

Exercício 3. Reescreva except (ValueError, TypeError): no estilo do Python 3.14 em uma função para_float(valor) que devolva 0.0 quando a conversão falhar.

Ver solução
1
2
3
4
5
6
7
def para_float(valor):
    try:
        return float(valor)
    except ValueError, TypeError:
        return 0.0

print(para_float("3.5"), para_float("abc"), para_float(None))

Saída: 3.5 0.0 0.0

float("abc") gera ValueError e float(None) gera TypeError. Sem as, os parênteses são opcionais no 3.14.

Exercício 4. Escreva um script que mostre a versão do Python e se o GIL está ativo, funcionando também em versões que não têm sys._is_gil_enabled().

Ver solução
1
2
3
4
5
6
7
8
import sys

versao = f"{sys.version_info.major}.{sys.version_info.minor}"
if hasattr(sys, "_is_gil_enabled"):
    gil = "ativo" if sys._is_gil_enabled() else "desativado"
else:
    gil = "ativo (versão sem free-threading)"
print(f"Python {versao} - GIL {gil}")

Saída em cada versão:

1
2
3
4
Python 3.12 - GIL ativo (versão sem free-threading)
Python 3.13 - GIL ativo
Python 3.13 - GIL desativado
Python 3.14 - GIL desativado

As linhas foram geradas com 3.12, 3.13, 3.13t e 3.14t, nessa ordem. O hasattr() evita AttributeError no 3.12, em que a função não existe.

Exercício 5. Dadas precos = [2.5, 15.0] e quantidades [10, 2, 1], calcule os totais com map() de forma que a diferença de tamanho gere erro, em vez de ser ignorada.

Ver solução
1
2
3
4
5
6
7
precos = [2.5, 15.0]
quantidades = [10, 2, 1]

try:
    totais = list(map(lambda p, q: p * q, precos, quantidades, strict=True))
except ValueError as erro:
    print("Erro:", erro)

Saída: Erro: map() argument 2 is longer than argument 1

Sem strict=True, o map() pararia na lista menor e devolveria [25.0, 30.0] sem avisar que uma quantidade ficou sem preço.

Exercício 6. No Python 3.14, escreva a classe Pedido com o método adicionar(self, item: Item) -> Pedido, em que Item é definida depois de Pedido, sem usar aspas. Mostre as anotações nos formatos STRING e padrão.

Ver solução
1
2
3
4
5
6
7
8
9
10
11
from annotationlib import get_annotations, Format

class Pedido:
    def adicionar(self, item: Item) -> Pedido:
        return self

class Item:
    pass

print(get_annotations(Pedido.adicionar, format=Format.STRING))
print(get_annotations(Pedido.adicionar))

Saída:

1
2
{'item': 'Item', 'return': 'Pedido'}
{'item': <class '__main__.Item'>, 'return': <class '__main__.Pedido'>}

Como as anotações só são avaliadas quando pedidas, Item e Pedido já existem no momento do get_annotations(). No 3.13, a definição da classe falharia com NameError.

Exercício 7 (estilo prova). Considere o código abaixo, executado no Python 3.14. O que ele imprime?

1
2
nome = "Ana"
print(type(t"Olá, {nome}"))

a) <class 'str'>
b) <class 'string.templatelib.Template'>
c) <class 'string.Template'>
d) SyntaxError: invalid syntax

Ver solução

Saída: <class 'string.templatelib.Template'>

Resposta: b. A t-string devolve um Template do módulo novo string.templatelib. A alternativa a seria o resultado de uma f-string, a c é a classe antiga string.Template (que usa $nome e existe há muitos anos) e a d só aconteceria no 3.13 ou anterior.

Exercício 8 (estilo prova). Sobre o free-threading (Python sem GIL), assinale a alternativa correta.

a) O Python 3.13 removeu o GIL de todas as instalações.
b) No Python 3.13 ele é experimental e usa um executável separado (como python3.13t); no 3.14 passou a ser oficialmente suportado, mas continua opcional.
c) No Python 3.14 o GIL foi removido do executável padrão.
d) O free-threading acelera qualquer programa Python, inclusive os de uma thread só.

Ver solução

Resposta: b. É o que dizem o What’s New do 3.13 (build experimental e separado) e a PEP 779, aceita no 3.14 (suportado, mas opcional). A a e a c estão erradas porque o executável padrão continua com GIL, e a d está errada porque código de uma thread só fica, na verdade, um pouco mais lento no build sem GIL (cerca de 5% a 10% no 3.14).

Quer dominar o Python moderno com projetos práticos, do básico ao avançado? Conheça o nosso curso de Python completo.

Conclusão

Neste guia das novidades do Python 3.13 e 3.14, você viu:

✅ REPL novo - edição multilinha, cores, exit sem parênteses e, no 3.14, realce de sintaxe
✅ Mensagens de erro - sugestões de argumento, de palavra-chave e de nome de arquivo
✅ Free-threading - experimental no 3.13, oficialmente suportado (e opcional) no 3.14
✅ JIT - experimental, com PYTHON_JIT=1 nos instaladores do 3.14
✅ t-strings - Template no lugar de str, para processar valores com segurança
✅ Anotações adiadas e except A, B: - menos aspas e menos parênteses

Próximos passos:

Se ficou com alguma dúvida, fique à vontade para deixar um comentário no box aqui embaixo! Será um prazer te responder! :wink:

Perguntas frequentes

Quais são as principais novidades do Python 3.13?

Segundo o What’s New oficial, as maiores mudanças do Python 3.13 (lançado em 7 de outubro de 2024) são um interpretador interativo (REPL) novo, com edição multilinha e cores, suporte experimental ao modo free-threaded sem GIL (PEP 703) e um compilador JIT experimental (PEP 744). Também vieram mensagens de erro melhores, tracebacks coloridos, copy.replace() e a remoção de 19 módulos antigos, como cgi e telnetlib.

Quais são as principais novidades do Python 3.14?

O Python 3.14, lançado em 7 de outubro de 2025, trouxe template strings (t-strings, PEP 750), avaliação adiada de anotações (PEP 649 e PEP 749), múltiplos interpretadores na biblioteca padrão (PEP 734), except sem parênteses (PEP 758), o módulo compression.zstd e realce de sintaxe no REPL. O modo free-threaded deixou de ser experimental e passou a ser oficialmente suportado (PEP 779).

O que são template strings (t-strings) no Python 3.14?

Template strings usam o prefixo t no lugar do f, com a mesma sintaxe de chaves: t'Olá, {nome}'. A diferença é que o resultado não é uma str, e sim um objeto string.templatelib.Template que guarda separadas as partes fixas e os valores interpolados. Isso permite processar os valores antes de montar o texto final, por exemplo escapando HTML ou SQL.

O Python 3.13 removeu o GIL?

Não por padrão. O Python 3.13 oferece um build separado e experimental, geralmente chamado python3.13t, em que o GIL fica desativado. A instalação comum continua com GIL. No Python 3.14, esse build free-threaded passou a ser oficialmente suportado, mas continua opcional: o executável padrão ainda tem GIL. Use sys._is_gil_enabled() para conferir.

Como usar o JIT do Python?

O JIT é experimental nas duas versões. No 3.13 ele só existe se o CPython for compilado com --enable-experimental-jit. No 3.14, os instaladores oficiais de Windows e macOS já incluem o JIT desligado, e ele pode ser ativado com a variável de ambiente PYTHON_JIT=1. O What’s New informa impacto de 10% mais lento a 20% mais rápido, conforme a carga, e não recomenda o uso em produção.

Posso usar except sem parênteses no Python?

Sim, a partir do Python 3.14 (PEP 758), desde que não haja a cláusula as: except ValueError, TypeError: é válido. Com as, os parênteses continuam obrigatórios: except (ValueError, TypeError) as erro:. No Python 3.13 ou anterior, a forma sem parênteses gera SyntaxError: multiple exception types must be parenthesized.

Vale a pena atualizar para o Python 3.14?

Para projetos novos, sim: o 3.14 é a versão estável mais recente com suporte completo. Para projetos existentes, teste antes, porque as anotações passaram a ser avaliadas de forma adiada e há módulos e APIs removidos. Confira se as suas dependências já publicam pacotes para o 3.14 e leia a seção Porting to Python 3.14 do What’s New oficial.

Em uma questão de prova, qual o tipo do resultado de t’Olá, {nome}’ no Python 3.14?

O resultado é um objeto string.templatelib.Template, e não uma str. É essa a diferença entre t-strings e f-strings: a f-string f'Olá, {nome}' já devolve o texto pronto (str), enquanto a t-string devolve uma estrutura com as partes fixas (strings) e as interpolações (interpolations) para serem processadas por uma função.

Começe agora sua Jornada na Programação!

Não deixe para amanhã o sucesso que você pode começar a construir hoje!

#newsletter Olá :wave: Curtiu o artigo? Então faça parte da nossa Newsletter! Privacidade Não se preocupe, respeitamos sua privacidade. Você pode se descadastrar a qualquer momento.