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.

The entry point file format was originally developed to allow packages built with setuptools to provide integration point metadata that would be read at runtime with importlib.metadata. It is now defined as a PyPA interoperability specification in order to allow build tools other than setuptools to publish importlib.metadata compatible entry point metadata, and runtime libraries other than importlib.metadata to portably read published entry point metadata (potentially with different caching and conflict resolution strategies).

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 Gravando projetos instalados para distribuições instaladas e em Formato de distribuição binária 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())

The difference between console_scripts and gui_scripts only affects Windows systems. console_scripts are wrapped in a console executable, so they are attached to a console and can use sys.stdin, sys.stdout and sys.stderr for input and output. gui_scripts are wrapped in a GUI executable, so they can be started without a console, but cannot use standard streams unless application code redirects them. Other platforms do not have the same distinction.

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.

Histórico#

  • October 2017: This specification was written to formalize the existing entry points feature of setuptools (discussion).