Пример #1
0
        /// <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);
        }
Пример #2
0
        /// <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);
        }
Пример #3
0
        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));
        }
Пример #4
0
        /// <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);
        }
Пример #5
0
        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);
        }
Пример #6
0
        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);
        }
Пример #7
0
        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));
        }
Пример #8
0
        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));
        }
Пример #9
0
        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);
        }