I'm calling an IronPython function from C#. It seems that on definition, this function captures its original scope. When I later call it without an explicit scope, it can still access values from that original scope. Even if I change scope values, it correctly reads the new values. Take a look at this example:
using IronPython.Hosting;
using IronPython.Runtime;
using IronPython.Runtime.Operations;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;
namespace IronPythonFuncTest {
class Program {
static void Main() {
ScriptEngine scriptEngine = Python.CreateEngine();
// Create scope with a global value for the script to use
ScriptScope scriptScope = scriptEngine.CreateScope();
scriptScope.SetVariable("someGlobalValue", 10);
// Execute script defining function foo(x)
string script = "def foo(): print(someGlobalValue)";
ScriptSource scriptSource = scriptEngine.
CreateScriptSourceFromString(script, SourceCodeKind.Statements);
scriptSource.Execute(scriptScope);
// Extract foo from the scope
PythonFunction foo = scriptScope.GetVariable<PythonFunction>("foo");
// Change someGlobalValue
scriptScope.SetVariable("someGlobalValue", 42);
// Call foo. This prints 42, not 10 (or nothing).
PythonCalls.Call(foo);
}
}
}
Now I'm wondering: Most overloads of PythonCalls.Call()
expect a CodeContext
object (which, if I understand correctly, mainly represents a scope). Am I losing something if I call an IronPython function like above, without passing a code context? Given that the function apparently captured its original scope on creation, there doesn't seem to be any point in passing an additional code context. Are there situations where it makes a difference whether I do?