[IronPython] Limitations of PythonEngine.CreateMethod<TDelegate>?

Dino Viehland dinov at exchange.microsoft.com
Tue Oct 10 02:09:48 CEST 2006


Thanks for the report - this sounds like a bug.  I suspect we're not creating the function w/ the proper environment in this case, but I haven't had a chance to investigate.  I've opened CodePlex bug #4196 for this.

-----Original Message-----
From: users-bounces at lists.ironpython.com [mailto:users-bounces at lists.ironpython.com] On Behalf Of Alex Henderson
Sent: Friday, October 06, 2006 8:51 PM
To: users at lists.ironpython.com
Subject: [IronPython] Limitations of PythonEngine.CreateMethod<TDelegate>?

Hi All,

I've been playing with the PythonEngine's CreateMethod<TDelegate>(..) and declaring functions within the body of another function - however it doesn't seem to work, for example I can writin a function like this:

def ExternalFunc():
        def InnerFunc1():
                def InnerFunc2():
                        return "2"
                return "1" + InnerFunc2()
        return "0" + InnerFunc1()

and then evaluate it...

>>> ExternalFunc()
'012'
>>>

But when I try to create a delegate for doing the same thing by shedding the outer "layer" of the function, and creating it as a method via the PythonEngine it doesn't work:

PythonEngine = new PythonEngine()
// some more setup code would go here...
Func<string> externalFunc = engine.CreateMethod<Func<string>>(@"def
InnerFunc1():
    def InnerFunc2():
        return ""2""
    return ""1"" + InnerFunc2()
return ""0"" + InnerFunc1()");

The call to CreateMethod spits the dummy, with a NullReferenceException...
here's the stack trace

failed: System.NullReferenceException : Object reference not set to an instance of an object.
        at IronPython.Compiler.Generation.CodeGen.DefineDynamicMethod(String
name, Type retType, Type[] paramTypes)
        at IronPython.Compiler.Generation.CodeGen.DefineMethod(String name, Type retType, Type[] paramTypes, SymbolId[] paramNames)
        at IronPython.Compiler.Ast.FunctionDefinition.Emit(CodeGen cg)
        at IronPython.Compiler.Ast.SuiteStatement.Emit(CodeGen cg)
        at
IronPython.Compiler.Ast.FunctionDefinition.EmitFunctionBody(CodeGen cg, CodeGen ocg)
        at
IronPython.Compiler.Ast.FunctionDefinition.EmitFunctionImplementation(CodeGe
n methodCodeGen, CodeGen initCodeGen)
        at
IronPython.Hosting.PythonEngine.CreateDelegateWorker[TDelegate](Statement s,
IList`1 parameters)
        at
IronPython.Hosting.PythonEngine.CreateMethodUnscoped[TDelegate](String
statements, IList`1 parameters)
        at IronPython.Hosting.PythonEngine.CreateMethod[TDelegate](String
statements, IList`1 parameters, EngineModule engineModule)
        at IronPython.Hosting.PythonEngine.CreateMethod[TDelegate](String
statements)

Am I overlooking something in my code, or is this just a limitation of using CreateMethod<TDelegate> to get a delegate to an anonymous python function?

For the mean time I'm just working around it by doing this:

engine.Execute(@"def ExternalFunc():
    def InnerFunc1():
        def InnerFunc2():
            return ""2""
        return ""1"" + InnerFunc2()
    return ""0"" + InnerFunc1()");

PythonFunction func = _engine.EvaluateAs<PythonFunction>("ExternalFunc");

Func<string> funcDel = delegate { return (string)func.Call(); };

Which gets me a suitable delegate, but it's not really the same as I end up having to declare the function as part of a module, which I was trying to avoid...

Chez,

 - Alex

_______________________________________________
users mailing list
users at lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com



More information about the Ironpython-users mailing list