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

Alex Henderson alex at syzmk.com
Sat Oct 7 05:51:24 CEST 2006


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




More information about the Ironpython-users mailing list