plugin_name = name or self.get_canonical_name(plugin)#獲取插件名if plugin_name in self._name2plugin or plugin in self._plugin2hookcallers:if self._name2plugin.get(plugin_name,-1)isNone:return# blocked plugin, return None to indicate no registrationraise ValueError("Plugin already registered: %s=%s\n%s"%(plugin_name, plugin, self._name2plugin))
def_add_hookimpl(self, hookimpl):"""Add an implementation to the callback chain.
"""if hookimpl.hookwrapper:#根據hookimpl.hookwrapper將plugin分爲兩類
methods = self._wrappers
else:
methods = self._nonwrappers
if hookimpl.trylast:#根據參數爲plugin調整對應的執行順序
methods.insert(0, hookimpl)elif hookimpl.tryfirst:
methods.append(hookimpl)else:# find last non-tryfirst method
i =len(methods)-1while i >=0and methods[i].tryfirst:
i -=1
methods.insert(i +1, hookimpl)if"__multicall__"in hookimpl.argnames:#版本更新做的處理,不再支持__multicall__的參數方式
warnings.warn("Support for __multicall__ is now deprecated and will be""removed in an upcoming release.",
DeprecationWarning,)
self.multicall = _legacymulticall
defcall_extra(self, methods, kwargs):""" Call the hook with some additional temporarily participating
methods using the specified kwargs as call parameters. """
old =list(self._nonwrappers),list(self._wrappers)#獲取到所有原始插件listfor method in methods:#遍歷plugin method
opts =dict(hookwrapper=False, trylast=False, tryfirst=False)#統一臨時plugin參數
hookimpl = HookImpl(None,"<temp>", method, opts)#創建臨時plugin實例
self._add_hookimpl(hookimpl)#默認排序plugin執行順序try:return self(**kwargs)#返回插件增加了臨時plugin的插件引用finally:
self._nonwrappers, self._wrappers = old #執行完畢,恢復原始插件list
def_maybe_apply_history(self, method):"""Apply call history to a new hookimpl if it is marked as historic.
"""if self.is_historic():for kwargs, result_callback in self._call_history:
res = self._hookexec(self,[method], kwargs)if res and result_callback isnotNone:
result_callback(res[0])