Accesing script scope variables from modules
Question: We use IronPython in our open source project. I have problem accesing the
variables added to the script scope like

    
    
    private ScriptScope CreateScope(IDictionary<string, object> globals)
    {
        globals.Add("starting", true);
        globals.Add("stopping", false);
    
        var scope = Engine.CreateScope(globals);
        scope.ImportModule("math");
        return scope;
    }
    

<https://github.com/AndersMalmgren/FreePIE/blob/master/FreePIE.Core/ScriptEngine/Python/PythonScriptEngine.cs#L267>

I can use the globals from the main script, but any module that is loaded will
fail. How can it be fixed?

update: Given this module _mymodule.py_

    
    
    if starting: #starting is defined on the scope
       ...
    

From the main script executed using this code

    
    
    void RunLoop(string script, ScriptScope scope)
    {
        ExecuteSafe(() =>
        {
            var compiled = Engine.CreateScriptSourceFromString(script).Compile();
    
            while (!stopRequested)
            {
                usedPlugins.ForEach(p => p.DoBeforeNextExecute());
                CatchThreadAbortedException(() => compiled.Execute(scope));
                scope.SetVariable("starting", false);
                threadTimingFactory.Get().Wait();
            }
            scope.SetVariable("stopping", true);
            CatchThreadAbortedException(() => compiled.Execute(scope));
        });
    }
    

<https://github.com/AndersMalmgren/FreePIE/blob/master/FreePIE.Core/ScriptEngine/Python/PythonScriptEngine.cs#L163>

    
    
    from mymodule import * #this will load the moduel and it fails with
    

![enter image description here](http://i.stack.imgur.com/2rkWc.png)

edit: In response to @BendEg's answer

I tried this

    
    
    scope.SetVariable("__import__", new Func<CodeContext, string, PythonDictionary, PythonDictionary, PythonTuple, object>(ResolveImport));
    

`ImportDelegate` is not defined so tried using a Func instead, the
ResolveImport method never triggers and I get the same exception that the name
is not defined

edit: I changed the scope creation to

    
    
    var scope = Engine.GetBuiltinModule();
    globals.ForEach(g => scope.SetVariable(g.Key, g.Value));
    

Now the import delegate triggers but it crashes on first line with `global
name 'mouse' is not defined`, mouse is not used from the module. It seems its
confused when I add my custom globals to the `BuiltinModule`


Answer: As far as i know, importing some module will create a new scope. So when
creating an instance of `PythonModule` via `from ... import ...` they has it's
own scope. In this new scope, your public variables are not available. Please
correct me if i am wrong.

Workaround:

You could create some static class, which holdes the values. Than you can be
sure, you always have them. For example:

    
    
    namespace someNS
    {
        public static class SomeClass
        {
            public static bool Start { get; set; }
        }
    }
    

And than in your IP-Code:

    
    
    from someNS import SomeClass
    
    # Now you can access the member
    yourVal = SomeClass.Start
    

maybe this is some thing you can use. You event don't need to set it as
variable in the scope.

**EDIT**

Maybe this is working for you. In the code i override module importing and try
to set the global vars:

First thing you need is, give IronPython some delegate, for module importing:

    
    
    # Scope should be your default scope
    scope.SetVariable("__import__", new ImportDelegate(ResolveImport));
    

Then override the import function:

    
    
    private object ResolveImport(CodeContext context, string moduleName, PythonDictionary globals, PythonDictionary locals, PythonTuple fromlist)
    {
        // Do default import but set module
        var builtin = IronPython.Modules.Builtin.__import__(context, moduleName, globals, locals, fromlist, 0);
        context.ModuleContext.Module.__setattr__(context, "some_global", "Hello World");
        return builtin;
    }
    

**EDIT**

Definition of `ImportDelegate`

    
    
    delegate object ImportDelegate(CodeContext context, string moduleName, PythonDictionary globals, PythonDictionary locals, PythonTuple fromlist);
    

