问题
我可以使用load_setuptools_entrypoints
在pluggy中成功注册单个插件,但我只能注册一个。如果两个不同的插件尝试自行注册,则最后注册的插件将是唯一运行的插件。
我认为这不是 Pluggy 的工作方式,而且我犯了一个配置错误,但我不知道该怎么做。我认为pluggy应该允许多个插件在调用该钩子(Hook)时注册并串行运行。
项目结构
.
├── pluggable
│ ├── pluggable.py
│ └── pyproject.toml
├── plugin_a
│ ├── a.py
│ └── pyproject.toml
└── plugin_b
├── b.py
└── pyproject.toml
与:
# pluggable/pluggable.py
import pluggy
NAME = "pluggable"
impl = pluggy.HookimplMarker(NAME)
@pluggy.HookspecMarker(NAME)
def run_plugin():
pass
def main():
m = pluggy.PluginManager(NAME)
m.load_setuptools_entrypoints(NAME)
m.hook.run_plugin()
if __name__ == "__main__":
main()
和
# pluggable/pyproject.toml
[project]
name = "pluggable"
version = "1.0.0"
dependencies = ["pluggy==1.3.0"]
plugin_a/a.py和plugin_b/b.py具有相同的内容:
# plugin_a/a.py
import pluggy
from pluggable import impl
@impl
def run_plugin():
print(f"run from {__name__}")
if __name__ == "__main__":
run_plugin()
plugin_a/pyproject.toml 和plugin_b/pyproject.toml 将各自的模块注册为插件:
# plugin_a/pyproject.toml
[project]
name = "plugin_a"
version = "1.0.0"
dependencies = ["pluggy==1.3.0", "pluggable"]
[project.entry-points.pluggable]
run_plugin = "a"
plugin_b/pyproject.toml 是相同的,除了 run_plugin = "b"
。
演示运行
$ python -m venv venv
...
$ venv/bin/pip install -e pluggable -e plugin_a
...
Successfully installed pluggable-1.0.0 plugin-a-1.0.0
$ venv/bin/python pluggable/pluggable.py
run from a
$ venv/bin/pip install -e plugin_b
...
Successfully installed plugin-b-1.0.0
$ venv/bin/python pluggable/pluggable.py
run from b
预期结果
最后我想看到的是
run from b
run from a
进一步分析
阅读 load_setuptools_entrypoints代码很清楚发生了什么。一旦一个插件注册到一个名称,PluginManager.get_plugin(name)
returns that value ,这样其他插件就不会以相同的名称注册。
但是我希望得到帮助来理解什么是使用pluggy配置插件系统的正确方法,以便两个不同的python包可以使用相同的规范和钩子(Hook)注册自己,这样pluggy将串行运行它们?
最佳答案
正如您所观察到的,可能只有一个具有特定名称的插件。使用入口点时,插件的名称就是入口点的名称。
据我了解the docs ,钩子(Hook)通过spec/impl名称和签名进行匹配,在此过程中插件名称并不重要(插件只是相关钩子(Hook)实现的命名集合)。
根据这两个,入口点名称应该与插件名称匹配(并且应该是唯一的);请参阅plugin setup.py example 。因此,pyproject.toml 入口点看起来类似于 a = "a"
。
(与上面的代码不相关的可能问题是,应该使用 add_hookspecs(), example 将规范添加到管理器中。鉴于您的代码在没有它的情况下也可以工作,它可能不是强制性的,但它允许管理器验证违反规范的实现,所有示例似乎都使用它。)
关于python - 如何使用 setuptools 注册多个 Pluggy 插件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77579324/