如何让装饰器包裹的函数__code__.co_filename与原函数一致适配robot.libdoc
问题解决方法
问题原因
- 装饰器的包装函数
_passargs定义在lib/keyword.py中,默认它的__code__对象的co_filename属性会指向自身定义的文件路径 functools.wraps仅会复制函数名、文档、模块名等表层属性,不会修改__code__内部的元信息,因此之前的写法无法修改co_filename的取值
实现方案
你使用的Python 3.8.10刚好支持code.replace()方法,可以在不修改包装函数执行逻辑的前提下,仅替换__code__对象中和源文件位置相关的属性,完全满足需求。
修改后的keyword.py代码如下:
from functools import wraps def keyword(name=None, tags=(), types=()): def _method_wrapper(func): @wraps(func) def _passargs(self, *args, **kwargs): # 原有逻辑完全保留 print(func.__code__.co_filename) # --> '..\main\test.py' return func(self, *args, **kwargs) # 替换code对象的源文件路径、行号信息 _passargs.__code__ = _passargs.__code__.replace( co_filename=func.__code__.co_filename, co_firstlineno=func.__code__.co_firstlineno ) # 同步函数__file__属性,保证工具兼容性 _passargs.__file__ = func.__file__ print(_passargs.__code__.co_filename) # 现在输出为 '..\main\test.py' return _passargs return _method_wrapper
验证说明
修改后_passargs的执行逻辑和之前完全一致,仅源文件定位元信息会和原函数func保持一致,robot.libdoc可以正常识别到关键字的源文件路径,顺利生成.libspec文档。
内容的提问来源于stack exchange,提问作者Timmy Lin
相关产品推荐
相关产品推荐

