我需要获取函数“get_id”的源,而inspect.getsource()正在返回函数“update_creds”的源,我不知道为什么
有关环境的一些细节:它在 Splunks SOAR 上运行,查看堆栈跟踪似乎正在运行一个包装程序来获取、解码、执行脚本,因此仅要求检查来查找源代码似乎不起作用,除非我手动将文件导入到自身中。
这是我正在调试的代码:
def get_id(**kwargs):
print("get_id")
# Function header I cannot touch
def update_creds(**kwargs):
# inspect.stack()[0][3] gets the name of the function we are currently in
exec(get_new_return(function=inspect.stack()[0][3]))
return
# Automatically generated code I cannot touch
phantom.act("old_parameter","other_parameters_that_change")
return
# Function header I cannot touch
def get_function_source(**kwargs):
import inspect
import re
import sys
# We have to add the git repo to the system path so we can import the file
sys.path.insert(0, '/scm/git/')
# Get the file name from __file__ (its formatted within angle brackets, so we get rid of them
source=__import__(re.sub(r'(<|>)','',__file__))
# use eval to specifially refer to this files function object.
# using debug comments, the eval does indeed refer to the correct object I want the source from
# However, the return of inspect.getsource() gives me the source of another function
function_source=inspect.getsource(eval("source."+kwargs["function"]))
generated_code=re.findall(r'phantom.act\((.*)\)', function_source)[-1]
return generated_code.replace("old_parameter", "new_parameter")
如果你真的想知道我为什么这样做,环境使用代码块来生成Python代码,特别是函数定义和最终函数调用以继续执行。但是,我需要为下一个函数调用添加一个参数,因此我使用inspect.getsource()来获取最终的函数调用,添加参数,调用它,然后提前返回。
我尝试跟踪它失去对正确函数的引用的地方,这似乎是在调用inspect.getsource()时。我期待“get_id”函数的来源,而不是“update_creds”函数的来源。
查看 getsource 的工作原理,我认为这可能与函数的名称有关,但从我所看到的来看,这些名称没有任何共同点。我唯一能想到的另一件事是,如果 getsource 引用行号,并且它错误地使用从一个文件到另一个文件的行号,但我不知道如何强制检查以确保它引用同一个文件
编辑:向代码块添加更多内容以获取更多上下文。在添加上下文时,我注意到 update_creds 是 get_id 上方的函数,因此几乎就像 inspect.getsource() 需要再进行一个函数定义,但我不知道这是否是一次性的,或者是否会总是落后一位。如果它总是相差一位,我如何让 getsource 给我下一个函数?
在您的代码中,永远不会调用
get_id()
,因此它永远不会出现在堆栈跟踪中。
除此之外,答案似乎就在代码的注释中;
def update_creds(**kwargs):
# inspect.stack()[0][3] gets the name of the function we are currently in
exec(get_new_return(function=inspect.stack()[0][3]))
inspect.stack()[0][3])
将计算为“update_creds”,因为这就是您调用它时所在的函数。因此,当您调用 get_new_return()
时,function
arg 将设置为“update_creds”。结果,get_new_return()
获得了 update_creds()
的来源