我有一个Python脚本,该脚本读取一些输入,生成python脚本,然后运行生成的脚本。我想要的是,如果生成的脚本中有错误,则会在输入文件的文件/行号而不是生成的脚本中报告错误。
如果python在C或perl中支持#line指令,则只需将它们放在生成的脚本中,这就是我所需要的。看起来好像不支持。
我尝试将生成的脚本放在try块中,以期我可以捕获异常并使用traceback模块调整堆栈跟踪的打印方式。问题在于,最常见的错误类型是解析错误,并且这些错误似乎发生并在我的控制范围之外报告(即,在尝试之前引发了异常,因此从未调用我的异常处理程序)。
我能想到的最好的选择是在生成的脚本上使用compile(),然后尝试捕获错误。看起来这将迫使我将整个生成的脚本当作字符串(可能很大)。另外,我真正想要的是能够在自己的沙箱中运行生成的脚本,因此它完全不受调用脚本的影响(如果不是出于错误报告的目的,我会将该脚本作为一个新的python进程来调用)。如果我使用compile / exec,那对我来说还不清楚。会为exec()的globals参数传递一个空字典会达到目的吗?
有没有更好的方法来做这种事情?
编辑:
生成的脚本几乎可以是任何东西。输入文件允许用户在生成的脚本中插入任意python代码。我想做的是生成一个脚本,如:
temp.py:
#line 10 original_file
for i in range(0,3)::
并且在“ original_file”的第10行而不是temp.py的第2行报告了语法错误(这对用户没有任何意义)。
到目前为止,我最好的方法是在生成的脚本中插入#line指令,并让原始脚本(即生成temp.py的脚本)执行生成的脚本,如下所示:
import runpy
try:
runpy.run_path(generated_file)
except:
print_stack_trace(traceback.format_exc(), generated_file)
“ print_stack_trace()”函数解析回溯并使用#line指令将其转换回原始源。
这对于简单的情况似乎还可以,但是我不确定在运行生成器脚本的同一Python中运行生成的脚本(其内容是任意的)的含义。