本系列前五篇其实已经将pluggy的流程原理等分析完了,只有PluginManager类还有几个方法的源代码没有提到,这里将这些方法拿出来简单的分析一下,因为有可能会用到,当然也有可能根本不会用这些
(1)unregister 取消注册插件
注册插件的过程都分析过了,取消注册过程就简单了,这里可以简单的看一下,这里主要就是对_name2plugin和_plugin2hookcallers这两个字典进行删除对应的插件,即取消注册插件,源代码如下:
def unregister(self, plugin=None, name=None):
""" unregister a plugin object and all its contained hook implementations
from internal data structures. """
if name is None:
assert plugin is not None, "one of name or plugin needs to be specified"
name = self.get_name(plugin)
if plugin is None:
plugin = self.get_plugin(name)
# if self._name2plugin[name] == None registration was blocked: ignore
if self._name2plugin.get(name):
del self._name2plugin[name]
for hookcaller in self._plugin2hookcallers.pop(plugin, []):
hookcaller._remove_plugin(plugin)
return plugin
(2)set_blocked 设置阻塞状态
这个设置阻塞状态可以是pluggy更加灵活,比如在在大多数场景下都要注册插件,但是在某中场景下,某个插件不支持,此时则可以暂时给设置阻塞状态,这样pluggy插件系统使用起来更加灵活
def set_blocked(self, name):
""" block registrations of the given name, unregister if already registered. """
self.unregister(name=name)
self._name2plugin[name] = None
(3)is_blocked 判断插件是否处于阻塞状态
def is_blocked(self, name):
""" return ``True`` if the given plugin name is blocked. """
return name in self._name2plugin and self._name2plugin[name] is None
(4)is_registered 判断插件是否是注册的
def is_registered(self, plugin):
""" Return ``True`` if the plugin is already registered. """
return plugin in self._plugin2hookcallers
(5)get_plugin 根据插件名称获取插件对象
def get_plugin(self, name):
""" Return a plugin or ``None`` for the given name. """
return self._name2plugin.get(name)
(6)get_name 根据插件对象获取插件名称
def get_name(self, plugin):
""" Return name for registered plugin or ``None`` if not registered. """
for name, val in self._name2plugin.items():
if plugin == val:
return name
(7)load_setuptools_entrypoints 通过setuptools的方式注册插件
这个方法需要注意一下,这个挺重要的,可以通过指定group名称的方式来自动注册插件,只要当前的环境中其他包中有通过setuptools的方式定义了此group名称的模块,就可以自动的注册,在著名的自动化测试框架pytest中,就是使用了这个函数,对group为“pytest11”的插件进行自动注册,使用起来非常方便,这样用户就可以通过自定义pytest11模块来对pytest做功能增强了,而不需要修改pytest的源码
def load_setuptools_entrypoints(self, group, name=None):
""" Load modules from querying the specified setuptools ``group``.
:param str group: entry point group to load plugins
:param str name: if given, loads only plugins with the given ``name``.
:rtype: int
:return: return the number of loaded plugins by this call.
"""
count = 0
for dist in importlib_metadata.distributions():
for ep in dist.entry_points:
if (
ep.group != group
or (name is not None and ep.name != name)
# already registered
or self.get_plugin(ep.name)
or self.is_blocked(ep.name)
):
continue
plugin = ep.load()
self.register(plugin, name=ep.name)
self._plugin_distinfo.append((plugin, DistFacade(dist)))
count += 1
return count
PluginManager类还有几个简单的方法,这里就不再一一分析了,至此对pluggy的源码分析就全部结束了
标签:插件,name,plugin,self,pytest,源码,._,None From: https://www.cnblogs.com/guanqibuyu/p/16649603.html