[pytest源码6]-pytest-pluggy源码总结

前言

在分析完pytest-pluggy部分后,在本篇进行一个总结。
个人拙见,有错请各位指出。
如果的我的文章对您有帮助,不符动动您的金手指给个Star,予人玫瑰,手有余香,不胜感激。 GitHub



回顾一下pluggy Demo

# -*- coding:utf-8 -*-

from pluggy import PluginManager, HookspecMarker, HookimplMarker

hookspec = HookspecMarker("myPluggyDemo_1") #一个声明hook method的类,每个hook method都需要用@hookspec来装饰
hookimpl = HookimplMarker("myPluggyDemo_1") #一个plugin的实现,需要完整实现对应的hook方法,并通过@hookimpl来装饰


class HookSpec:
    @hookspec
    def calculate(self, a, b):
        pass


class HookImpl1:
    @hookimpl
    def calculate(self, a, b):
        return a + b


pm = PluginManager("myPluggyDemo_1") #创建PluginManager对象
pm.add_hookspecs(HookSpec)
pm.register(HookImpl1())
results = pm.hook.calculate(a=1, b=5)
print(results)




总结

对前面分析的源码进行一次总结,这里就不会详细的去讲了。
阅读了一遍源码之后我们再对着pluggy的demo进行总结



I.

  • 首先保证项目唯一的project name是因为我们添加hook与注册pluggy时都需要利用封装类。
  • 装饰器将hook方法、plugin实现的引用以project name + spec+ method 为属性名增加到封装类中。
  • 保证唯一才能正确的找到对应的hook、plugin。

II.

  • 实例化HookspecMarker, HookimplMarker时会返回一个装饰器,我们可以通过这个方式自定义(重新定义)装饰器引用名称。

IV.

  • 在通过装饰器声明hook方法、plugin方法时,传入不同的参数可以达到如:改变执行顺序、定义wrapper plugin(yield)等效果

V.

  • 通过add_hookspecs将传入的hook instance中的特殊方法名hook name与对应的hook调用的封装实例_HookCallername:hc的形式作为属性添加加到PluginManager实例中的self.hook属性上。
  • 如果该特殊方法hook method存在的话。
    • 倘若特殊方法hook method不存在的话,将module_or_class与该“hook name”通过HookSpec()执行一遍2.的逻辑,并遍历当前PluginManager实例中的_nonwrappers_wrappers检查hook是否正确添加。

VI.

  • 通过register将传入的pluggy instance中特殊方法pluggy method进行数据封装得到HookImpl instance,并获取到当前PluginManager实例中的self.hook的同名属性。

  • 关键点就在这,此前我们在第4步添加hook时,所添加的同名hook方法就是在这个时候以这个同名属性关联起来了。

  • 然后将plugin的实现方法的调用方法以一定顺序(通过装饰器传入的的参数)添加到同名属性中,并保存到列表hookcallers中,即最后存储在PluginManager实例的self._plugin2hookcallers[plugin]

    • 倘若根本没有对应的同名hook呢?此时就会通过执行与第4步中相同的操作,封装_HookCallername:hook的形式作为属性添加到PluginManager实例中的self.hook属性上。然后再将plugin的调用方法添加到同名属性中,并保存到PluginManager实例的self._plugin2hookcallers[plugin]
    • 前置:会预先检查当前pluggy是否已经注册过了,抛出ValueError

VII.

  • 每个pluggy实现都会被封装成_HookCaller instance保存在PluginManager实例属性pm.hook中。
  • 每次对同名pluggy方法进行调用时,大致的调用逻辑是这样的:获得存储着对应的plugin实现的列表,将其反转(所以后register的plugin先执行),并检查plugin方法的参数是否有遵守对应hook方法的约定。
  • 分成hookwrapper和nonwrapper两种形式去执行plugin的实现代码,执行结果用_Result类进行封装,最后检查plugin call过程有无异常,没有异常就返回执行结果。



GitHubhttps://github.com/potatoImp/pytestCodeParsing

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值