入口点规范

入口点 是已安装分发的一种机制,用于公布它提供给其他代码发现和使用的组件。例如:

  • 分配可以指定 console_scripts 入口点,每个都指向一个函数。什么时候? pip (或另一个控制台脚本感知安装程序)安装分发版,它将为每个入口点创建一个命令行包装器。

  • 应用程序可以使用入口点加载插件;例如,Pygment(语法突出显示工具)可以使用单独安装的包中的其他lexer和样式。有关更多信息,请参阅 创建和发现插件 .

入口点文件格式最初是为允许使用SetupTools构建的包提供集成点元数据而开发的,这些元数据将在运行时使用 pkg_resources . 现在它被定义为一个Pypa互操作性规范,以便允许除SETUPTOOLS之外的构建工具发布 pkg_resources 兼容的入口点元数据和运行库,而不是 pkg_resources 可移植地读取已发布的入口点元数据(可能具有不同的缓存和冲突解决策略)。

数据模型

概念上,入口点由三个必需的属性定义:

  • 这个 入口点所属的属性表示它提供的对象类型。例如,集团 console_scripts 用于引用可用作命令的函数的入口点,而 pygments.styles 定义Pygments样式的类的组。使用者通常定义预期的接口。为了避免冲突,定义新组的消费者应该使用以消费者项目拥有的pypi名称开头的名称,然后使用 . . 组名必须是一组或多组字母、数字和下划线,用点分隔(regex ^\w+(\.\w+)*$

  • 这个 name 标识其组中的此入口点。这一点的确切含义取决于消费者。对于控制台脚本,入口点的名称是用于启动它的命令。在分发中,入口点名称应该是唯一的。如果不同的发行版提供相同的名称,那么使用者将决定如何处理此类冲突。名称可以包含除 = ,但不能以任何空格字符开头或结尾,也不能以 [ . 对于新的入口点,建议仅使用字母、数字、下划线、短划线和点(regex [\w-.]+

  • 这个 对象引用 指向一个python对象。它要么在形式上 importable.moduleimportable.module:object.attr . 由点和冒号分隔的每个部分都是有效的Python标识符。它的目的是要像这样向上看:

    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)
    

注解

有些工具将这种对象引用本身称为“入口点”,因为缺少更好的术语,特别是当它指向一个函数来启动程序时。

还有一个可选属性: 额外的 是一组字符串,用于标识提供入口点的分发的可选功能。如果指定了这些,则入口点需要这些“附加”的依赖项。请参见元数据字段 提供额外的(多用途) .

不再建议对入口点使用附加项。消费者应该支持从现有的发行版解析它们,但随后可能会忽略它们。新的发布工具不需要支持指定附加项。处理额外软件的功能与SETUPTOOLS管理“egg”软件包的模型相关联,但是新的工具(如pip和virtualenv)使用不同的模型。

文件格式

入口点在名为 entry_points.txt*.dist-info 分发目录。这是中描述的目录 PEP 376 对于已安装的分发,以及 PEP 427 对于车轮。文件使用UTF-8字符编码。

文件内容为ini格式,如python的 configparser 模块。但是,默认情况下,configparser将名称视为不区分大小写,而入口点名称则区分大小写。可以这样创建区分大小写的配置分析器:

import configparser

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

入口点文件必须始终使用 = 从值中分隔名称(而configParser还允许使用 :

配置文件的各个部分表示入口点组,名称是名称,值对对象引用和可选附加项进行编码。如果使用附加项,则它们是方括号内逗号分隔的列表。

在一个值中,读卡器必须接受并忽略冒号之前或之后、对象引用和左方括号之间、多余名称和方括号之间以及分隔它们的冒号之后以及右方括号之后的空格(包括多个连续空格)。Extras的语法正式指定为 PEP 508 (AS) extras )对于编写文件的工具,建议只在对象引用和左方括号之间插入一个空格。

例如::

[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

用于脚本

两组入口点在包装中具有特殊意义: console_scriptsgui_scripts . 在这两个组中,安装包之后,入口点的名称应可用作系统shell中的命令。对象引用指向一个函数,该函数在运行此命令时将不带参数调用。函数可以返回一个整数作为进程退出代码,并返回 None 等于返回 0 .

例如,入口点 mycmd = mymod:main 将创建一个命令 mycmd 启动这样的脚本:

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

两者之间的区别 console_scriptsgui_scripts 仅影响Windows系统。 console_scripts 包装在控制台可执行文件中,因此它们附加到控制台并可以使用 sys.stdinsys.stdoutsys.stderr 输入和输出。 gui_scripts 被包装在一个GUI可执行文件中,因此它们可以在没有控制台的情况下启动,但是除非应用程序代码重定向它们,否则不能使用标准流。其他平台没有相同的区别。

安装工具应为这两种情况设置包装器 console_scriptsgui_scripts 在安装方案的脚本目录中。他们不负责将此目录放入 PATH 定义命令行工具的位置的环境变量。

由于文件是根据名称创建的,并且某些文件系统不区分大小写,所以包应该避免在这些组中使用仅大小写不同的名称。安装工具在名称不同时的行为只有在未定义的情况下才不同。