获取当前帧正在执行的AST节点以及其他信息
项目描述
executing
这个小包让您能够获取有关帧当前正在执行的信息,特别是正在执行的AST节点。
用法
获取AST节点
import executing
node = executing.Source.executing(frame).node
在这种情况下,node
将是一个来自ast
标准库模块的AST节点,或者如果节点无法识别(这可能会经常发生,因此应该始终进行检查),则为None。
对于多次调用,如果执行点相同,则node
将始终是相同的实例。
如果您有一个跟踪对象,请直接将其传递给Source.executing()
,而不是传递tb_frame
属性,以获取正确的节点。
获取节点的源代码
为此,您需要单独安装asttokens
库,然后获取一个ASTTokens
对象
executing.Source.executing(frame).source.asttokens()
或
executing.Source.for_frame(frame).asttokens()
或使用其中一个便利方法
executing.Source.executing(frame).text()
executing.Source.executing(frame).text_range()
获取当前函数的__qualname__
executing.Source.executing(frame).code_qualname()
或
executing.Source.for_frame(frame).code_qualname(frame.f_code)
Source类
所有内容都通过Source
类进行。每个文件名只创建一个类的实例。建议在创建时或添加方法时对该类进行子类化。像executing
这样的类方法会尊重这一点。请参阅源代码和docstrings以获取更多详细信息。
安装
pip install executing
如果您不喜欢这样做,可以简单地复制文件executing.py
,没有依赖关系(但当然您不会收到更新)。
它是如何工作的?
假设框架正在执行此行
self.foo(bar.x)
特别是它目前正在获取属性self.foo
。查看字节码,特别是frame.f_code.co_code[frame.f_lasti]
,我们可以知道它正在加载一个属性,但不确定是哪一个。我们可以使用frame.f_lineno
来缩小正在执行的语句,并找到表示self.foo
和bar.x
的两个ast.Attribute
节点。我们如何在不重新创建整个Python编译器的情况下找出它是哪一个呢?
诀窍是略微修改每个候选表达式的AST,并观察字节码指令的变化。我们将AST修改为以下内容
(self.foo ** 'longuniqueconstant')(bar.x)
并编译它,字节码将几乎相同,但会有两个新的指令
LOAD_CONST 'longuniqueconstant'
BINARY_POWER
在这之前将有一个对应于self.foo
的LOAD_ATTR
指令。看到它在原始指令相同的位置,我们知道我们已经找到了匹配项。
它可靠吗?
是的——如果它识别了一个节点,您可以相信它已经识别了正确的节点。测试非常彻底——除了直接检查各种情况的单元测试外,还有针对大量文件(请参阅此构建中打印的文件名)的属性测试,其中包含真实代码。具体来说,对于每个文件,测试
- 尽可能从文件中的所有字节码指令中识别出尽可能多的节点,并断言它们都是唯一的
- 找到所有应该可识别的节点,并断言它们确实在某个地方被识别
换句话说,它表明节点和可以处理的指令之间存在一对一的映射。这留给错误的余地很小。
此外,executing
检查从修改后的AST编译的指令与原始代码(除了一些已知的小异常外)完全匹配。这解释了解释器中的所有怪癖和优化。
它可以识别哪些节点?
目前它适用于以下ast
节点的几乎所有情况
Call
,例如self.foo(bar)
Attribute
,例如point.x
Subscript
,例如lst[1]
BinOp
,例如x + y
(不包括and
和or
)UnaryOp
,例如-n
(包括not
但有时不起作用)Compare
,例如a < b
(不适用于链,如0 < p < 1
)
计划在未来扩展到更多操作。
使用此技术的项目
我的项目
stack_data
:从堆栈帧和回溯中提取数据,特别是显示比默认更有用的回溯。还使用我的另一个相关库:pure_eval
。futurecoder
:通过stack_data
使用executing
突出显示回溯中的执行节点,并使用snoop
提供调试。snoop
:一个功能丰富且方便的调试库。使用executing
显示导致异常的操作,并允许pp
函数显示其参数的源代码。heartrate
:Python程序执行过程的简单实时可视化。使用executing
突出显示当前正在执行的操作,尤其是在堆栈跟踪的每一帧中。sorcery
:Python中的暗黑魔法乐趣。使用executing
让特殊的可调用对象(魔法)知道它们被调用的位置。
我贡献的项目
IPython
:使用stack_data
通过executing
突出显示跟踪回溯中的执行节点。icecream
:🍦 甜美香浓的打印调试。使用executing
识别ic
被调用的位置并打印其参数。friendly_traceback
:使用stack_data
和executing
定位错误原因并提供有用的说明。python-devtools
:使用executing
进行类似于icecream
的打印调试。sentry_sdk
:将集成sentry_sdk.integrations.executingExecutingIntegration()
添加到sentry事件中显示每个帧的__qualname__
函数。varname
:关于Python中变量名称的暗黑魔法。使用executing
查找其各种魔法函数(如varname
和nameof
)的调用位置。
项目详情
下载文件
下载适合您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。
源分布
构建分布
executing-2.1.0.tar.gz的散列
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 8ea27ddd260da8150fa5a708269c4a10e76161e2496ec3e587da9e3c0fe4b9ab |
|
MD5 | e64dd9916bb0a6c89f88295f4867c1b6 |
|
BLAKE2b-256 | 8ce37d45f492c2c4a0e8e0fad57d081a7c8a0286cdd86372b070cca1ec0caa1e |
执行-2.1.0-py2.py3-none-any.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 8d63781349375b5ebccc3142f4b30350c0cd9c79f921cde38be2be4637e98eaf |
|
MD5 | 99bcfdc77ecdd522bf2fee68c9d32f78 |
|
BLAKE2b-256 | b5fdafcd0496feca3276f509df3dbd5dae726fcc756f1a08d9e25abe1733f962 |