1:N
的对应关系,假设同时注册了多个实现了同一hook的plugin,则会对应的返回多个结果。# -*- coding:utf-8 -*-
from pluggy import PluginManager, HookspecMarker, HookimplMarker
hookspec = HookspecMarker("myPluggyDemo_2")
hookimpl = HookimplMarker("myPluggyDemo_2")
class HookSpec:
@hookspec
def calculate(self, a, b):
pass
class HookImpl1:
@hookimpl
def calculate(self, a, b):
return a + b
class HookImpl2:
@hookimpl
def calculate(self, a, b):
return a * b
pm = PluginManager("myPluggyDemo_2")
pm.add_hookspecs(HookSpec)
pm.register(HookImpl1())
pm.register(HookImpl2())
print(pm.hook.calculate(a=2, b=3))
[6, 5]
plugin
,HookImpl1
和HookImpl2
,分别实现了加法和乘法两个逻辑。plugin
执行的结果,先执行后注册的HookImpl2
,再执行先注册的HookImpl1
,即越晚注册的plugin越先执行。(后续会讲原因)# -*- coding:utf-8 -*-
from pluggy import PluginManager, HookspecMarker, HookimplMarker
hookspec = HookspecMarker("myPluggyDemo_3")
hookimpl = HookimplMarker("myPluggyDemo_3")
class HookSpec:
@hookspec(firstresult=True)
def calculate(self, a, b):
pass
class HookImpl1:
@hookimpl
def calculate(self, a, b):
return a + b #本例子中不会执行加法逻辑
class HookImpl2:
@hookimpl
def calculate(self, a, b):
return a * b
pm = PluginManager("myPluggyDemo_3")
pm.add_hookspecs(HookSpec)
pm.register(HookImpl1())
pm.register(HookImpl2())
print(pm.hook.calculate(a=2, b=3))
6
# -*- coding:utf-8 -*-
from pluggy import PluginManager, HookspecMarker, HookimplMarker
hookspec = HookspecMarker("myPluggyDemo_4")
hookimpl = HookimplMarker("myPluggyDemo_4")
class HookSpec:
@hookspec()
def calculate(self, a, b):
pass
class HookImpl1:
@hookimpl(tryfirst=True)
def calculate(self, a, b):
return a + b
class HookImpl2:
@hookimpl
def calculate(self, a, b):
return a * b
pm = PluginManager("myPluggyDemo_4")
pm.add_hookspecs(HookSpec)
pm.register(HookImpl1())
pm.register(HookImpl2())
print(pm.hook.calculate(a=2, b=3))
[5, 6]
WrapperPlugin
# -*- coding:utf-8 -*-
from pluggy import PluginManager, HookspecMarker, HookimplMarker
hookspec = HookspecMarker("myPluggyDemo_5")
hookimpl = HookimplMarker("myPluggyDemo_5")
class HookSpec:
@hookspec
def calculate(self, a, b):
pass
class HookImpl1:
@hookimpl
def calculate(self, a, b):
print('HookImpl1 execute!')
return a + b
class HookImpl2:
@hookimpl(tryfirst=True)
def calculate(self, a, b):
print('HookImpl2 execute!')
return a * b
class WrapperPluggy:
@hookimpl(hookwrapper=True)
def calculate(self, a, b):
print('WrapperPluggy execute!')
print("Before yield")
result = yield #此处返回的值为其他两个pluggy执行的结果
print(f"After yield,result is {result.get_result()}")
return a * b + (a + b)
pm = PluginManager("myPluggyDemo_5")
pm.add_hookspecs(HookSpec)
pm.register(HookImpl1())
pm.register(HookImpl2())
pm.register(WrapperPluggy())
print(pm.hook.calculate(a=2, b=3))
WrapperPluggy execute!
Before yield
HookImpl2 execute!
HookImpl1 execute!
After yield,result is [6, 5]
[6, 5]
ImplWrapper
中的pluggy
的代码逻辑,以result = yield
为分割线,分成两个部分。第一部分执行完毕后,中断继续执行,转去执行其他plugin
,待其他plugin
都执行完时,回来继续执行剩下的部分。result = yield
result通过yield来获取到其他plugin执行的结果,即非wrapper plugin
的执行结果(HookImpl2
和HookImpl1
)WrapperPluggy
的返回结果没有被打印出来,这是因为wrapper plugin
的返回值会被Ignore
,原因后续会提到。GitHub:https://github.com/potatoImp/pytestCodeParsing