Especificação de pontos de entrada

Pontos de entrada são um mecanismo para uma distribuição instalada anunciar componentes que ela fornece para serem descobertos e usados por outro código. Por exemplo:

  • As distribuições podem especificar pontos de entrada console_scripts, cada um referindo-se a uma função. Quando pip (ou outro instalador compatível com console_scripts) instala a distribuição, ele cria um wrapper de linha de comando para cada ponto de entrada.

  • As aplicações podem usar pontos de entrada para carregar plug-ins; por exemplo, Pygments (uma ferramenta de realce de sintaxe) pode usar lexers e estilos adicionais de pacotes instalados separadamente. Para mais informações, consulte Criando e descobrindo plug-ins.

O formato de arquivo de ponto de entrada foi originalmente desenvolvido para permitir que pacotes construídos com setuptools forneçam metadados de ponto de integração que seriam lidos em tempo de execução com importlib.metadata. Ele agora é definido como uma especificação de interoperabilidade PyPA a fim de permitir que outras ferramentas de construção além do setuptools publiquem metadados de ponto de entrada compatíveis com importlib.metadata e bibliotecas de tempo de execução diferentes de importlib.metadata para ler portavelmente publicado metadados de ponto de entrada (potencialmente com diferentes estratégias de cache e resolução de conflitos).

Modelo de dados

Conceitualmente, um ponto de entrada é definido por três propriedades necessárias:

  • O grupo ao qual um ponto de entrada pertence indica que tipo de objeto ele fornece. Por exemplo, o grupo console_scripts é para pontos de entrada referentes a funções que podem ser usadas como um comando, enquanto pygments.styles é o grupo para classes que definem estilos de pigmentos. O consumidor normalmente define a interface esperada. Para evitar conflitos, os consumidores que definem um novo grupo devem usar nomes começando com um nome PyPI pertencente ao projeto do consumidor, seguido por .. Os nomes dos grupos devem ser um ou mais grupos de letras, números e sublinhados, separados por pontos (regex ^\w+(\.\w+)*$).

  • O nome identifica este ponto de entrada em seu grupo. O significado preciso disso depende do cliente. Para scripts de console, o nome do ponto de entrada é o comando que será usado para iniciá-lo. Em uma distribuição, os nomes dos pontos de entrada devem ser exclusivos. Se distribuições diferentes fornecerem o mesmo nome, o consumidor decide como lidar com tais conflitos. O nome pode conter quaisquer caracteres, exceto =, mas não pode começar ou terminar com nenhum caractere de espaço em branco, ou começar com [. Para novos pontos de entrada, é recomendado usar apenas letras, números, sublinhados, pontos e travessões (regex [\w.-]+).

  • A referência de objeto aponta para um objeto Python. Ele está no formato importable.module ou importable.module:object.attr. Cada uma das partes delimitadas por pontos e dois pontos é um identificador válido Python. Destina-se a ser consultado assim:

    import importlib
    modname, qualname_separator, qualname = object_ref.partition(':')
    obj = importlib.import_module(modname)
    if qualname_separator:
        for attr in qualname.split('.'):
            obj = getattr(obj, attr)
    

Nota

Algumas ferramentas chamam esse tipo de referência de objeto por si só de “ponto de entrada”, por falta de um termo melhor, especialmente quando aponta para uma função para iniciar um programa.

Há também uma propriedade opcional: os extras são um conjunto de strings que identifica recursos opcionais da distribuição que fornece o ponto de entrada. Se forem especificados, o ponto de entrada requer as dependências desses ‘extras’. Veja o campo de metadados Provides-Extra (vários usos).

Usar extras para um ponto de entrada não é mais recomendado. Os consumidores devem oferecer suporte para analisá-los em distribuições existentes, mas podem então ignorá-los. Novas ferramentas de publicação não precisam suportar especificações extras. A funcionalidade de manipulação de extras estava ligada ao modelo do setuptools de gerenciamento de pacotes “egg”, mas as ferramentas mais recentes, como pip e virtualenv, usam um modelo diferente.

Formato de arquivo

Os pontos de entrada são definidos em um arquivo chamado entry_points.txt no diretório *.dist-info da distribuição. Este é o diretório descrito em PEP 376 para distribuições instaladas e em PEP 427 para wheels. O arquivo usa a codificação de caracteres UTF-8.

O conteúdo do arquivo está no formato INI, conforme lido pelo módulo configparser do Python. No entanto, o configparser trata os nomes como não diferenciando maiúsculas de minúsculas por padrão, enquanto os nomes de pontos de entrada diferenciam maiúsculas de minúsculas. Um analisador de configuração com distinção entre maiúsculas e minúsculas pode ser feito assim:

import configparser

class CaseSensitiveConfigParser(configparser.ConfigParser):
    optionxform = staticmethod(str)

O arquivo de pontos de entrada deve sempre usar = para delimitar nomes de valores (enquanto o configparser também permite o uso de :).

As seções do arquivo de configuração representam grupos de pontos de entrada, os nomes são nomes e os valores codificam a referência do objeto e os extras opcionais. Se extras forem usados, eles serão uma lista separada por vírgulas entre colchetes.

Dentro de um valor, os leitores devem aceitar e ignorar os espaços (incluindo vários espaços consecutivos) antes ou depois dos dois pontos, entre a referência do objeto e o colchete esquerdo, entre os nomes extras e os colchetes e dois pontos que os delimitam, e depois do quadrado direito suporte. A sintaxe para extras é formalmente especificada como parte da PEP 508 (como extras) e restrições em valores especificados na PEP 685. Para ferramentas de gravação de arquivo, é recomendável inserir apenas um espaço entre a referência do objeto e o colchete esquerdo.

Por exemplo:

[console_scripts]
foo = foomod:main
# One which depends on extras:
foobar = foomod:main_bar [bar,baz]

# pytest plugins refer to a module, so there is no ':obj'
[pytest11]
nbval = nbval.plugin

Uso para scripts

Dois grupos de pontos de entrada têm um significado especial no empacotamento: console_scripts e gui_scripts. Em ambos os grupos, o nome do ponto de entrada deve ser usado como um comando em um shell do sistema após a instalação do pacote. A referência do objeto aponta para uma função que será chamada sem argumentos quando este comando for executado. A função pode retornar um inteiro para ser usado como um código de saída do processo, e retornar None é equivalente a retornar 0.

Por exemplo, o ponto de entrada mycmd = mymod:main criaria um comando mycmd lançando um script como este:

import sys
from mymod import main
sys.exit(main())

A diferença entre console_scripts e gui_scripts afeta apenas os sistemas Windows. console_scripts são empacotados em um executável de console, então eles são anexados a um console e podem usar sys.stdin, sys.stdout e sys.stderr para entrada e saída. gui_scripts são empacotados em um executável GUI, então eles podem ser iniciados sem um console, mas não podem usar streams padrão a menos que o código da aplicação os redirecione. Outras plataformas não têm a mesma distinção.

Espera-se que as ferramentas de instalação configurem wrappers para console_scripts e gui_scripts no diretório de scripts do esquema de instalação. Eles não são responsáveis por colocar este diretório na variável de ambiente PATH que define onde as ferramentas de linha de comando são encontradas.

Como os arquivos são criados a partir dos nomes e alguns sistemas de arquivos não fazem distinção entre maiúsculas e minúsculas, os pacotes devem evitar o uso de nomes nesses grupos que diferem apenas em maiúsculas e minúsculas. O comportamento das ferramentas de instalação quando os nomes diferem apenas no caso de ser indefinido.