首页 > 编程语言 >pytest系列——pluggy插件源码解读(六)PluginManager类的其他功能

pytest系列——pluggy插件源码解读(六)PluginManager类的其他功能

时间:2022-09-02 13:55:37浏览次数:64  
标签:插件 name plugin self pytest 源码 ._ None

本系列前五篇其实已经将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

相关文章