基于setuptools入口点机制的插件管理器
项目描述
Reentry
一个基于setuptools入口点的插件管理器,速度提高了10倍
存档通知
Python 3.8将importlib.metadata引入到Python标准库。使用import importlib.metadata和使用entry_points()函数扫描入口点都非常快。
单独的importlib-metadata软件包将此功能回传到python >=3.6,并且从版本4.6.3(或更早版本)开始,扫描甚至比标准库还要快。
以下是在MacBook Air M1(2020)上,在python 3.9.1 conda环境中(安装了248个软件包,其中约30个注册了入口点)记录的时间。
pkg_resources:总时间约147毫秒
$ python -mtimeit -n1 -r1 'import pkg_resources' 1 loop, best of 1: 146 msec per loop $ python -mtimeit -s 'import pkg_resources as pkg' 'pkg.iter_entry_points("aiida.calculations")' 500000 loops, best of 5: 435 nsec per loop
importlib.metadata:总时间约39毫秒
$ python -mtimeit -n1 -r1 'import importlib.metadata' 1 loop, best of 1: 17.8 msec per loop $ python -mtimeit -s 'import importlib.metadata as im' 'im.entry_points()' 50 loops, best of 5: 21.4 msec per loop
importlib-metadata软件包(v4.6.3):总时间约40毫秒
$ python -mtimeit -n1 -r1 'import importlib_metadata' 1 loop, best of 1: 33.8 msec per loop $ python -mtimeit -s 'import importlib_metadata as im' 'im.entry_points()' 50 loops, best of 5: 5.94 msec per loop
reentry(v1.3.1):总时间约25毫秒
$ python -mtimeit -n1 -r1 'import reentry' 1 loop, best of 1: 23.8 msec per loop $ python -mtimeit -s 'from reentry.default_manager import PluginManager as p' 'p().get_entry_map()' 200 loops, best of 5: 1.07 msec per loop
随着更快(固态)硬盘和更快importlib实现的到来,reentry带来的速度优势已经大幅减少(在上述基准测试中下降到约15毫秒或40%)。虽然可能仍然存在一些边缘情况,其中reentry是有用的,但我们将停止使用它,因此将存档此存储库。
有兴趣继续维护reentry的用户,请在问题跟踪器上创建一个问题。
特性
查找插件:reentry在文件中保持入口点的映射
速度:reentry提供了一个EntryPoint实现,它通过牺牲搜索和加载速度来换取额外的检查
自动注册:在您的setup.py中使用reentry_register: True来自动注册插件
请注意,reentry_register会在reentry上创建一个构建时依赖关系。建议的解决方法是使用PEP518中描述的方法,pip 10已添加对它的支持:在setup.py旁边放置一个包含以下内容的文件pyproject.toml:
[build-system] # Minimum requirements for the build system to execute. requires = ["setuptools", "wheel", "reentry"]
指定构建依赖关系的另一种方法是在您的setup.py中放置以下内容
setup( ... setup_requires=[reentry], ... )
此替代方案与所有版本的pip兼容,但在与旧SSL库链接的系统中(例如,某些版本的OS X的系统Python)会失败。
限制
支持具有额外依赖项的入口点(name = module_name:attrs [extras])。但是,尝试加载它们会导致导入pkg_resources并放弃速度提升。
快速入门
在您的插件setup.py中使用以下内容
setup( ... setup_requires=['reentry'], reentry_register=True, entry_points={ 'my_plugins': ['this_plugin = this_package.subpackage:member'], ... }
然后从宿主包中迭代已安装的插件
from reentry import manager available_plugins = manager.iter_entry_points(group='my_plugins') for plugin in available_plugins: plugin_object = plugin.load() plugin_object.use()
该语法与setuptools的pkg_resources保持一致,因此您可以用作后备
try: from reentry import manager as entry_pt_manager except: import pkg_resources as entry_pt_manager entry_pt_manager.iter_entry_points(...) ...
Reentry配置
Reentry支持从配置文件获取信息。该文件将在以下路径中搜索
<HOME>/.reentryrc
<HOME>/.config/reentry/config
配置文件具有ini格式,并支持以下键
[general] datadir=/path/to/data/dir data_filename=name
datadir是reentry存储包含已注册入口点信息的数据文件的文件夹。如果配置文件不存在于上述路径之一,则将datadir设置为<HOME>/.config/reentry/data。如果想要自己选择名称,而不是让reentry选择,则可以使用data_filename。警告:默认情况下,reentry为每个Python解释器创建一个独立的数据文件,以避免在不同Python环境中混合入口点。在配置文件中设置data_filename告诉reentry始终使用此数据文件,如果同时在多个Python环境中使用reentry,可能会导致意外的行为。
您还可以通过环境变量设置reentry的配置选项
datadir可以通过REENTRY_DATADIR定义。
data_filename可以通过REENTRY_DATA_FILENAME定义。
环境变量优先于配置文件。
用途?
为了在时间敏感的情况下(如命令行界面)使入口点对插件可用!
Setup工具的入口点系统便于用于基于插件的Python应用程序。它允许独立的Python包作为宿主包(或彼此)的插件,从而使宿主程序易于查找和迭代插件的相关数据结构。
然而,导入setuptools所需的时间与已安装的分布数量成比例增长,在中等复杂的环境中,它可能达到0.5秒。查找和加载插件可能是时间敏感的,例如在需要加载子命令的命令行工具中,100毫秒的延迟是明显的。
导入setuptools的pkg_resources需要时间,因为它验证环境中所有分布的依赖项是否正确安装。这允许入口点具有额外的依赖项或“额外内容”(entry_point = module_name:attrs [extras])。
Reentry省略了“额外内容”入口点的依赖项检查,从而实现快速且与已安装插件的数量的扩展性。
独立管理器使用
有时可能需要更新缓存的入口点,例如
在卸载插件后(目前setuptools没有卸载钩子)
在安装不使用安装钩子的插件后
在开发插件/插件宿主时
对于这些情况,Reentry有一个命令行界面
$ reentry --help Usage: reentry [OPTIONS] COMMAND [ARGS]... manage your reentry python entry point cache Options: --help Show this message and exit. Commands: clear Clear entry point map. dev Development related commands. map Print out a map of cached entry points scan Scan for python entry points to cache for faster loading.
$ reentry scan --help Usage: reentry scan [OPTIONS] PATTERN Scan for python entry points to cache for faster loading. Scan only for specific PATTERNs or leave empty to scan all Options: -r, --regex Treat PATTERNs as regular expresions --help Show this message and exit.
$ reentry map --help Usage: reentry map [OPTIONS] Options: --dist TEXT limit map to a distribution --group TEXT limit map to an entry point group --name TEXT limit map to entrypoints that match NAME --help Show this message and exit.
注意:在需要的地方(例如在jupyter笔记本中),这些操作也可以使用reentry manager在Python中执行,例如
from reentry import manager manager.scan()
CLI示例
Reentry提供了iter_entry_points的替代方案
import click from click_plugins import with_plugins from reentry.manager import iter_entry_points @with_plugins(iter_entry_points('cli_plugins')) @click.group() def cli(): """ command with subcommands loaded from plugin entry points """
为了使其工作,Reentry必须安装,并且必须使用它扫描过‘cli_plugins’组的入口点一次。
开发
运行测试
tox
创建发行版
tox -e py39-release
项目详情
下载文件
下载适用于您平台文件。如果您不确定选择哪个,请了解有关安装包的更多信息。
源分布
构建分布
reentry-1.3.3.tar.gz 的散列值
算法 | 散列摘要 | |
---|---|---|
SHA256 | 6343d83245e5047c9f8db0702ec1a7fa8210bd553f0ab643212572f6fce2c3ff |
|
MD5 | 30b57a189bb3c319c0552a2f3105d34d |
|
BLAKE2b-256 | 9520e820a29014f1cb662423d7001dc09a9ea5280083ea300f0c5efe5cae238b |
reentry-1.3.3-py3-none-any.whl 的散列值
算法 | 散列摘要 | |
---|---|---|
SHA256 | 32c0badd69f1fc7a550e55bf5d1bf3cdaa2220f93ebe6dcf913020d3218470f3 |
|
MD5 | 70b73c638eb94c611eb568d796193356 |
|
BLAKE2b-256 | 0f30cd3e86316192148d61a4a61cffe3d1feb8ffcd1ec854d6ab5330b1592592 |