/// <summary> /// This is more of a formality since the injected module loader already has the module loaded, but this gives us conformity with /// the module importing system. /// </summary> /// <param name="spec">The module spec we will load.</param> /// <returns>The loaded asset... which might be a PyModule wrapper if this is a namespace. Otherwise, the asset itself.</returns> public async Task <object> Load(IInterpreter interpreter, FrameContext context, PyModuleSpec spec) { // Don't get too fixated on this being a module at the end of the day. var module = PyModule.Create(spec.Name); var clrContext = (ClrContext)spec.LoaderState; // TODO: [CLR - OPTIMIZE GETATTR] Create a .NET PyModule interface overridding __getattr__ to do these lookups instead of stuffing the // module with everything. Tackle that once this has settled down a bit and we know exactly what we're trying to do. // Some LINQ magic could probably do this but I think I want to be able to step through it. bool foundAny = false; foreach (var assembly in clrContext.AddedReferences) { foreach (var type in assembly.GetTypes()) { if (type.Namespace == spec.Name) { // TODO: [DISAMBIGUATE GENERIC IMPORTS] Replace clr generic type import with a more robust system that can manage Type<T> and Type<T, K> // As it stands, they will collide here since we're removing the `# designator at the end. It would normally be: // Type<T> -> Type`1 // Type<T, K> -> Type`2 // // But we're collapsing them into just "Type" var collapsedName = type.Name; var genericParamQualifierIdx = collapsedName.IndexOf("`"); if (genericParamQualifierIdx >= 0) { collapsedName = collapsedName.Substring(0, genericParamQualifierIdx); } if (!module.__dict__.ContainsKey(collapsedName)) { foundAny = true; module.__dict__.Add(collapsedName, type); } } } } // Maybe it's not a namespace! if (!foundAny) { foreach (var assembly in clrContext.AddedReferences) { foreach (var type in assembly.GetTypes()) { if (type.Name == spec.Name) { return(type); } } } } return(module); }
/// <summary> /// Intended to be called once by the Cloaca interpreter to create the clr module in an injectable /// module loader. /// </summary> /// <returns></returns> public static PyModule CreateClrModule() { var internals = new ClrModuleInternals(); var module = PyModule.Create("clr"); var addReference = new WrappedCodeObject("AddReference", internals.GetType().GetMethod("EmbeddedAddReference"), internals); module.__dict__.Add("AddReference", addReference); module.__dict__.Add("References", internals.references); return(module); }
public async Task RootLevel() { var repo = new InjectedModuleRepository(); var fooModule = PyModule.Create("foo"); repo.AddNewModuleRoot(fooModule); var fooSpec = repo.find_spec(null, "foo", null, null); Assert.That(fooSpec, Is.Not.Null); var fooLoaded = await fooSpec.Loader.Load(null, null, fooSpec); Assert.That(fooLoaded, Is.EqualTo(fooModule)); }
/// <summary> /// This is more of a formality since the injected module loader already has the module loaded, but this gives us conformity with /// the module importing system. /// </summary> /// <param name="spec">The module spec we will load.</param> /// <returns>The loaded asset... which might be a PyModule wrapper if this is a namespace. Otherwise, the asset itself.</returns> public async Task <object> Load(IInterpreter interpreter, FrameContext context, PyModuleSpec spec) { // Don't get too fixated on this being a module at the end of the day. var module = PyModule.Create(spec.Name); var clrContext = (ClrContext)spec.LoaderState; // TODO: [CLR - OPTIMIZE GETATTR] Create a .NET PyModule interface overridding __getattr__ to do these lookups instead of stuffing the // module with everything. Tackle that once this has settled down a bit and we know exactly what we're trying to do. // Some LINQ magic could probably do this but I think I want to be able to step through it. bool foundAny = false; foreach (var assembly in clrContext.AddedReferences) { foreach (var type in assembly.GetTypes()) { if (type.Namespace == spec.Name) { if (!module.__dict__.ContainsKey(type.Name)) { foundAny = true; module.__dict__.Add(type.Name, type); } } } } // Maybe it's not a namespace! if (!foundAny) { foreach (var assembly in clrContext.AddedReferences) { foreach (var type in assembly.GetTypes()) { if (type.Name == spec.Name) { return(type); } } } } return(module); }
public void setupFinders() { var repo = new InjectedModuleRepository(); fooModule = PyModule.Create("foo"); barModule = PyModule.Create("bar"); fooThing = PyString.Create("FooThing"); otherThing = PyString.Create("OtherThing"); fooModule.__dict__.Add("bar", barModule); fooModule.__dict__.Add("FooThing", fooThing); fooModule.__dict__.Add("OtherThing", otherThing); foo2Module = PyModule.Create("foo2"); repo.AddNewModuleRoot(fooModule); repo.AddNewModuleRoot(foo2Module); moduleFinders = new List <ISpecFinder>(); moduleFinders.Add(repo); }
public PyModule CreateModule() { var sysHandle = PyModule.Create("sys"); var schedulerHandle = PyModule.Create("scheduler"); var me = this.GetType(); var getActive = new WrappedCodeObject("get_active", me.GetMethod("getTasksActive"), this); var getBlocked = new WrappedCodeObject("get_blocked", me.GetMethod("getTasksBlocked"), this); var getUnblocked = new WrappedCodeObject("get_unblocked", me.GetMethod("getTasksUnblocked"), this); var getYielded = new WrappedCodeObject("get_yielded", me.GetMethod("getTasksYielded"), this); var schedule = new WrappedCodeObject("schedule", me.GetMethod("schedule"), this); schedulerHandle.__dict__.Add(getActive.Name, getActive); schedulerHandle.__dict__.Add(getBlocked.Name, getBlocked); schedulerHandle.__dict__.Add(getUnblocked.Name, getUnblocked); schedulerHandle.__dict__.Add(getYielded.Name, getYielded); schedulerHandle.__dict__.Add(schedule.Name, schedule); sysHandle.__dict__.Add("scheduler", schedulerHandle); return(sysHandle); }
public async Task SecondLevelNonModule() { // Exception should be something like: // ModuleNotFoundError: No module named 'foo.bar.barstring'; 'foo.bar.barstring' is not a package // They would be forced to use the "from foo.bar import barstring" var repo = new InjectedModuleRepository(); var fooModule = PyModule.Create("foo"); var barModule = PyModule.Create("bar"); var barString = PyString.Create("bar string"); barModule.__dict__.Add("barstring", barString); fooModule.__dict__.Add("bar", barModule); repo.AddNewModuleRoot(fooModule); var barStringSpec = repo.find_spec(null, "foo.bar.barstring", null, null); Assert.That(barStringSpec, Is.Not.Null); var barStringLoaded = await barStringSpec.Loader.Load(null, null, barStringSpec); Assert.That(barStringLoaded, Is.EqualTo(barString)); }
public async Task SecondLevel() { var repo = new InjectedModuleRepository(); var fooModule = PyModule.Create("foo"); var barModule = PyModule.Create("bar"); fooModule.__dict__.Add("bar", barModule); repo.AddNewModuleRoot(fooModule); var fooSpec = repo.find_spec(null, "foo", null, null); var barSpec = repo.find_spec(null, "foo.bar", null, null); Assert.That(fooSpec, Is.Not.Null); Assert.That(barSpec, Is.Not.Null); var fooLoaded = await fooSpec.Loader.Load(null, null, fooSpec); var barLoaded = await barSpec.Loader.Load(null, null, barSpec); Assert.That(fooLoaded, Is.EqualTo(fooModule)); Assert.That(barLoaded, Is.EqualTo(barModule)); }
public async Task <object> Load(IInterpreter interpreter, FrameContext context, PyModuleSpec spec) { var foundPath = (string)spec.LoaderState; var inFile = File.ReadAllText(foundPath); var moduleCode = ByteCodeCompiler.Compile(inFile, new Dictionary <string, object>()); await interpreter.CallInto(context, moduleCode, new object[0]); if (context.EscapedDotNetException != null) { throw context.EscapedDotNetException; } var moduleFrame = context.callStack.Pop(); var module = PyModule.Create(spec.Name); for (int local_i = 0; local_i < moduleFrame.LocalNames.Count; ++local_i) { module.__setattr__(moduleFrame.LocalNames[local_i], moduleFrame.Locals[local_i]); } return(module); }