Pluggy源码解读----PluginManager类的其他功能

【原文链接】Pluggy源码解读----PluginManager类的其他功能

至此pluggy的主要功能的源码基本都已经解读完了,这里在将PluginManager类中其他功能的代码在简要的解读一下,PluginManager类不但提供了注册插件的功能,还提供了取消注册插件的功能,取消注册插件的功能代码实现如下所示,注册的代码解读完成后再来看取消注册的代码就简单多了,取消注册简单点说就是_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)

PluginManager还提供了设置阻塞的方法,代码如下,设置阻塞的代码就更简单了,直接调用取消注册的方法实现,然后将_name2plugin属性此插件名对应的值设置为None即可。

    def set_blocked(self, name):
        """block registrations of the given name, unregister if already registered."""
        self.unregister(name=name)
        self._name2plugin[name] = None

下面是判断是否阻塞的代码实现,实质上就是判断插件名是否在_name2plugin属性中以及当_name2plugin属性中存在插件名时需要进一步判断此插件名对应的插件对象是否为None。

    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

如下为获取插件列表的代码,这里直接将_plugin2hookcallers属性转换为集合然后返回。

    def get_plugins(self):
        """return the set of registered plugins."""
        return set(self._plugin2hookcallers)

如下代码为判断插件是否注册,即判断插件类对象是否在_plugin2hookcallers属性中。

    def is_registered(self, plugin):
        """Return ``True`` if the plugin is already registered."""
        return plugin in self._plugin2hookcallers

如下为根据插件名获取插件对象,这里直接从_name2plugin属性中根据名称获取即可,因为_name2plugin是一个字典格式数据。

    def get_plugin(self, name):
        """Return a plugin or ``None`` for the given name."""
        return self._name2plugin.get(name)

如下为判断是否有插件,则直接调用根据名称获取插件对象,只要返回的插件对象不为None即可。

    def has_plugin(self, name):
        """Return ``True`` if a plugin with the given name is registered."""
        return self.get_plugin(name) is not None

如下是一个很重要的,可以通过指定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 list(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的源码分析就全部完成了。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

redrose2100

您的鼓励是我最大的创作动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值