O que há de novo no Python 3.12

Editor:

Adam Turner

Este artigo explica os novos recursos no Python 3.12, em comparação com 3.11. Python 3.12 foi lançado em 2 de outubro de 2023. Veja changelog para uma lista completa de mudanças.

Ver também

PEP 693 – Agendamento de lançamento do Python 3.12

Resumo – Destaques da versão

Python 3.12 é a versão estável mais recente da linguagem de programação Python, com uma combinação de alterações na linguagem e na biblioteca padrão. As alterações da biblioteca se concentram na limpeza de APIs descontinuadas, usabilidade e correção. É importante notar que o pacote distutils foi removido da biblioteca padrão. O suporte ao sistema de arquivos em os e pathlib teve uma série de melhorias e vários módulos têm melhor desempenho.

As mudanças de linguagem se concentram na usabilidade, já que f-strings tiveram muitas limitações removidas e as sugestões ‘Did you mean …’ continuam a melhorar. A nova sintaxe de parâmetro type e a instrução type melhoram a ergonomia para usar tipos genéricos e apelidos de tipos com verificadores de tipo estáticos.

Este artigo não tenta fornecer uma especificação completa de todos os novos recursos, mas fornece uma visão geral conveniente. Para detalhes completos, você deve consultar a documentação, como Referência da Biblioteca e Referência da Linguagem. Se você quiser entender a implementação completa e a justificativa do design para uma mudança, consulte a PEP para um novo recurso específico; mas observe que as PEPs geralmente não são mantidas atualizadas depois que um recurso é totalmente implementado.


Novos recursos de sintaxe:

  • PEP 695, sintaxe de parâmetro de tipo e a instrução type

Novos recursos de gramática:

Melhorias no interpretador:

Melhorias no modelo de dados Python:

Melhorias significativas na biblioteca padrão:

Melhorias de segurança:

  • Substitui as implementações embutidas do hashlib de SHA1, SHA3, SHA2-384, SHA2-512 e MD5 pelo código formalmente verificado do projeto HACL*. Essas implementações embutidas permanecem como fallbacks que são usados somente quando o OpenSSL não as fornece.

Melhorias na API C:

Melhorias na implementação do CPython:

  • PEP 709, inlining de compreensão

  • Suporte do CPython para o perfilador Linux perf

  • Implementa proteção contra estouro de pilha em plataformas suportadas

New typing features:

Descontinuações, remoções ou restrições importantes:

  • PEP 623: Remove wstr os objetos Unicode na API C do Python, reduzindo o tamanho de cada objeto str em pelo menos 8 bytes.

  • PEP 632: Remove o pacote distutils. Consulte o guia de migração para obter conselhos sobre a substituição das APIs fornecidas por ele. O pacote de terceiros Setuptools continua fornecendo distutils, se você ainda precisar dele no Python 3.12 e posterior.

  • gh-95299: Não pré-instala setuptools em ambientes virtuais criados com venv. Isso significa que distutils, setuptools, pkg_resources e easy_install não estarão mais disponíveis por padrão; para acessá-los, execute pip install setuptools no ambiente virtual ativado.

  • Os módulos asynchat, asyncore e imp foram removidos, juntamente com vários apelidos de métodos de unittest.TestCase.

Novas funcionalidades

PEP 695: Sintaxe do parâmetro de tipo

As classes e funções genéricas sob a PEP 484 foram declaradas usando uma sintaxe detalhada que deixou o escopo dos parâmetros de tipo pouco claro e exigiu declarações explícitas de variação.

PEP 695 apresenta uma maneira nova, mais compacta e explícita de criar classes genéricas e funções:

def max[T](args: Iterable[T]) -> T:
    ...

class list[T]:
    def __getitem__(self, index: int, /) -> T:
        ...

    def append(self, element: T) -> None:
        ...

Além disso, a PEP introduz uma nova maneira de declarar apelidos de tipos usando a instrução type, que cria uma instância de TypeAliasType:

type Point = tuple[float, float]

Os apelidos de tipo também podem ser genéricos:

type Point[T] = tuple[T, T]

A nova sintaxe permite declarar os parâmetros TypeVarTuple e ParamSpec, bem como os parâmetros TypeVar com limites ou restrições:

type IntFunc[**P] = Callable[P, int]  # ParamSpec
type LabeledTuple[*Ts] = tuple[str, *Ts]  # TypeVarTuple
type HashableSequence[T: Hashable] = Sequence[T]  # TypeVar with bound
type IntOrStrSequence[T: (int, str)] = Sequence[T]  # TypeVar with constraints

O valor dos apelidos de tipo e os limites e restrições das variáveis de tipo criadas por meio dessa sintaxe são avaliados somente sob demanda (consulte avaliação preguiçosa). Isso significa que os apelidos de tipo podem se referir a outros tipos definidos posteriormente no arquivo.

Os parâmetros de tipo declarados por meio de uma lista de parâmetros de tipo são visíveis no escopo da declaração e em quaisquer escopos aninhados, mas não no escopo externo. Por exemplo, eles podem ser usados nas anotações de tipo para os métodos de uma classe genérica ou no corpo da classe. Entretanto, não podem ser usadas no escopo do módulo depois que a classe é definida. Consulte Type parameter lists para obter uma descrição detalhada da semântica de tempo de execução dos parâmetros de tipo.

Para dar suporte a essa semântica de escopo, um novo tipo de escopo é introduzido, o escopo de anotação. Os escopos de anotação se comportam, em sua maior parte, como escopos de função, mas interagem de forma diferente com os escopos de classe. No Python 3.13, anotações também serão avaliadas em escopos de anotação.

Consulte PEP 695 para obter mais detalhes.

(PEP escrita por Eric Traut. Implementação por Jelle Zijlstra, Eric Traut e outros em gh-103764).

PEP 701: Formalização sintática de f-strings

PEP 701 resolve algumas restrições no uso de f-strings. Componentes de expressão dentro de f-strings agora podem ser qualquer expressão válida do Python, incluindo strings reutilizando a mesma aspa que a f-string contida, expressões multi-linhas, comentários, barras invertidas e sequências de escape unicode. Vamos cobri-los em detalhes:

  • Reuso de aspas: no Python 3.11, reusar as mesmas aspas que a f-string que contém levanta um SyntaxError, forçando o usuário a usar outras aspas disponíveis (como usar aspas duplas ou triplas se a f-string usa aspas simples). No Python 3.12, agora você pode fazer coisas como esta:

    >>> songs = ['Take me back to Eden', 'Alkaline', 'Ascensionism']
    >>> f"This is the playlist: {", ".join(songs)}"
    'This is the playlist: Take me back to Eden, Alkaline, Ascensionism'
    

    Observe que, antes dessa alteração, não havia limite explícito de como f-strings podem ser aninhadas, mas o fato de as aspas de string não poderem ser reusadas dentro do componente de expressão de f-strings tornava impossível aninhar f-strings arbitrariamente. Na verdade, esta é a f-string mais aninhada que poderia ser escrita:

    >>> f"""{f'''{f'{f"{1+1}"}'}'''}"""
    '2'
    

    Como agora f-strings podem conter qualquer expressão Python válida dentro de componentes de expressão, agora é possível aninhar f-strings arbitrariamente:

    >>> f"{f"{f"{f"{f"{f"{1+1}"}"}"}"}"}"
    '2'
    
  • Expressões e comentários multilinhas: no Python 3.11, as expressões f-string devem ser definidas em uma única linha, ainda que a expressão dentro de f-string externas possa normalmente abranger várias linhas (como listas literais sendo definidas em várias linhas), tornando-as mais difíceis de ler. No Python 3.12, agora você pode definir f-strings abrangendo várias linhas e adicionar comentários inline:

    >>> f"This is the playlist: {", ".join([
    ...     'Take me back to Eden',  # My, my, those eyes like fire
    ...     'Alkaline',              # Not acid nor alkaline
    ...     'Ascensionism'           # Take to the broken skies at last
    ... ])}"
    'This is the playlist: Take me back to Eden, Alkaline, Ascensionism'
    
  • Contrabarra e caracteres unicode: antes do Python 3.12, as expressões f-string não podiam conter nenhum caractere \. Isso também afetou as sequências de escape unicode (como \N{snowman}), pois elas contêm a parte \N que anteriormente não podia fazer parte dos componentes de expressão de f-strings. Agora, você pode definir expressões como esta:

    >>> print(f"This is the playlist: {"\n".join(songs)}")
    This is the playlist: Take me back to Eden
    Alkaline
    Ascensionism
    >>> print(f"This is the playlist: {"\N{BLACK HEART SUIT}".join(songs)}")
    This is the playlist: Take me back to Eden♥Alkaline♥Ascensionism
    

Veja PEP 701 para mais detalhes.

Como um efeito colateral positivo de como esse recurso foi implementado (analisando f-strings com o analisador GASE ou PEG), agora as mensagens de erro para f-strings são mais precisas e incluem o local exato do erro. Por exemplo, no Python 3.11, a seguinte f-string levanta um SyntaxError:

>>> my_string = f"{x z y}" + f"{1 + 1}"
  File "<stdin>", line 1
    (x z y)
     ^^^
SyntaxError: f-string: invalid syntax. Perhaps you forgot a comma?

mas a mensagem de erro não inclui o local exato do erro dentro da linha e também tem a expressão artificialmente cercada por parênteses. No Python 3.12, como as f-strings são analisadas com o analisador GASE, as mensagens de erro podem ser mais precisas e mostrar a linha inteira:

>>> my_string = f"{x z y}" + f"{1 + 1}"
  File "<stdin>", line 1
    my_string = f"{x z y}" + f"{1 + 1}"
                   ^^^
SyntaxError: invalid syntax. Perhaps you forgot a comma?

(Contribuição de Pablo Galindo, Batuhan Taskaya, Lysandros Nikolaou, Cristián Maureira-Fredes e Marta Gómez em gh-102856. PEP escrito por Pablo Galindo, Batuhan Taskaya, Lysandros Nikolaou e Marta Gómez).

PEP 684: Um GIL por interpretador

A PEP 684 introduz um GIL por interpretador, para que subinterpretadores possam agora ser criados com um GIL único por interpretador. Isso permite que programas Python aproveitem ao máximo vários núcleos de CPU. Isso está atualmente disponível apenas por meio da API C, embora uma API Python seja esperada para 3.13.

Use a nova função Py_NewInterpreterFromConfig() para criar um interpretador com seu próprio GIL:

PyInterpreterConfig config = {
    .check_multi_interp_extensions = 1,
    .gil = PyInterpreterConfig_OWN_GIL,
};
PyThreadState *tstate = NULL;
PyStatus status = Py_NewInterpreterFromConfig(&tstate, &config);
if (PyStatus_Exception(status)) {
    return -1;
}
/* The new interpreter is now active in the current thread. */

Para obter mais exemplos de como usar a API C para subinterpretadores com um GIL por interpretador, consulte Modules/_xxsubinterpretersmodule.c.

(Contribuição de Eric Snow em gh-104210, etc.)

PEP 669: Monitoramento de baixo impacto para CPython

A PEP 669 define uma nova API para perfis, depuradores e outras ferramentas monitorarem eventos no CPython. Ela abrange uma ampla gama de eventos, incluindo chamadas, retornos, linhas, exceções, saltos e mais. Isso significa que você só paga pelo que usa, fornecendo suporte para depuradores e ferramentas de cobertura com sobrecarga quase zero. Veja sys.monitoring para mais detalhes.

(Contribuição de Mark Shannon em gh-103082.)

PEP 688: Tornando o protocolo de buffer acessível no Python

A PEP 688 apresenta uma maneira de usar o protocolo de buffer do código Python. As classes que implementam o método __buffer__() agora podem ser usadas como tipos de buffer.

O novo collections.abc.Buffer ABC fornece uma maneira padrão de representar objetos de buffer, por exemplo, em anotações de tipo. A nova enumeração inspect.BufferFlags representa os sinalizadores que podem ser usados para personalizar a criação do buffer. (Contribuição de Jelle Zijlstra em gh-102500.)

PEP 709: Fazendo inline de compreensão

As compreensões de dicionário, lista e conjunto agora estão embutidas, em vez de criar um novo objeto função de uso único para cada execução da compreensão. Isso acelera a execução de uma compreensão em até duas vezes. Veja PEP 709 para mais detalhes.

As variáveis de iteração de compreensão permanecem isoladas e não sobrescrevem uma variável de mesmo nome no escopo externo, nem são visíveis após a compreensão. O uso de inlining resulta em algumas mudanças visíveis de comportamento:

  • Não há mais um quadro separado para a compreensão em tracebacks (situação da pilha de execução), e o rastreamento/criação de perfil não mostra mais a compreensão como uma chamada de função.

  • O módulo symtable não produzirá mais tabelas de símbolos filhos para cada compreensão; em vez disso, os locais da compreensão serão incluídos na tabela de símbolos da função pai.

  • Chamar locals() dentro de uma compreensão agora inclui variáveis de fora da compreensão e não inclui mais a variável sintética .0 para o “argumento” de compreensão.

  • Uma compreensão que itera diretamente sobre locals() (por exemplo, [k for k in locals()]) pode ver “RuntimeError: dictionary changed size during iteration” quando executada sob rastreamento (por exemplo, medição de cobertura de código). Esse é o mesmo comportamento já observado, por exemplo, em for k in locals():. Para evitar o erro, primeiro crie uma lista de chaves para iterar: keys = list(locals()); [k for k in keys].

(Contribuição de Carl Meyer and Vladimir Matveev em PEP 709.)

Mensagens de erro melhoradas

  • Os módulos da biblioteca padrão agora são potencialmente sugeridos como parte das mensagens de erro exibidas pelo interpretador quando uma exceção NameError é levantada ao nível superior. (Contribuição de Pablo Galindo em gh-98254.)

    >>> sys.version_info
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'sys' is not defined. Did you forget to import 'sys'?
    
  • Melhora a sugestão de erro para exceções NameError para instâncias. Agora, se uma exceção NameError for levantada em um método e a instância tiver um atributo que é exatamente igual ao nome na exceção, a sugestão incluirá self.<NOME> em vez da correspondência mais próxima no escopo do método. (Contribuição de Pablo Galindo em gh-99139.)

    >>> class A:
    ...    def __init__(self):
    ...        self.blech = 1
    ...
    ...    def foo(self):
    ...        somethin = blech
    ...
    >>> A().foo()
    Traceback (most recent call last):
      File "<stdin>", line 1
        somethin = blech
                   ^^^^^
    NameError: name 'blech' is not defined. Did you mean: 'self.blech'?
    
  • Melhora a mensagem de erro de SyntaxError quando o usuário digita import x from y ao invés de from y import x. (Contribuição de Pablo Galindo em gh-98931.)

    >>> import a.y.z from b.y.z
    Traceback (most recent call last):
      File "<stdin>", line 1
        import a.y.z from b.y.z
        ^^^^^^^^^^^^^^^^^^^^^^^
    SyntaxError: Did you mean to use 'from ... import ...' instead?
    
  • Exceções ImportError levantadas a partir de instruções from <módulo> import <nome> com falha agora incluem sugestões para o valor de <nome> com base nos nomes disponíveis em <módulo>. (Contribuição de Pablo Galindo em gh-91058.)

    >>> from collections import chainmap
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ImportError: cannot import name 'chainmap' from 'collections'. Did you mean: 'ChainMap'?
    

Outras mudanças na linguagem

  • O analisador sintático agora exibe SyntaxError ao analisar o código-fonte que contém bytes nulos. (Contribuição de Pablo Galindo em gh-96670.)

  • Um par de caracteres de barra invertida que não seja uma sequência de escape válida agora levanta uma exceção SyntaxWarning, em vez de DeprecationWarning. Por exemplo, re.compile("\d+\.\d+") agora emite um SyntaxWarning ("\d" é uma sequência de escape inválida, use strings brutas para expressão regular: re.compile(r"\d+\.\d+")). Em uma versão futura do Python, SyntaxError acabará sendo levantada, em vez de SyntaxWarning. (Contribuição de Victor Stinner em gh-98401.)

  • Escapes octais com valor maior do que 0o377 (ex: "\477"), descontinuados no Python 3.11, agora produzem um SyntaxWarning, em vez de DeprecationWarning. Em uma versão futura do Python, eles serão eventualmente um SyntaxError. (Contribuição de Victor Stinner em gh-98401.)

  • As variáveis usadas na parte de destino das compreensões que não são armazenadas agora podem ser usadas em expressões de atribuição (:=). Por exemplo, em [(b := 1) for a, b.prop in some_iter], a atribuição a b agora é permitida. Observe que a atribuição a variáveis armazenadas em na parte de destino das compreensões (como a) ainda não é permitida, conforme PEP 572. (Contribuição de Nikita Sobolev em gh-100581.)

  • As exceções levantadas em um método __set_name__ de uma classe ou um tipo não são mais envolvidas por um RuntimeError. As informações de contexto são adicionadas à exceção como uma nota PEP 678. (Contribuição de Irit Katriel em gh-77757.)

  • Quando uma construção try-except* lida com toda a ExceptionGroup e levanta uma outra exceção, essa exceção não é mais envolvida em uma ExceptionGroup. Também alterada na versão 3.11.4. (Contribuição de Irit Katriel em gh-103590.)

  • O coletor de lixo agora é executado somente no mecanismo de quebra de avaliação do laço de avaliação de bytecode do Python em vez de alocações de objetos. O coletor de lixo também pode ser executado quando PyErr_CheckSignals() é chamado, de modo que as extensões C que precisam ser executadas por um longo período sem executar nenhum código Python também têm a chance de executar o coletor de lixo periodicamente. (Contribuição de Pablo Galindo em gh-97922.)

  • Todos os chamáveis internos e de extensão que esperam parâmetros booleanos agora aceitam argumentos de qualquer tipo, em vez de apenas bool e int. (Contribuição de Serhiy Storchaka em gh-60203.)

  • memoryview agora oferece suporte ao tipo meio ponto flutuante (o código de formato “e”). (Contribuição de Donghee Na e Antoine Pitrou em gh-90751.)

  • Objetos slice agora são hasheáveis, permitindo que sejam usados como chaves de dicionário e itens de conjunto. (Contribuição de Will Bradshaw, Furkan Onder e Raymond Hettinger em gh-101264.)

  • sum() agora usa a soma de Neumaier para melhorar a precisão e comutatividade ao somar valores flutuantes ou misturas de ints e floats. (Contribuição de Raymond Hettinger em gh-100425.)

  • ast.parse() agora exibe SyntaxError em vez de ValueError ao analisar o código-fonte que contém bytes nulos. (Contribuição de Pablo Galindo em gh-96670.)

  • Os métodos de extração em tarfile e shutil.unpack_archive() têm um novo argumento filter que permite limitar os recursos do tar que podem ser surpreendentes ou perigosos, como a criação de arquivos fora do diretório de destino. Consulte arquivos de extração de de arquivos tar para obter detalhes. No Python 3.14, o padrão mudará para 'data'. (Contribuição de Petr Viktorin em PEP 706.)

  • Instâncias de types.MappingProxyType agora são hasheáveis se o mapeamento subjacente for hasheável (Contribuição de Serhiy Storchaka em gh-87995.)

  • Adiciona suporte ao perfilador perf por meio da nova variável de ambiente PYTHONPERFSUPPORT e da opção de linha de comando -X perf, bem como das novas funções sys.activate_stack_trampoline(), sys.deactivate_stack_trampoline() e sys.is_stack_trampoline_active(). (Design de Pablo Galindo. Contribuição de Pablo Galindo e Christian Heimes com contribuições de Gregory P. Smith [Google] e Mark Shannon em gh-96123).

Novos módulos

  • Nenhum.

Módulos melhorados

array

asyncio

calendar

csv

dis

  • Opcodes de pseudo-instruções (que são usados pelo compilador, mas não aparecem no bytecode executável) agora são expostos no módulo dis. HAVE_ARGUMENT ainda é relevante para opcodes reais, mas não é útil para pseudo-instruções. Use a nova coleção dis.hasarg. (Contribuição de Irit Katriel em gh-94216.)

  • Adiciona a coleção dis.hasexc para indicar instruções que definem um manipulador de exceções. (Contribuição de Irit Katriel em gh-94216.)

fractions

importlib.resources

inspect

itertools

  • Adiciona itertools.batched() para coletar tuplas de tamanhos iguais, onde o último lote pode ser menor que o resto. (Contribuição de Raymond Hettinger em gh-98363.)

math

  • Adiciona math.sumprod() para calcular uma soma de produtos. (Contribuição de Raymond Hettinger em gh-100485.)

  • Estende math.nextafter() para incluir um argumento steps para subir ou descer várias etapas ao mesmo tempo. (Contribuição de Matthias Goergens, Mark Dickinson e Raymond Hettinger em gh-94906.)

os

  • Adiciona os.PIDFD_NONBLOCK para abrir um descritor de arquivo para um processo com os.pidfd_open() em modo sem bloqueio. (Contribuição de Kumar Aditya em gh-93312.)

  • os.DirEntry agora inclui um método os.DirEntry.is_junction() para verificar se a entrada é uma junção. (Contribuição de Charles Machalow em gh-99547.)

  • Adiciona funções os.listdrives(), os.listvolumes() e os.listmounts() no Windows para enumerar unidades, volumes e pontos de montagem. (Contribuição de Steve Dower em gh-102519.)

  • os.stat() e os.lstat() agora são mais precisos no Windows. O campo st_birthtime agora será preenchido com a hora de criação do arquivo, e st_ctime foi descontinuado, mas ainda contém a hora de criação (mas no futuro vai retornar a última alteração de metadados, para consistência com outras plataformas ). st_dev pode ter até 64 bits e st_ino até 128 bits dependendo do seu sistema de arquivos, e st_rdev é sempre definido como zero em vez de valores incorretos. Ambas as funções podem ser significativamente mais rápidas nas lançamentos mais recentes do Windows. (Contribuição de Steve Dower em gh-99726.)

os.path

pathlib

pdb

  • Adiciona variáveis de conveniência para armazenar valores temporariamente para a sessão de depuração e fornece acesso rápido a valores como o quadro atual ou o valor de retorno. (Contribuição de Tian Gao em gh-103693.)

random

shutil

  • shutil.make_archive() agora passa o argumento root_dir para arquivadores personalizados que o suportam. Neste caso, ele não altera mais temporariamente o diretório de trabalho atual do processo para root_dir para realizar o arquivamento. (Contribuição de Serhiy Storchaka em gh-74696.)

  • shutil.rmtree() agora aceita um novo argumento onexc que é um tratador de erros como onerror mas que espera uma instância de exceção em vez de um trio (typ, val, tb). onerror foi descontinuado. (Contribuição de Irit Katriel em gh-102828.)

  • shutil. which() agora consulta a variável de ambiente PATHEXT para encontrar correspondências dentro de PATH no Windows mesmo quando o cmd fornecido inclui um componente de diretório. (Contribuição de Charles Machalow em gh-103179.)

    shutil. which() chamará NeedCurrentDirectoryForExePathW ao consultar executáveis no Windows para determinar se o diretório de trabalho atual deve ser anexado ao caminho de pesquisa. (Contribuição de Charles Machalow em gh-103179.)

    shutil.which() vai retornar um caminho que corresponde ao cmd com um componente de PATHEXT antes de uma correspondência direta em outro lugar no caminho de pesquisa no Windows. (Contribuição de Charles Machalow em gh-103179.)

sqlite3

statistics

  • Estende statistics.correlation() para incluir como um método ranked para calcular a correlação de Spearman de dados classificados. (Contribuição de Raymond Hettinger em gh-95861.)

sys

tempfile

  • A função tempfile.NamedTemporaryFile tem um novo parâmetro opcional delete_on_close (Contribuição de Evgeny Zorin em gh-58451.)

  • tempfile.mkdtemp() agora sempre retorna um caminho absoluto, mesmo se o argumento fornecido para o parâmetro dir for um caminho relativo.

threading

tkinter

  • tkinter.Canvas.coords() agora nivela seus argumentos. Agora ele aceita não apenas coordenadas como argumentos separados (x1, y1, x2, y2, ...) e uma sequência de coordenadas ([x1, y1, x2, y2, ...]) , mas também coordenadas agrupadas em pares ((x1, y1), (x2, y2), ... e [(x1, y1), (x2, y2), ...]) , como métodos create_*(). (Contribuição de Serhiy Storchaka em gh-94473.)

tokenize

types

typing

  • As verificações de isinstance() com protocolos verificáveis em tempo de execução agora use inspect.getattr_static() em vez de hasattr() para verificar se existem atributos. Isso significa que descritores e métodos __getattr__() não são mais avaliados inesperadamente durante verificações isinstance() em protocolos verificáveis em tempo de execução. No entanto, também pode significar que alguns objetos que costumavam ser considerados instâncias de um protocolo verificável em tempo de execução podem não ser mais considerados instâncias desse protocolo no Python 3.12+ e vice-versa. É improvável que a maioria dos usuários seja afetada por esta mudança. (Contribuição de Alex Waygood em gh-102433.)

  • Os membros de um protocolo verificável em tempo de execução agora são considerados “congelados” em tempo de execução assim que a classe é criada. Fazer alterações em atributos em tempo de execução em um protocolo verificável em tempo de execução ainda vai funcioanr, mas não terá impacto nas verificações de isinstance() comparando objetos com o protocolo. Por exemplo:

    >>> from typing import Protocol, runtime_checkable
    >>> @runtime_checkable
    ... class HasX(Protocol):
    ...     x = 1
    ...
    >>> class Foo: ...
    ...
    >>> f = Foo()
    >>> isinstance(f, HasX)
    False
    >>> f.x = 1
    >>> isinstance(f, HasX)
    True
    >>> HasX.y = 2
    >>> isinstance(f, HasX)  # unchanged, even though HasX now also has a "y" attribute
    True
    

    Esta mudança foi feita para acelerar as verificações de isinstance() em protocolos verificáveis em tempo de execução.

  • O perfil de desempenho de verificações de isinstance() com protocolos verificáveis em tempo de execução mudou significativamente. A maioria das verificações isinstance() a esses protocolos com apenas alguns membros devem ser pelo menos 2x mais rápidas que na versão 3.11, e algumas podem ser 20x mais rápidas ou mais. No entanto, as verificações de isinstance() em protocolos com muito mais membros podem ser mais lentas do que no Python 3.11. (Contribuição de Alex Waygood em gh-74690 e gh-103193.)

  • Todas as classes typing.TypedDict e typing.NamedTuple agora possuem o atributo __orig_bases__. (Contribuição de Adrian Garcia Badaracco em gh-103699.)

  • Adiciona o parâmetro frozen_default a typing.dataclass_transform(). (Contribuição de Erik De Bonte em gh-99957.)

unicodedata

  • O banco de dados Unicode foi atualizado para a versão 15.0.0. (Contribuição de Benjamin Peterson em gh-96734).

unittest

Adiciona uma opção de linha de comando --durations, mostrando os N casos de teste mais lentos:

python3 -m unittest --durations=3 lib.tests.test_threading
.....
Slowest test durations
----------------------------------------------------------------------
1.210s     test_timeout (Lib.test.test_threading.BarrierTests)
1.003s     test_default_timeout (Lib.test.test_threading.BarrierTests)
0.518s     test_timeout (Lib.test.test_threading.EventTests)

(0.000 durations hidden.  Use -v to show these durations.)
----------------------------------------------------------------------
Ran 158 tests in 9.869s

OK (skipped=3)

(Contribuição de Giampaolo Rodola em gh-48330)

uuid

Otimizações

  • Remove os membros wstr e wstr_length dos objetos Unicode. Reduz o tamanho do objeto em 8 ou 16 bytes na plataforma de 64 bits. (PEP 623) (Contribuição de Inada Naoki em gh-92536.)

  • Adiciona suporte experimental para usar o otimizador binário BOLT no processo de construção, o que melhora o desempenho de 1 a 5%. (Contribuição de Kevin Modzelewski em gh-90536 e ajuste de Donghee Na em gh-101525)

  • Acelera a substituição de expressões regulares (funções re.sub() e re.subn() e métodos re.Pattern correspondentes) para strings de substituição contendo referências de grupo em 2 ou 3 vezes . (Contribuição de Serhiy Storchaka em gh-91524.)

  • Acelera a criação de asyncio.Task adiando a dispendiosa formatação de strings. (Contribuição de Itamar Oren em gh-103793.)

  • As funções tokenize.tokenize() e tokenize.generate_tokens() são até 64% mais rápidas como efeito colateral das mudanças necessárias para cobrir PEP 701 no módulo tokenize . (Contribuição de Marta Gómez Macías e Pablo Galindo em gh-102856.)

  • Acelera chamadas de métodos super() e carregamentos de atributos através da nova instrução LOAD_SUPER_ATTR. (Contribuição de Carl Meyer e Vladimir Matveev em gh-103497.)

Alterações de bytecode do CPython

Ferramentas e daemons

  • Remove o diretório Tools/demo/ que continha scripts antigos de demonstração. Uma cópia pode ser encontrada no projeto old-demos. (Contribuição de Victor Stinner em gh-97681.)

  • Remove scripts de exemplo desatualizados do diretório Tools/scripts/. Uma cópia pode ser encontrada no projeto old-demos. (Contribuição de Victor Stinner em gh-97669.)

Descontinuados

Remoção pendente no Python 3.13

Os módulos e APIs a seguir foram descontinuados em lançamentos anteriores do Python e serão removidos no Python 3.13.

Módulos (veja PEP 594):

  • aifc

  • audioop

  • cgi

  • cgitb

  • chunk

  • crypt

  • imghdr

  • mailcap

  • msilib

  • nis

  • nntplib

  • ossaudiodev

  • pipes

  • sndhdr

  • spwd

  • sunau

  • telnetlib

  • uu

  • xdrlib

Outros módulos:

APIs:

Remoção pendente em Python 3.14

As APIs a seguir foram descontinuadas e serão removidas no Python 3.14.

  • argparse: Os parâmetros type, choices e metavar de argparse.BooleanOptionalAction

  • ast:

    • ast.Num

    • ast.Str

    • ast.Bytes

    • ast.NameConstant

    • ast.Ellipsis

  • asyncio:

    • asyncio.MultiLoopChildWatcher

    • asyncio.FastChildWatcher

    • asyncio.AbstractChildWatcher

    • asyncio.SafeChildWatcher

    • asyncio.set_child_watcher()

    • asyncio.get_child_watcher(),

    • asyncio.AbstractEventLoopPolicy.set_child_watcher()

    • asyncio.AbstractEventLoopPolicy.get_child_watcher()

  • collections.abc: collections.abc.ByteString.

  • email: o parâmetro isdst em email.utils.localtime().

  • importlib.abc:

    • importlib.abc.ResourceReader

    • importlib.abc.Traversable

    • importlib.abc.TraversableResources

  • itertools: Suporte para operações de cópia, cópia profunda (deepcopy) e pickle.

  • pkgutil:

    • pkgutil.find_loader()

    • pkgutil.get_loader().

  • pty:

    • pty.master_open()

    • pty.slave_open()

  • shutil: O argumento onerror de shutil.rmtree()

  • typing: typing.ByteString

  • xml.etree.ElementTree: Teste do valor verdadeiro de uma xml.etree.ElementTree.Element.

  • Os atributos __package__ e __cached__ em objetos de módulo.

  • O atributo co_lnotab de objetos código.

Remoção pendente em Python 3.15

As APIs a seguir foram descontinuadas e serão removidas no Python 3.15.

APIs:

Remoção pendente em versões futuras

As APIs a seguir foram descontinuadas em versões anteriores do Python e serão removidas, embora atualmente não haja uma data agendada para sua remoção.

  • código de formatação 'u' do array (gh-57281)

  • typing.Text (gh-92332)

  • Atualmente Python aceita literais numéricos imediatamente seguidos por palavras-chave, por exemplo 0in x, 1or x, 0if 1else 2. Permite expressões confusas e ambíguas como [0x1for x in y] (que pode ser interpretada como [0x1 for x in y] ou [0x1f or x in y]). Um aviso de sintaxe é levantado se o literal numérico for seguido imediatamente por uma das palavras-chave and, else, for, if, in, is e or. Em um lançamento futuro, será alterado para um erro de sintaxe. (gh-87999)

Removidos

asynchat e asyncore

  • Esses dois módulos foram removidos de acordo com o cronograma em PEP 594, tendo sido descontinuados no Python 3.6. Use asyncio em vez disso. (Contribuição de Nikita Sobolev em gh-96580.)

configparser

distutils

  • Remove o pacote distutils. Foi descontinuado no Python 3.10 por PEP 632 “Descontinuar o módulo distutils”. Para projetos que ainda usam distutils e não podem ser atualizados para outra coisa, o projeto setuptools pode ser instalado: ele ainda fornece distutils. (Contribuição de Victor Stinner em gh-92584.)

ensurepip

  • Remove o wheel de setuptools incluído em ensurepip e para de instalar setuptools em ambientes criados por venv.

    pip (>= 22.1) não requer que setuptools sejam instalados no ambiente. Pacotes baseados em setuptools (e baseados em distutils) ainda podem ser usados com pip install, já que o pip fornecerá setuptools no ambiente de construção que ele usa para construir um pacote.

    easy_install, pkg_resources, setuptools e distutils não são mais fornecidos por padrão em ambientes criados com venv ou inicializados com ensurepip, já que eles são parte do pacote setuptools. Para projetos que dependem destes em tempo de execução, o projeto setuptools deve ser declarado como uma dependência e instalado separadamente (normalmente, usando pip).

    (Contribuição de Pradyun Gedam em gh-95299.)

enum

  • Remove EnumMeta.__getattr__ de enum, que não é mais necessário para acesso ao atributos do enum. (Contribuição de Ethan Furman em gh-95083.)

ftplib

  • Remove o atributo de classe FTP_TLS.ssl_version do ftplib: use o parâmetro context em seu lugar. (Contribuição de Victor Stinner em gh-94172.)

gzip

  • Remove o atributo filename do gzip.GzipFile de gzip, descontinuado desde Python 2.6, use o atributo name em seu lugar. No modo de gravação, o atributo filename adicionou a extensão de arquivo '.gz' se ela não estivesse presente. (Contribuição de Victor Stinner em gh-94196.)

hashlib

  • Remove a implementação Python pura de hashlib.pbkdf2_hmac() de hashlib, descontinuado em Python 3.10. Python 3.10 e mais recente requer OpenSSL 1.1.1 (PEP 644): esta versão do OpenSSL fornece uma implementação C de pbkdf2_hmac() que é mais rápida. (Contribuição de Victor Stinner em gh-94199.)

importlib

  • Foi concluída a remoção de muitos alvos de importlib que haviam sido descontinuados anteriormente:

    • Referências e suporte a module_repr() foram removidos. (Contribuição de Barry Warsaw em gh-97850.)

    • importlib.util.set_package, importlib.util.set_loader e importlib.util.module_for_loader foram todos removidos. (Contribuição de Brett Cannon e Nikita Sobolev em gh-65961 e gh-97850.)

    • O suporte para APIs find_loader() e find_module() foi removido. (Contribuição de Barry Warsaw em gh-98040.)

    • importlib.abc.Finder, pkgutil.ImpImporter e pkgutil.ImpLoader foram removidos. (Contribuição de Barry Warsaw em gh-98040.)

imp

  • O módulo imp foi removido. (Contribuição de Barry Warsaw em gh-98040.)

    Para migrar consulte a seguinte tabela de correspondência:

    imp

    importlib

    imp.NullImporter

    Insere None em sys.path_importer_cache

    imp.cache_from_source()

    importlib.util.cache_from_source()

    imp.find_module()

    importlib.util.find_spec()

    imp.get_magic()

    importlib.util.MAGIC_NUMBER

    imp.get_suffixes()

    importlib.machinery.SOURCE_SUFFIXES, importlib.machinery.EXTENSION_SUFFIXES e importlib.machinery.BYTECODE_SUFFIXES

    imp.get_tag()

    sys.implementation.cache_tag

    imp.load_module()

    importlib.import_module()

    imp.new_module(name)

    types.ModuleType(name)

    imp.reload()

    importlib.reload()

    imp.source_from_cache()

    importlib.util.source_from_cache()

    imp.load_source()

    Veja abaixo

    Substitua imp.load_source() com:

    import importlib.util
    import importlib.machinery
    
    def load_source(modname, filename):
        loader = importlib.machinery.SourceFileLoader(modname, filename)
        spec = importlib.util.spec_from_file_location(modname, filename, loader=loader)
        module = importlib.util.module_from_spec(spec)
        # The module is always executed and not cached in sys.modules.
        # Uncomment the following line to cache the module.
        # sys.modules[module.__name__] = module
        loader.exec_module(module)
        return module
    
  • Remove funções e atributos do imp sem substituições:

    • Funções não documentadas:

      • imp.init_builtin()

      • imp.load_compiled()

      • imp.load_dynamic()

      • imp.load_package()

    • imp.lock_held(), imp.acquire_lock(), imp.release_lock(): o esquema de bloqueio foi alterado no Python 3.3 para bloqueios por módulo.

    • Constantes de imp.find_module(): SEARCH_ERROR, PY_SOURCE, PY_COMPILED, C_EXTENSION, PY_RESOURCE, PKG_DIRECTORY, C_BUILTIN, PY_FROZEN, PY_CODERESOURCE, IMP_HOOK.

io

  • Remove io.OpenWrapper e _pyio.OpenWrapper de io, descontinuados em Python 3.10: basta usar open() em seu lugar. A função open() (io.open()) é uma função embutida. Desde o Python 3.10, _pyio.open() também é um método estático. (Contribuição de Victor Stinner em gh-94169.)

locale

smtpd

  • O módulo smtpd foi removido de acordo com o cronograma em PEP 594, tendo sido descontinuado em Python 3.4.7 e 3.5.4. Use o módulo PyPI aiosmtpd ou qualquer outro servidor baseado em asyncio. (Contribuição de Oleg Iarygin em gh-93243.)

sqlite3

  • Os seguintes recursos não documentados do sqlite3, descontinuados no Python 3.10, foram agora removidos:

    • sqlite3.enable_shared_cache()

    • sqlite3.OptimizedUnicode

    Se um cache compartilhado deve ser usado, abra o banco de dados no modo URI usando o parâmetro de consulta cache=shared.

    A fábrica de texto sqlite3.OptimizedUnicode tem sido um apelido para str desde Python 3.3. O código que anteriormente definiu a fábrica de texto como OptimizedUnicode pode usar str explicitamente ou confiar no valor padrão que também é str.

    (Contribuição de Erlend E. Aasland em gh-92548.)

ssl

  • Remove a função ssl.RAND_pseudo_bytes() do ssl, descontinuada no Python 3.6: use os.urandom() ou ssl.RAND_bytes() em seu lugar. (Contribuição de Victor Stinner em gh-94199.)

  • Remove a função ssl.match_hostname(). Foi descontinuada no Python 3.7. OpenSSL realiza correspondência de nome de host desde Python 3.7, Python não usa mais a função ssl.match_hostname(). (Contribuição de Victor Stinner em gh-94199.)

  • Remove a função ssl.wrap_socket(), descontinuada no Python 3.7: em vez desta, crie um objeto ssl.SSLContext e chame seu método ssl.SSLContext.wrap_socket. Qualquer pacote que ainda use ssl.wrap_socket() está quebrado e é inseguro. A função não envia uma extensão SNI TLS nem valida o nome do host do servidor. O código está sujeito a CWE-295 (validação inadequada de certificado). (Contribuição de Victor Stinner em gh-94199.)

unittest

webbrowser

  • Remove o suporte para navegadores descontinuados de webbrowser. Os navegadores removidos incluem: Grail, Mosaic, Netscape, Galeon, Skipstone, Iceape, Firebird e Firefox versões 35 e inferiores (gh-102871).

xml.etree.ElementTree

  • Remove o método ElementTree.Element.copy() da implementação Python pura, descontinuado no Python 3.10; use a função copy.copy() em seu lugar. A implementação C de xml.etree.ElementTree não possui nenhum método copy(), apenas um método __copy__(). (Contribuição de Victor Stinner em gh-94383.)

zipimport

  • Remove os métodos find_loader() e find_module() do zipimport, descontinuados no Python 3.10: use o método find_spec() em seu lugar. Veja PEP 451 para o raciocínio. (Contribuição de Victor Stinner em gh-94379.)

Outros

  • Remove a regra suspicious do Makefile da documentação e do Doc/tools/rstlint.py, ambas em favor do sphinx-lint. (Contribuição de Julien Palard em gh-98179.)

  • Remove os parâmetros keyfile e certfile dos módulos ftplib, imaplib, poplib e smtplib, e dos módulos key_file, cert_file e check_hostname do módulo http.client, todos descontinuados desde Python 3.6. Use o parâmetro context (ssl_context em imaplib). (Contribuição de Victor Stinner em gh-94172.)

  • Remove hacks de compatibilidade Jython de vários módulos e testes da stdlib. (Contribuição de Nikita Sobolev em gh-99482.)

  • Remove o sinalizador _use_broken_old_ctypes_structure_semantics_ do módulo ctypes. (Contribuição de Nikita Sobolev em gh-99285.)

Portando para Python 3.12

Esta seção lista as alterações descritas anteriormente e outras correções que podem exigir alterações no seu código.

Alterações na API Python

  • Regras mais rigorosas agora são aplicadas para referências numéricas de grupos e nomes de grupos em expressões regulares. Apenas a sequência de dígitos ASCII agora é aceita como referência numérica. O nome do grupo em padrões de bytes e strings de substituição agora pode conter apenas letras e dígitos ASCII e sublinhado. (Contribuição de Serhiy Storchaka em gh-91760.)

  • Remove a funcionalidade randrange() descontinuada desde o Python 3.10. Anteriormente, randrange(10.0) era convertido sem perdas para randrange(10). Agora, ele levanta um TypeError. Além disso, a exceção levantada para valores não inteiros como randrange(10.5) ou randrange('10') foi alterada de ValueError para TypeError. Isso também evita bugs onde randrange(1e25) selecionaria silenciosamente um intervalo maior que randrange(10**25). (Originalmente sugerido por Serhiy Storchaka gh-86388.)

  • argparse.ArgumentParser alterou a codificação e o tratador de erros para ler argumentos do arquivo (por exemplo, opção fromfile_prefix_chars) da codificação de texto padrão (por exemplo, locale.getpreferredencoding(False)) para tratador de erros e codificação do sistema de arquivos. Os arquivos de argumento devem ser codificados em UTF-8 em vez de ANSI Codepage no Windows.

  • Remove o módulo smtpd baseado em asyncore descontinuado no Python 3.4.7 e 3.5.4. Um substituto recomendado é o módulo PyPI baseado em asyncio aiosmtpd.

  • shlex.split(): Passar None para o argumento s agora levanta uma exceção, ao invés de ler sys.stdin. O recurso foi descontinuado no Python 3.9. (Contribuição de Victor Stinner em gh-94352.)

  • O módulo os não aceita mais caminhos bytes ou similar, como os tipos bytearray e memoryview: apenas o tipo exato bytes é aceito para strings de bytes. (Contribuição de Victor Stinner em gh-98393.)

  • syslog.openlog() e syslog.closelog() agora falham se usadas ​​em subinterpretadores. syslog.syslog() ainda pode ser usada em subinterpretadores, mas agora somente se syslog.openlog() já tiver sido chamada no interpretador principal. Estas novas restrições não se aplicam ao interpretador principal, então apenas um pequeno grupo de usuários poderá ser afetado. Essa mudança ajuda no isolamento do interpretador. Além disso, syslog é um wrapper em torno de recursos globais de processo, que são melhor gerenciados a partir do interpretador principal. (Contribuição de Donghee Na em gh-99127.)

  • O comportamento não documentado de bloqueio de cached_property() foi removido, porque bloqueava todas as instâncias da classe, levando a uma alta contenção de bloqueio. Isso significa que uma função getter de propriedade em cache agora pode ser executada mais de uma vez para uma única instância, se duas threads competirem. Para a maioria das propriedades simples em cache (por exemplo, aquelas que são idempotentes e simplesmente calculam um valor com base em outros atributos da instância), isso será suficiente. Se a sincronização for necessária, implemente o bloqueio na função getter de propriedade em cache ou em torno de pontos de acesso multithread.

  • sys._current_exceptions() agora retorna um mapeamento de thread-id para uma instância de exceção, ao invés de uma tupla (typ, exc, tb). (Contribuição de Irit Katriel em gh-103176.)

  • Ao extrair arquivos tar usando tarfile ou shutil.unpack_archive(), passe o argumento filter para limitar recursos que podem surpreender ou ser perigosos. Veja Extraction filters para detalhes.

  • A saída das funções tokenize.tokenize() e tokenize.generate_tokens() agora foi alterada devido às mudanças introduzidas na PEP 701. Isso significa que os tokens STRING não são mais emitidos para f-strings e os tokens descritos em PEP 701 agora são produzidos: FSTRING_START, FSTRING_MIDDLE e FSTRING_END agora são emitidos para partes “string” de f-strings, além dos tokens apropriados para a tokenização nos componentes da expressão. Por exemplo, para a f-string f"start {1+1} end" a versão antiga do tokenizer emitida:

    1,0-1,18:           STRING         'f"start {1+1} end"'
    

    enquanto a nova versão emite:

    1,0-1,2:            FSTRING_START  'f"'
    1,2-1,8:            FSTRING_MIDDLE 'start '
    1,8-1,9:            OP             '{'
    1,9-1,10:           NUMBER         '1'
    1,10-1,11:          OP             '+'
    1,11-1,12:          NUMBER         '1'
    1,12-1,13:          OP             '}'
    1,13-1,17:          FSTRING_MIDDLE ' end'
    1,17-1,18:          FSTRING_END    '"'
    

    Além disso, pode haver algumas pequenas alterações comportamentais como consequência das alterações necessárias para oferecer suporte à PEP 701. Algumas dessas mudanças incluem:

    • O atributo type dos tokens emitidos ao tokenizar alguns caracteres Python inválidos, como !, mudou de ERRORTOKEN para OP.

    • Strings incompletas de linha única agora também levantam tokenize.TokenError como fazem strings multilinhas incompletas.

    • Algum código Python incompleto ou inválido agora levanta tokenize.TokenError em vez de retornar tokens ERRORTOKEN arbitrários ao tokenizá-lo.

    • Misturar tabulações e espaços como indentação no mesmo arquivo não é mais suportado e vai levantar uma TabError.

  • O módulo threading agora espera que o módulo _thread tenha um atributo _is_main_interpreter. É uma função sem argumentos que retorna True se o interpretador atual for o interpretador principal.

    Qualquer biblioteca ou aplicação que forneça um módulo _thread personalizado deve fornecer _is_main_interpreter(). (Veja gh-112826.)

Alterações de construção

  • Python não usa mais setup.py para construir módulos de extensão C compartilhados. Parâmetros de construção como cabeçalhos e bibliotecas são detectados no script configure. As extensões são construídas por Makefile. A maioria das extensões usa pkg-config e recorre à detecção manual. (Contribuição de Christian Heimes em gh-93939.)

  • va_start() com dois parâmetros, como va_start(args, format), agora é necessário para construir Python. va_start() não é mais chamado com um único parâmetro. (Contribuição de Kumar Aditya em gh-93207.)

  • CPython agora usa a opção ThinLTO como política de otimização de tempo de vincualção padrão se o compilador Clang aceitar o sinalizador. (Contribuição de Donghee Na em gh-89536.)

  • Adiciona a variável COMPILEALL_OPTS em Makefile para substituir as opções compileall (padrão: -j0) em make install. Também fundiu os 3 comandos compileall em um único comando para construir arquivos .pyc para todos os níveis de otimização (0, 1, 2) de uma só vez. (Contribuição de Victor Stinner em gh-99289.)

  • Adiciona trios de plataforma para LoongArch de 64 bits:

    • loongarch64-linux-gnusf

    • loongarch64-linux-gnuf32

    • loongarch64-linux-gnu

    (Contribuição de Zhang Na em gh-90656.)

  • PYTHON_FOR_REGEN agora requer Python 3.10 ou mais novo.

  • Autoconf 2.71 e aclocal 1.16.4 agora são necessários para regerar !configure. (Contribuição de Christian Heimes em gh-89886.)

  • Construções do Windows e instaladores do macOS em python.org agora usam OpenSSL 3.0.

Alterações na API C

Novas funcionalidades

  • PEP 683: Introduz Objetos Imortais, que permite que objetos ignorem contagens de referências e alterações relacionadas à API C:

    • _Py_IMMORTAL_REFCNT: A contagem de referências que define um objeto

      como imortal.

    • _Py_IsImmortal Verifica se um objeto possui a contagem de referências imortal.

    • PyObject_HEAD_INIT Isso agora inicializará a contagem de referências para

      _Py_IMMORTAL_REFCNT quando usado com Py_BUILD_CORE.

    • SSTATE_INTERNED_IMMORTAL Um identificador para objetos unicode internalizados

      que são imortais.

    • SSTATE_INTERNED_IMMORTAL_STATIC Um identificador para unicode internalizado

      objetos que são imortais e estáticos

    • sys.getunicodeinternedsize Isso retorna o número total de unicode

      objetos que foram internalizados. Isso agora é necessário para refleak.py rastrear corretamente contagens de referências e blocos alocados

    (Contribuição de Eddie Elizondo em gh-84436.)

  • PEP 684: Adiciona a nova função Py_NewInterpreterFromConfig() e PyInterpreterConfig, que podem ser usadas para criar sub-interpretadores com seus próprios GILs. (Veja PEP 684: Um GIL por interpretador para mais informações.) (Contribuição de Eric Snow em gh-104110.)

  • Na API C limitada versão 3.12, as funções Py_INCREF() e Py_DECREF() agora são implementadas como chamadas de função opacas para ocultar detalhes de implementação. (Contribuição de Victor Stinner em gh-105387.)

Portando para Python 3.12

  • APIs Unicode legadas baseadas na representação de Py_UNICODE* foram removidas. Migre para APIs baseadas em UTF-8 ou wchar_t*.

  • Funções de análise de argumentos como PyArg_ParseTuple() não mais oferecem suporte a formato baseado em Py_UNICODE* (por exemplo, u, Z). Migre para outros formatos para Unicode como s, z, es e U.

  • tp_weaklist para todos os tipos embutidos estáticos é sempre NULL. Este é um campo somente interno em PyTypeObject, mas estamos apontando a mudança caso alguém acesse o campo diretamente de qualquer maneira. Para evitar quebras, considere usar a API C pública existente ou, se necessário, a macro _PyObject_GET_WEAKREFS_LISTPTR() (somente interna).

  • Este PyTypeObject.tp_subclasses somente interno pode agora não ser um ponteiro de objeto válido. Seu tipo foi alterado para void* para refletir isso. Mencionamos isso caso alguém esteja acessando diretamente o campo somente interno.

    Para obter uma lista de subclasses, chame o método Python __subclasses__() (usando PyObject_CallMethod(), por exemplo).

  • Adicionado suporte para mais opções de formatação (alinhamento à esquerda, octais, hexadecimais maiúsculos, intmax_t, ptrdiff_t, wchar_t strings C, largura variável e precisão) em PyUnicode_FromFormat() e PyUnicode_FromFormatV(). (Contribuição de Serhiy Storchaka em gh-98836.)

  • Um caractere de formato não reconhecido em PyUnicode_FromFormat() e PyUnicode_FromFormatV() agora define um SystemError. Nas versões anteriores, fazia com que todo o restante da string de formato fosse copiado como estava para a string de resultado e quaisquer argumentos extras descartados. (Contribuição de Serhiy Storchaka em gh-95781.)

  • Corrige o posicionamento incorreto do sinal em PyUnicode_FromFormat() e PyUnicode_FromFormatV(). (Contribuição de Philip Georgi em gh-95504.)

  • Extension classes wanting to add a __dict__ or weak reference slot should use Py_TPFLAGS_MANAGED_DICT and Py_TPFLAGS_MANAGED_WEAKREF instead of tp_dictoffset and tp_weaklistoffset, respectively. The use of tp_dictoffset and tp_weaklistoffset is still supported, but does not fully support multiple inheritance (gh-95589), and performance may be worse. Classes declaring Py_TPFLAGS_MANAGED_DICT must call _PyObject_VisitManagedDict() and _PyObject_ClearManagedDict() to traverse and clear their instance’s dictionaries. To clear weakrefs, call PyObject_ClearWeakRefs(), as before.

  • A função PyUnicode_FSDecoder() não aceita mais caminhos bytes ou similar, como os tipos bytearray e memoryview: apenas o tipo exato bytes é aceito para strings de bytes. (Contribuição de Victor Stinner em gh-98393.)

  • As macros Py_CLEAR, Py_SETREF e Py_XSETREF agora avaliam seus argumentos apenas uma vez. Se um argumento tiver efeitos colaterais, esses efeitos colaterais não serão mais duplicados. (Contribuição de Victor Stinner em gh-98724.)

  • O indicador de erro do interpretador agora está sempre normalizado. Isso significa que PyErr_SetObject(), PyErr_SetString() e as outras funções que definem o indicador de erro agora normalizam a exceção antes de armazená-la. (Contribuição de Mark Shannon em gh-101578.)

  • _Py_RefTotal não é mais oficial e é mantido apenas para compatibilidade com ABI. Observe que é um global interno e está disponível apenas em compilações de depuração. Se acontecer de você usá-lo, você precisará começar a usar _Py_GetGlobalRefTotal().

  • As seguintes funções agora selecionam uma metaclasse apropriada para o tipo recém-criado:

    A criação de classes cujas substituições de metaclasse tp_new foi descontinuada e no Python 3.14+ não será permitida. Observe que essas funções ignoram tp_new da metaclasse, possivelmente permitindo uma inicialização incompleta.

    Observe que PyType_FromMetaclass() (adicionada em Python 3.12) já não permite a criação de classes cuja metaclasse substitui tp_new (__new__() em Python).

    Como tp_new substitui quase tudo que as funções PyType_From* fazem, os dois são incompatíveis entre si. O comportamento existente – ignorar a metaclasse em vários passos de criação do tipo – é inseguro em geral, uma vez que as (meta)classes assumem que tp_new foi chamado. Não existe uma solução geral simples. Um dos seguintes pode funcionar para você:

    • Se você controla a metaclasse, evite usar tp_new nela:

      • Se a inicialização puder ser ignorada, isso pode ser feito em tp_init.

      • Se a metaclasse não precisa ser instanciada do Python, defina seu tp_new como NULL usando o sinalizador Py_TPFLAGS_DISALLOW_INSTANTIATION. Isso o torna aceitável para funções PyType_From*.

    • Evite funções PyType_From*: se você não precisa de recursos específicos do C (slots ou configuração do tamanho da instância), crie tipos chamando a metaclasse.

    • Se você sabe que tp_new pode ser ignorado com segurança, filtre o aviso de descontinuação usando warnings.catch_warnings() do Python.

  • PyOS_InputHook e PyOS_ReadlineFunctionPointer não são mais chamados em subinterpretadores. Isso ocorre porque os clientes geralmente dependem do estado global de todo o processo (uma vez que esses retornos de chamada não têm como recuperar o estado do módulo de extensão).

    Isso também evita situações em que as extensões podem ser executadas em um subinterpretador que não oferecem suporte (ou no qual ainda não foram carregadas). Veja gh-104668 para mais informações.

  • PyLongObject teve seus componentes internos alterados para melhor desempenho. Embora os internos de PyLongObject sejam privados, eles são usados por alguns módulos de extensão. Os campos internos não devem mais ser acessados diretamente, em vez disso, as funções da API que começam com PyLong_... devem ser usadas. Duas novas funções de API instáveis são fornecidas para acesso eficiente ao valor de PyLongObjects que cabe em uma única palavra de máquina:

  • Alocadores personalizados, definidos via PyMem_SetAllocator(), agora precisam ser seguros para thread, independentemente do domínio de memória. Os alocadores que não possuem estado próprio, incluindo “ganchos”, não são afetados. Se o seu alocador personalizado ainda não for seguro para thread e você precisar de orientação, crie um novo relatório de problema no GitHub e CC @ericsnowcurrently.

Descontinuados

Remoção pendente em Python 3.14

Remoção pendente em Python 3.15

Remoção pendente em versões futuras

As APIs a seguir foram descontinuado e serão removidas, embora atualmente não haja uma data agendada para sua remoção.

Removidos

  • Remove o arquivo de cabeçalho token.h. Nunca houve nenhuma API C de tokenizador público. O arquivo de cabeçalho token.h foi projetado apenas para ser usado por internos do Python. (Contribuição de Victor Stinner em gh-92651.)

  • As APIs Unicode legadas foram removidas. Veja a PEP 623 para detalhes.

    • PyUnicode_WCHAR_KIND

    • PyUnicode_AS_UNICODE()

    • PyUnicode_AsUnicode()

    • PyUnicode_AsUnicodeAndSize()

    • PyUnicode_AS_DATA()

    • PyUnicode_FromUnicode()

    • PyUnicode_GET_SIZE()

    • PyUnicode_GetSize()

    • PyUnicode_GET_DATA_SIZE()

  • Remove a macro de função PyUnicode_InternImmortal(). (Contribuição de Victor Stinner em gh-85858.)