Tuesday, 6 October 2020

IronPython: script validation via C# code

I'm working with IronPython in a C#/.Net Core 3.1 project and I need to be able to validate a script before executing it in a production environment.

I have found this solution, creating my custom Microsoft.Scripting.Hosting.ErrorListener implementation:

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
        });
    }
}

and then passing an instance of it to the Microsoft.Scripting.Hosting.ScriptSource.Compile(ErrorListener) method:

IronPythonListener listener = new IronPythonListener();
ScriptEngine engine = Python.CreateEngine();
ScriptSource scriptSource = engine.CreateScriptSourceFromString(script, SourceCodeKind.AutoDetect);
CompiledCode code =  scriptSource.Compile(listener);

In listener.Errors list I find all the compilation errors.

This solution works, but for my purposes it is not complete, because for example:

  • if the passed script is something like my_var = 5 + "some text", listener.Errors is empty and the script is considered valid even though it cannot be executed (in fact, it throws a unsupported operand type(s) for +: 'int' and 'str' exception)
  • if the passed script contains calls to undefined functions (e.g. length(my_string) instead of len(my_string)), it is considered valid

Another thing that seems strange to me is that all the errors I can find are of type Severity.FatalError (e.g. passing my_var = 6 +), but I'm not able to find any Severity.Error or Severity.Warning.

Is there a way to improve the validation, without executing my compiled script?

Thanks in advance for any help, unfortunately I cannot find so much documentation about this.

Edit: I found some online validators (e.g. https://repl.it/languages/python3 or http://pep8online.com/) and they also don't provide a complete python validation (in the former one, validation is handled better by the IDE, but the 5 + "some text" error is detected only at execution time). Of course I can try to execute the script and catch the exception when listener.Errors is empty, but it would be better to avoid this.

Edit 2: I tried also this solution, using a separated python script to validate mine, but I have the same issues with undefined functions and wrong operators usage.



from IronPython: script validation via C# code

No comments:

Post a Comment