【pytest框架源码分析三】pluggy源码分析之hook注册调用流程

embedded/2025/3/5 4:25:30/

pluggy的hook调用,最重要的就是使用了__call__魔法函数,这个函数能够在我们调用实例时,自动调用这个函数,无需自己手动调用。
前面介绍了各个类的方法,这里简述下pluggy的调用流程(主要介绍主流程,分支处理忽略)。
前面我们介绍了HookspecMarker和HookimplMarker这两个类,这两个类是用来作装饰器用的,spec相当于接口类,impl为实现类。我们这边还用之前的例子,来介绍下插件的注册调用流程。

import pluggyspec_test = pluggy.HookspecMarker('test11')
impl_test = pluggy.HookimplMarker('test11')class Spec:@spec_testdef pluggy_test(self, arg1):print(f'this is spec test and arg is {arg1}')passclass Impl1:@impl_testdef pluggy_test(self, arg1):print(f'this is test1 and arg is {arg1}')return arg1class Impl2:@impl_testdef pluggy_test(self, arg1):print(f'this is test2 and arg is {arg1}')return -1 * arg1pm = pluggy.PluginManager('test11')
pm.add_hookspecs(Spec)
pm.register(Impl1())
pm.register(Impl2())
res = pm.hook.pluggy_test(arg1=1)

pluggy.PluginManager(‘test11’)调用后实例化一个pm,注册执行流程都依靠pm管理。
add_hookspecs(Spec)在pm中增加一个spec。
在这里插入图片描述
这个方法中最重要的就是实例化了一个HookCaller的对象,并且把它放到self.hook中。
然后调用pm.register(Impl1())注册 插件
在这里插入图片描述
注册方法中比较重要的就是实例化了一个hookimpl对象,并且把它添加到hook中,具体看就是添加到_hookimpls的list中(整体在我们上面添加的HookCaller下)。
在这里插入图片描述
接下继续注册第二个插件Impl2,注意hook添加spec时,是按照方法名添加的。impl1和impl2中两个方法名是一样的,所以不会添加新的name来存放impl2下的pluggy_test。Impl2的pluggy_test也和impl1的pluggy_test注册在同一个HookCaller下。
最后调用 pm.hook.pluggy_test(arg1=1)来执行插件。这里的pluggy_test就是HookCaller对象(add_hookspecs步骤)。因为HookCaller类中有__call__函数,所以调用该对象时,会自动调用该方法。
在这里插入图片描述
执行方法就是最下面这行。_hookexec方法即是我们初始化HookCaller传入的。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
即我们在执行pm.hook.pluggy_test(arg1=1)的时候调用的_multicall方法执行插件方法。
这就是pluggy的整体注册调用流程,细节部分可结合前后文一起看下。


http://www.ppmy.cn/embedded/170084.html

相关文章

PyTorch 深度学习快速入门教程

PyTorch 深度学习快速入门教程 🚀 PyTorch 是一个 灵活且易用 的深度学习框架,支持 动态图计算,广泛用于 学术研究 和 工业应用。本教程将带你快速掌握 PyTorch 的 基本用法,涵盖 张量(Tensor)操作、自动求…

【Redis】Mac系统一键安装redis

要在 macOS 上一键安装 Redis,可以使用 Homebrew(一个流行的包管理工具)来简化安装过程。下面是可以执行的安装脚本: 安装脚本: #!/bin/bash# 检查 Homebrew 是否已安装,如果没有安装,则安装 …

QT 中的元对象系统(三):QObject深入理解

目录 1.简介 2.特性 2.1.对象树与内存管理 2.2.信号与槽机制 2.3.事件处理 2.4.属性系统 2.4.1.Q_PROPERTY配置的属性 2.4.2.动态属性 2.4.3.实现原理 2.5.国际化支持 2.6. 定时器支持 3.类设计(q和d指针) 4.总结 1.简介 QObject这个 class 是 QT 对象模型的核心&…

前端水印实现方式

一、简介 简单来说,前端水印就是在网页或应用程序的前端界面上添加的一种标记,通常是文本、图标或图案等形式。它就像给你的数字内容贴上了一个独特的 “标签”,用于标识内容的归属、防止未经授权的使用和传播。比如,一些在线图片…

【HarmonyOS NEXT】控制 WebP 格式动图播放次数的实现方案

一、背景 在开发过程中,我们可能会遇到需要控制 WebP 格式动态图播放次数的需求。例如,某些场景下只需要动图播放一次,而不是循环播放。然而,使用原生组件(如 Image 或 ImageAnimator)时,WebP …

【终篇】基于C++的通讯录管理系统(完整源码)

前置 安装 nlohmann/json 库 文件结构 AddressBook/ ├── nlohmann└── json.hpp ├── Contact.h ├── Contact.cpp ├── AddressBook.h ├── AddressBook.cpp ├── Serializer.h ├── Serializer.cpp ├── FileManager.h ├── FileManager.cpp └── …

深度求索(DeepSeek)的AI革命:NLP、CV与智能应用的技术跃迁

Deepseek官网:DeepSeek 引言:AI技术浪潮中的深度求索 近年来,人工智能技术以指数级速度重塑全球产业格局。在这场技术革命中,深度求索(DeepSeek)凭借其前沿的算法研究、高效的工程化能力以及对垂直场景的…

PySpark中mapPartitionsWithIndex等map类算子生成器函数问题 - return\yield

PySpark中mapPartitionsWithIndex等map类算子生成器函数问题 - return\yield 顾名思义,本文讲述了map算子生成器函数的相关问题——return 和 yield的使用。 首先先讲结论,在使用map等迭代生成的算子时最好使用yield。 1、问题产生 在写代码的过程中&…