You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Splunk SOAR中inspect.getsource返回错误函数源码问题求助

问题:inspect.getsource() 返回错误函数的源码(Splunk SOAR环境)

环境背景

运行在Splunk SOAR中,环境通过包装程序获取、解码并执行脚本,直接调用inspect无法正常获取源码,必须手动将文件导入自身。

问题现象

尝试获取get_id函数的源码时,eval("source.get_id")已正确指向目标函数对象,但inspect.getsource()却返回了前一个函数update_creds的源码,导致无法提取get_id中自动生成的phantom.act调用代码。

排查结论

问题源于inspect.getsource()依赖函数的__code__.co_firstlineno属性获取行号,但Splunk SOAR的包装程序导致该属性与实际文件中的行号不匹配,出现固定偏移,从而指向了前一个函数的定义位置。

解决办法

办法1:直接读取文件内容定位函数

绕过inspect的行号依赖,直接读取文件并通过函数定义行定位目标函数的源码:

def get_function_source(**kwargs):
    import re
    import sys
    import os

    sys.path.insert(0, '/scm/git/')
    # 处理文件名,去掉尖括号
    filename = re.sub(r'(<|>)','',__file__)
    file_path = os.path.join('/scm/git/', f"{filename}.py")
    
    # 读取文件所有行
    with open(file_path, 'r') as f:
        lines = f.readlines()
    
    target_func = kwargs["function"]
    func_start = None
    indent_level = None
    func_content = []

    # 遍历找到函数定义起始行
    for idx, line in enumerate(lines):
        stripped_line = line.strip()
        if stripped_line.startswith(f'def {target_func}('):
            func_start = idx
            # 记录函数定义的缩进级别
            indent_level = len(line) - len(stripped_line)
            func_content.append(line)
            break
    
    if func_start is not None:
        # 收集函数内容直到遇到同级别缩进的新函数定义
        for line in lines[func_start+1:]:
            stripped_line = line.strip()
            current_indent = len(line) - len(stripped_line)
            # 遇到同级别def就停止
            if stripped_line.startswith('def ') and current_indent == indent_level:
                break
            func_content.append(line)
    
    function_source = ''.join(func_content)
    # 提取最后一行phantom.act调用
    generated_code = re.findall(r'phantom.act\((.*)\)', function_source)[-1]
    return generated_code.replace("old_parameter", "new_parameter")

办法2:修正函数的行号属性

临时修改函数的co_firstlineno为实际文件中的行号,让inspect.getsource()能正确定位:

def get_function_source(**kwargs):
    import inspect
    import re
    import sys
    import os

    sys.path.insert(0, '/scm/git/')
    filename = re.sub(r'(<|>)','',__file__)
    source = __import__(filename)
    func = eval(f"source.{kwargs['function']}")
    file_path = os.path.join('/scm/git/', f"{filename}.py")
    
    # 找到函数在文件中的实际起始行号(inspect用1-based行号)
    with open(file_path, 'r') as f:
        lines = f.readlines()
    
    correct_firstlineno = None
    for idx, line in enumerate(lines, 1):
        if line.strip().startswith(f'def {kwargs["function"]}('):
            correct_firstlineno = idx
            break
    
    if correct_firstlineno:
        # 替换函数的co_firstlineno属性
        func.__code__ = func.__code__.replace(co_firstlineno=correct_firstlineno)
        function_source = inspect.getsource(func)
        generated_code = re.findall(r'phantom.act\((.*)\)', function_source)[-1]
        return generated_code.replace("old_parameter", "new_parameter")

内容的提问来源于stack exchange,提问作者user23530071

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 16:35:08