Custom IronPython import resolution

前端 未结 4 1226
温柔的废话
温柔的废话 2020-12-09 06:02

I am loading an IronPython script from a database and executing it. This works fine for simple scripts, but imports are a problem. How can I intercept these import calls a

4条回答
  •  隐瞒了意图╮
    2020-12-09 06:55

    After a great deal of trial and error, I arrived at a solution. I never managed to get the PlatformAdaptationLayer approach to work correctly. It never called back to the PAL when attempting to load the modules.

    So what I decided to do was replace the built-in import function by using the SetVariable method as shown below (Engine and Scope are protected members exposing the ScriptEngine and ScriptScope for the parent script):

    delegate object ImportDelegate(CodeContext context, string moduleName, PythonDictionary globals, PythonDictionary locals, PythonTuple tuple);
    
    protected void OverrideImport()
    {
        ScriptScope scope = IronPython.Hosting.Python.GetBuiltinModule(Engine);
        scope.SetVariable("__import__", new ImportDelegate(DoDatabaseImport));
    }
    
    protected object DoDatabaseImport(CodeContext context, string moduleName, PythonDictionary globals, PythonDictionary locals, PythonTuple tuple)
    {
        if (ScriptExistsInDb(moduleName))
        {
            string rawScript = GetScriptFromDb(moduleName);
            ScriptSource source = Engine.CreateScriptSourceFromString(rawScript);
            ScriptScope scope = Engine.CreateScope();
            Engine.Execute(rawScript, scope);
            Microsoft.Scripting.Runtime.Scope ret = Microsoft.Scripting.Hosting.Providers.HostingHelpers.GetScope(scope);
            Scope.SetVariable(moduleName, ret);
            return ret;
         }
         else
         {   // fall back on the built-in method
             return IronPython.Modules.Builtin.__import__(context, moduleName);
         }
    }
    

    Hope this helps someone!

提交回复
热议问题