IronPython引发以下异常:无法将类型为Func <pythonfunction,object>的对象转换为Func <codecontext,codecontext =“”>

时间:2019-05-30 15:02:52

标签: c# ironpython

我们在软件中嵌入了IronPython,并允许用户编写和运行自己的自定义Python脚本,这些脚本在IronPython引擎中运行。 我们的一位用户遇到了以下异常情况:

Unable to cast object of type 'System.Func`2[IronPython.Runtime.PythonFunction,System.Object]' to type 'System.Func`2[IronPython.Runtime.CodeContext,IronPython.Runtime.CodeContext]'.

以下代码的第一行抛出此异常(显然还有更多代码,但这是失败的行):

class User:
    pass

堆栈跟踪如下:

at IronPython.Runtime.Operations.PythonOps.GetClassCode(CodeContext context, FunctionCode funcCode, Func`2 body)
at IronPython.Runtime.Operations.PythonOps.MakeClass(FunctionCode funcCode, Func`2 body, CodeContext parentContext, String name, Object[] bases, String selfNames)
at Microsoft.Scripting.Interpreter.FuncCallInstruction`7.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.LightLambda.Run2[T0,T1,TRet](T0 arg0, T1 arg1)
at IronPython.Compiler.PythonCallTargets.OriginalCallTarget1(PythonFunction function, Object arg0)
at IronPython.Runtime.FunctionCaller`1.Call1(CallSite site, CodeContext context, Object func, T0 arg0)
at System.Dynamic.UpdateDelegates.UpdateAndExecute3[T0,T1,T2,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2)
at Microsoft.Scripting.Interpreter.DynamicInstruction`4.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.LightLambda.Run2[T0,T1,TRet](T0 arg0, T1 arg1)
at IronPython.Compiler.PythonScriptCode.RunWorker(CodeContext ctx)
at IronPython.Compiler.PythonScriptCode.Run(Scope scope)
at IronPython.Compiler.RuntimeScriptCode.InvokeTarget(Scope scope)
at IronPython.Compiler.RuntimeScriptCode.Run(Scope scope)
at Microsoft.Scripting.SourceUnit.Execute(Scope scope, ErrorSink errorSink)
at Microsoft.Scripting.Hosting.ScriptSource.Execute(ScriptScope scope)
at Microsoft.Scripting.Hosting.ScriptEngine.Execute(String expression, ScriptScope scope)...

在IronPython.Runtime.Operations.PythonOps中尝试将funcCode.Target强制转换为Func<CodeContext, CodeContext>时,查看IronPython源代码显然失败了:

public static object MakeClass(FunctionCode funcCode, Func<CodeContext, CodeContext> body, CodeContext/*!*/ parentContext, string name, object[] bases, string selfNames) {
    Func<CodeContext, CodeContext> func = GetClassCode(parentContext, funcCode, body);

    return MakeClass(parentContext, name, bases, selfNames, func(parentContext).Dict);
}

private static Func<CodeContext, CodeContext> GetClassCode(CodeContext/*!*/ context, FunctionCode funcCode, Func<CodeContext, CodeContext> body) {
    if (body == null) {
        if (funcCode.Target == null) {
            funcCode.UpdateDelegate(context.LanguageContext, true);
        }
        return (Func<CodeContext, CodeContext>)funcCode.Target;
    } else {
        if (funcCode.Target == null) {
            funcCode.SetTarget(body);
            funcCode._normalDelegate = body;
        }
        return body;
    }
}

在我看来,这似乎是IronPython中的错误。但是我不得不承认,对于真正导致IronPython崩溃的原因,我有些犹豫。 funcCode.Target是一个委托,IronPython希望它的类型为Func<CodeContext, CodeContext>,但由于某种原因,它的类型为Func<PythonFunction, Object>。但是我不知道该委托将如何或为什么设置为其他类型的Func。

客户的代码似乎是无害的。 我无法在开发环境中重新创建异常,但是该客户经常发生这种情况。

有什么我可以尝试的方法吗?还是我应该向IronPython员工提出这个错误。如果是这样,我该如何向IronPython员工提出错误?

我还应该提到这是IronPython2,而不是3。

1 个答案:

答案 0 :(得分:0)

这是IronPython中的错误。

首先可以在我们的软件中复制错误,然后在simple console app中进行复制。我reported the bug加入IronPython团队。