RestrictedPython执行用户代码报错:'_iter_unpack_sequence_'未定义,求解决
RestrictedPython配置问题与错误优化方案
一、解决'iter_unpack_sequence'未定义错误
该错误源于RestrictedPython默认未包含序列解包(如a, b = [1,2])所需的内部辅助函数,需手动将相关函数添加到安全全局变量中,同时完成允许模块、可操作变量的配置:
导入必要工具与模块
从RestrictedPython导入编译和安全内置函数,同时获取序列解包依赖的_iter_unpack_sequence_:from RestrictedPython import compile_restricted, safe_builtins from RestrictedPython.Eval import _iter_unpack_sequence_ import pandas as pd import datetime import math import random构建安全全局变量字典
整合允许的模块、可操作全局变量及必要辅助函数,同时通过safe_builtins默认禁用新模块导入:# 初始化全局变量,替换d为你的DataFrame字典 global_vars = { '__builtins__': safe_builtins, # 允许使用的模块 'pandas': pd, 'datetime': datetime, 'math': math, 'random': random, # 可操作的全局变量 'd': {}, 'x': None, # 添加序列解包及常用操作所需的辅助函数 '_iter_unpack_sequence_': _iter_unpack_sequence_, '_getitem_': lambda ob, idx: ob[idx], '_iter_': lambda ob: iter(ob), }编译并执行用户代码
使用compile_restricted编译用户代码后执行,传入构建好的安全全局变量:user_code = """ d['df1'] = pandas.DataFrame({'a': [1,2,3]}) x = math.sqrt(16) a, b = [1,2] # 序列解包操作不再报错 """ try: compiled_code = compile_restricted(user_code, '<user_code>', 'exec') exec(compiled_code, global_vars) # 可输出验证结果 print(global_vars['x'], global_vars['d']) except Exception as e: # 后续处理错误信息 pass
二、生成更具解释性的错误信息
通过捕获编译、执行阶段的异常,结合栈追踪信息提取关键错误细节,整理为用户易读的格式:
分阶段捕获并解析异常
区分语法错误、名称错误等类型,提取错误描述与行号:try: compiled_code = compile_restricted(user_code, '<user_code>', 'exec') exec(compiled_code, global_vars) except SyntaxError as e: error_msg = f"语法错误:{e.msg},行号:{e.lineno}" except NameError as e: line_no = e.__traceback__.tb_lineno error_msg = f"名称错误:{e.args[0]},行号:{line_no}" except Exception as e: # 提取运行时错误的行号与详细信息 tb = e.__traceback__ while tb.tb_next: tb = tb.tb_next line_no = tb.tb_lineno error_msg = f"执行错误:{type(e).__name__} - {e.args[0]},行号:{line_no}" print(error_msg)用traceback模块增强错误栈信息
过滤掉RestrictedPython内部栈帧,仅保留用户代码相关的错误追踪:import traceback try: compiled_code = compile_restricted(user_code, '<user_code>', 'exec') exec(compiled_code, global_vars) except Exception as e: tb_lines = traceback.format_exception(type(e), e, e.__traceback__) # 筛选用户代码相关的栈帧 user_tb_lines = [line for line in tb_lines if '<user_code>' in line] error_msg = "用户代码执行错误:\n" + ''.join(user_tb_lines if user_tb_lines else tb_lines) print(error_msg)
内容的提问来源于stack exchange,提问作者user61123
相关产品推荐
相关产品推荐

