Reputation:
I am trying to override the default __import__ method provided by IronPython to handle database imports. I have already run through the example provided here: https://stackoverflow.com/a/4127766/862319
Everything is working so far, but there is a minor issue related to namespace resolution within CLR types. I am able to import using the syntax import ClrAssembly.Type
but the syntax from ClrAssembly import Type
does not work. This is a minor inconvenience, but I would like to get it resolved. My suspicion is that there are two method signatures tied to the __import__method in IronPython:
But, the SO link above results in only a single method being applied with the 5 parameter signature. Here is the __import__ variable after being set:
How would I go about constructing a custom IronPython.Runtime.Types.BuiltinFunction
that maps to 2 method signatures (5 param and 2 param version of DoDatabaseImport) and assign it back to the __import__ variable?
Upvotes: 4
Views: 755
Reputation: 70
Hopefully this answer helps someone who is looking at this old question.
Looking at the source for IronPython 2.7.7 specifically the builtin.cs file from https://github.com/IronLanguages/main/blob/3d9c336e1b6f0a86914a89ece171a22f48b0cc6e/Languages/IronPython/IronPython/Modules/Builtin.cs
you can see that the 2 parameter function calls the 5 parameter overload with default values.
public static object __import__(CodeContext/*!*/ context, string name) {
return __import__(context, name, null, null, null, -1);
}
To replicate this I used a delegate with similar default values.
delegate object ImportDelegate(CodeContext context, string moduleName, object globals = null, object locals = null, object fromlist = null, int level = -1);
protected object ImportOverride(CodeContext context, string moduleName, object globals = null, object locals = null, object fromlist = null, int level = -1)
{
// do custom import logic here
return IronPython.Modules.Builtin.__import__(context, moduleName, globals, locals, fromlist, level);
}
Overriding the builtin import function is shown below
private ScriptEngine pyengine;
private ScriptingEngine()
{
Dictionary<string, object> options = new Dictionary<string, object>();
options["Debug"] = true;
pyengine = Python.CreateEngine(options);
var builtinscope = Python.GetBuiltinModule(pyengine);
builtinscope.SetVariable("__import__", new ImportDelegate(ImportOverride));
}
Upvotes: 2
Reputation: 21088
I had the same problem. My solution was, to search for all clr types and store them in a HashSet
. If IronPython tries to import some thing from the clr, i ingored my own set of rules and called the built-in importer from IronPython. This is working pretty well for a while now.
Hope this helps.
Upvotes: 0