Python的inspect获取源代码返回不相关的源代码

0 投票
1 回答
42 浏览
提问于 2025-04-14 18:22

我需要获取一个叫做 'get_id' 的函数的源代码,但使用 inspect.getsource() 时,它却返回了 'update_creds' 函数的源代码,我不知道为什么会这样。

关于环境的一些具体信息:它在 Splunk 的 SOAR 上运行,从堆栈跟踪来看,似乎是在运行一个包装程序来获取、解码和执行脚本,所以仅仅请求 inspect 找源代码似乎不太管用,除非我手动将文件导入到自身。

这是我正在调试的代码:

def update_creds(**kwargs):
    print("update_creds")

# Function header I cannot touch
def get_id(**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")

get_id()

如果你真的想知道我为什么要这样做,这个环境使用代码块来生成 Python 代码,特别是函数定义和最终的函数调用来继续执行。然而,我需要在下一个函数调用中添加一个参数,所以我使用 inspect.getsource() 来获取最终的函数调用,添加参数,然后调用它,并提前返回。

我试着追踪它是在哪里失去对正确函数的引用的,似乎是在调用 inspect.getsource() 的时候。我期待的是 'get_id' 函数的源代码,而不是 'update_creds' 函数。

在研究 getsource 的工作原理时,我想这可能和函数的名字有关,但从我能看到的,名字之间没有任何共同点。我能想到的唯一其他情况是,如果 getsource 是根据行号来引用的,而它错误地使用了一个文件的行号来引用另一个文件,但我不知道怎么强制 inspect 确保它引用的是同一个文件。

编辑:为了提供更多上下文,我在代码块中添加了更多内容。在添加上下文时,我注意到 update_creds 是在 get_id 之上的函数,所以就好像 inspect.getsource() 需要再往下一个函数定义,但我不知道这是否是偶然的,或者它是否总是会偏差一个。如果它总是偏差一个,我该如何让 getsource 给我下一个函数呢?

1 个回答

0

在你的代码中,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这个参数会被设置为'update_creds'。结果就是,get_new_return()获取的是update_creds()的源代码。

撰写回答