如何使用Setuptools注册多个Pluggy插件并让它们按序执行?
如何使用Setuptools注册多个Pluggy插件并让它们按序执行?
嘿,我完全懂你现在的困惑——你遇到的问题核心其实是entry point的命名重复了!咱们来一步步拆解解决:
问题根源
你现在给两个插件的entry point都用了run_plugin这个名字,Pluggy的插件管理器在加载时,会把同名的entry point视为同一个插件实例,后面安装的插件会直接覆盖之前的,所以最后只有最后安装的那个插件能运行。
解决步骤
1. 给每个插件的entry point设置独一无二的名称
修改两个插件的pyproject.toml,把entry point的名字改成各自独有的:
plugin_a/pyproject.toml
[project] name = "plugin_a" version = "1.0.0" dependencies = ["pluggy==1.3.0", "pluggable"] [project.entry-points.pluggable] plugin_a = "a" # 改成独有的名字,比如直接用插件名
plugin_b/pyproject.toml
[project] name = "plugin_b" version = "1.0.0" dependencies = ["pluggy==1.3.0", "pluggable"] [project.entry-points.pluggable] plugin_b = "b" # 同样用独有的名字
2. 重新安装插件并测试
先清理环境(可选,确保没有残留),然后重新安装插件:
venv/bin/pip uninstall -y plugin_a plugin_b venv/bin/pip install -e pluggable -e plugin_a -e plugin_b
再运行主程序:
venv/bin/python pluggable/pluggable.py
这时候你就能看到两个插件的输出了:
run from a run from b
自定义执行顺序
如果想要指定插件的执行顺序,而不是依赖安装顺序,可以在定义hook实现时添加tryfirst或trylast参数:
比如让plugin_b优先执行:
# plugin_b/b.py import pluggy from pluggable import impl @impl(tryfirst=True) # 添加这个参数,让它先执行 def run_plugin(): print(f"run from {__name__}")
重新运行后就会先输出run from b,再输出run from a,完全符合你的预期!
原理补充
Pluggy的load_setuptools_entrypoints方法是通过entry point的名称来区分不同插件的,每个唯一的名称对应一个独立的插件模块。只要名称不重复,所有符合钩子规范的插件都会被加载,并且在调用钩子时按顺序执行。
备注:内容来源于stack exchange,提问作者kojiro
相关产品推荐
相关产品推荐

