IronPython:通过C#代码进行脚本验证

IronPython:通过C#代码进行脚本验证,python,c#,ironpython,Python,C#,Ironpython,我正在C#/.Net Core 3.1项目中使用IronPython,我需要能够在生产环境中执行脚本之前验证脚本 我发现,正在创建自定义的Microsoft.Scripting.Hosting.ErrorListener实现: public class IronPythonListener : ErrorListener { public List<ValidationError> Errors = new List<ValidationError>();

我正在C#/.Net Core 3.1项目中使用IronPython,我需要能够在生产环境中执行脚本之前验证脚本

我发现,正在创建自定义的Microsoft.Scripting.Hosting.ErrorListener实现:

public class IronPythonListener : ErrorListener
{
    public List<ValidationError> Errors = new List<ValidationError>();

    public override void ErrorReported(ScriptSource source, string message, SourceSpan span, int errorCode, Severity severity)
    {
        Errors.Add(new ValidationError
        {
            Message = message,
            ErrorCode = errorCode,
            Severity = severity,
            Span = span
        });
    }
}
listener.Errors
列表中,我找到了所有编译错误

此解决方案可行,但就我而言,它并不完整,因为例如:

  • 如果传递的脚本类似于
    my_var=5+“some text”
    listener.Errors
    为空,即使无法执行,脚本也被视为有效(事实上,它为+:“int”和“str”抛出了
    不支持的操作数类型
  • 如果传递的脚本包含对未定义函数的调用(例如
    length(my\u string)
    而不是
    len(my\u string)
    ),则认为该脚本有效
另一件对我来说似乎很奇怪的事情是,我能找到的所有错误类型都是
严重性.FatalError
(例如,传递
my_var=6+
),但我找不到任何
严重性.Error
严重性.Warning

有没有一种方法可以在不执行编译脚本的情况下改进验证

提前感谢您的帮助,不幸的是我找不到这么多关于这个的文档

编辑:我发现了一些在线验证器(例如or),它们也没有提供完整的python验证(在前一种情况下,IDE可以更好地处理验证,但是
5+“some text”
错误仅在执行时检测到)。当然,当
listener.Errors
为空时,我可以尝试执行脚本并捕获异常,但最好避免这种情况


编辑2:我也尝试过,使用一个单独的python脚本来验证我的脚本,但在未定义的函数和错误的运算符使用方面,我也遇到了同样的问题。

上面代码片段之后的
code
值是多少?@John它是一个
Microsoft.Scripting.Hosting.CompiledCode
有效对象。我已经读过
ScriptSource.Compile(ErrorListener)
在无法编译脚本时返回
null
,但事实并非如此。OK。我看到了这一点,只是想知道。:)嗨,我过去也遇到过同样的问题,我的结论是这验证了语法,但没有验证功能。我认为唯一的方法是评估代码,但这意味着运行它。所以我所做的是考虑用户足够聪明,并认为所有脚本运行是正常的。然后使用MessageBox抛出一个异常,以防出现错误。@mara6399:-)我理解你的意思。也许我错了,但我认为唯一的方法是运行代码。请记住,像v=10+a这样的值是完全有效的。这是一个源于Python语言本身设计的问题,因为它不是一种强类型语言,它允许混合和匹配所有内容。这就是为什么许多程序员讨厌它。
IronPythonListener listener = new IronPythonListener();
ScriptEngine engine = Python.CreateEngine();
ScriptSource scriptSource = engine.CreateScriptSourceFromString(script, SourceCodeKind.AutoDetect);
CompiledCode code =  scriptSource.Compile(listener);