IronPython generators' scope

Mar 9, 2011 at 4:20 PM
Edited Mar 9, 2011 at 4:24 PM

Hi,
I have problems to understand how IronPython determines the scripts' scope, especially when I use generators.

For example, if I run this code (http://pastebin.com/P24BZUJU) with IronPython 2.6.2

ScriptEngine engine = Python.CreateEngine();

string code = @"
import System
print System.Int32(5) # OK

gen = (System.Int32(i) for i in range(1,10))
for x in gen:
    print x
";

ScriptSource source = engine.CreateScriptSourceFromString(code, SourceCodeKind.AutoDetect);
CompiledCode compiledCode = source.Compile();

try
{
	compiledCode.Execute(engine.CreateScope()); // IronPython.Runtime.UnboundNameException
}
catch (System.Exception ex) 
{
	Console.WriteLine(ex.ToString());
}

try
{
	compiledCode.Execute();  // OK
}
catch (System.Exception ex)
{
	Console.WriteLine(ex.ToString());
}



In the first trycatch block I get the the following exception:

IronPython.Runtime.UnboundNameException: global name 'System' is not defined
   at IronPython.Compiler.PythonGlobal.GetCachedValue()
   at IronPython.Compiler.PythonGlobal.get_CurrentValue()
   at __generator_$1(Closure , MutableTuple )
   at IronPython.Runtime.PythonGenerator.MoveNextWorker()
   at IronPython.Runtime.PythonGenerator.System.Collections.IEnumerator.MoveNext()
   at Microsoft.Scripting.Interpreter.FuncCallInstruction`2.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.Hosting.CompiledCode.Execute(ScriptScope scope)
   ...

The second trycatch  block works fine instead.

If I run this example with IronPython 2.7 RC2, I don't get any exception.

Is this a bug, or something I am doing wrong?

Regards,

Paolo

Coordinator
Mar 9, 2011 at 4:37 PM

I'm CC'ing the IPy discussion list, but you are seeing a bug in empty scope initialization that was in 2.6.2. The expected behavior, unless I'm missing something Dino, Jeff, or Michael points out, is what you're getting with 2.7RC2. I don't recall the time window, but there was a time when Dino and I discussed the default references the ipy engine should apply to scopes.

If you had to run in 2.6.2, it might be that if you did "import clr" followed by clr.AddReference(…) and then followed by "import System", the code might work. Or, I'm wrong, and it is just the generator's closure didn't have the right context flowed into it.

Bill

From: paolomoretti [email removed]
Sent: Wednesday, March 09, 2011 9:21 AM
To: Bill Chiles
Subject: IronPython generators' scope [dlr:249060]

From: paolomoretti

Hi,
I have problems to understand how IronPython determines the scripts' scope, especially when I use generators.

For example, if I run this code (http://pastebin.com/P24BZUJU) with IronPython 2.6.2

ScriptEngine engine = Python.CreateEngine();
 
string code = @"
import System
print System.Int32(5) # OK
 
gen = (System.Int32(i) for i in range(1,10))
for x in gen:
    print x
";
 
ScriptSource source = engine.CreateScriptSourceFromString(code, SourceCodeKind.AutoDetect);
CompiledCode compiledCode = source.Compile();
 
try
{
  compiledCode.Execute(engine.CreateScope());
}
catch (System.Exception ex) // IronPython.Runtime.UnboundNameException
{
  Console.WriteLine(ex.ToString());
}
 
try
{
  compiledCode.Execute();  // OK
}
catch (System.Exception ex)
{
  Console.WriteLine(ex.ToString());
}



In the first trycatch block I get the the following exception:

IronPython.Runtime.UnboundNameException: global name 'System' is not defined
at IronPython.Compiler.PythonGlobal.GetCachedValue()
at IronPython.Compiler.PythonGlobal.get_CurrentValue()
at __generator_$1(Closure , MutableTuple )
at IronPython.Runtime.PythonGenerator.MoveNextWorker()
at IronPython.Runtime.PythonGenerator.System.Collections.IEnumerator.MoveNext()
at Microsoft.Scripting.Interpreter.FuncCallInstruction`2.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.Hosting.CompiledCode.Execute(ScriptScope scope)
...

The second trycatch block works fine instead.

If I run this example with IronPython 2.7 RC2, I don't get any exception.

Is this a bug, or something I am doing wrong?

Regards,

Paolo