Example #1
0
 public void TestCompileExpression()
 {
     using (Py.GIL())
     {
         ps.Set("bb", 100); //declare a global variable
         ps.Set("cc", 10);  //declare a local variable
         PyObject script = PythonEngine.Compile("bb + cc + 3", "", RunFlagType.Eval);
         var      result = ps.Execute <int>(script);
         Assert.AreEqual(113, result);
     }
 }
Example #2
0
        /// <summary>
        /// Load a module into a scope.
        /// </summary>
        /// <param name="name">Name to be assigned to the module</param>
        /// <param name="fileName">Name of the code file.</param>
        /// <param name="globals">Globals to be set before execution of the script.</param>
        /// <returns>PyScope with code loaded.</returns>
        private PyScope LoadModule(string name, string fileName, Dictionary <string, object> globals)
        {
            PyScope scope = null;

            using (Py.GIL())
            {
                // Create a new scope
                scope = Py.CreateScope(name);

                // Assign any globals.
                if (globals != null)
                {
                    foreach (string gname in globals.Keys)
                    {
                        scope.Set(gname, globals[gname]);
                    }
                }

                // Load python code, compile, then execute it in the scope.
                string   scriptText = File.ReadAllText(fileName);
                PyObject code       = PythonEngine.Compile(scriptText, fileName);
                dynamic  r          = scope.Execute(code);
            }
            return(scope);
        }
Example #3
0
        public static void ExecFile(this PyScope scope, string path)
        {
            if (!File.Exists(path))
            {
                throw new FileNotFoundException(path);
            }
            var txt = File.ReadAllText(path, Encoding.UTF8);

            using (Py.GIL()) {
                var script = PythonEngine.Compile(txt, new FileInfo(path).FullName, RunFlagType.File);
                scope.Execute(script)?.Dispose();
            }
        }
Example #4
0
        public void TestCreate()
        {
            using PyScope scope = Py.CreateScope();

            Assert.IsFalse(PyModule.SysModules.HasKey("testmod"));

            PyModule testmod = new PyModule("testmod");

            testmod.SetAttr("testattr1", "True".ToPython());

            PyModule.SysModules.SetItem("testmod", testmod);

            using PyObject code = PythonEngine.Compile(
                      "import testmod\n" +
                      "x = testmod.testattr1"
                      );
            scope.Execute(code);

            Assert.IsTrue(scope.TryGet("x", out dynamic x));
            Assert.AreEqual("True", x.ToString());
        }
        protected override async Task <object[]> EvaluateInternal(object[] inputs, CancellationToken cancel)
        {
            if (parserError != null)
            {
                throw parserError;
            }

            var script = this.Script;

            if (script == null)
            {
                return(new object[0]);       // no script available
            }

            object[] returnValue = null;

            void evalAction()
            {
                // create new python scope
                using (PyScope ps = Py.CreateScope())
                {
                    if (!string.IsNullOrEmpty(filename))
                    {
                        ps.Set("__file__", filename);
                    }

                    // load script into scope
                    ps.Execute(script);

                    ps.Set("context", this.Runtime.ScriptContext.ToPython());
                    ps.Set("store", this.Graph.ValueStore.ToPython());

                    // process module inputs and convert them to python objects
                    int firstArgIndex = inputs.Length - argumentPins.Count;
                    var args          = CreateArguments(inputs, firstArgIndex);

                    // call python method
                    string   functionName = (string)inputs[FUNCTION_NAME_PIN_INDEX] ?? DEFAULT_FUNCTION_NAME;
                    PyObject fn           = ps.Get(functionName);

                    PyObject pyResult = null;
                    try
                    {
                        pyResult = fn.Invoke(args);
                    }
                    catch (PythonException e)
                    {
                        throw new XamlaPythonException(e);
                    }

                    // convert result back to clr object
                    var result = PyConvert.ToClrObject(pyResult, signature.ReturnType);

                    if (result == null)
                    {
                        returnValue = new object[] { null }
                    }
                    ;
                    else if (!result.GetType().IsTuple())
                    {
                        returnValue = new object[] { result }
                    }
                    ;
                    else
                    {
                        returnValue = TypeHelpers.GetTupleValues(result);
                    }
                }
            }

            int useMainThreadPinIndex = 2;

            if (this.flowMode != FlowMode.NoFlow)
            {
                useMainThreadPinIndex += 1;
            }
            bool useMainThread = (bool)inputs[useMainThreadPinIndex];

            if (useMainThread)
            {
                await mainThread.Enqueue(evalAction, cancel);
            }
            else
            {
                using (Py.GIL())
                {
                    evalAction();
                }
            }

            if (this.flowMode != FlowMode.NoFlow)
            {
                return((new object[] { Flow.Default }.Concat(returnValue)).ToArray());
            }
            else
            {
                return(returnValue);
            }
        }
        protected virtual void UpdateSignature()
        {
            if (this.Graph == null)     // file path resolving only possible when module is attached to graph
            {
                return;
            }

            logger.LogInformation("UpdateSignature");
            lock (gate)
            {
                PySignature signature = null;

                // when there is no script available
                var src = this.GetScript();
                if (string.IsNullOrEmpty(src))
                {
                    // there are no arguments
                    signature   = new PySignature();
                    this.Script = null;
                    SetParserError(null);
                }
                else
                {
                    mainThread.RunSync(() =>
                    {
                        using (PyScope ps = Py.CreateScope())
                        {
                            PyObject script = PythonEngine.Compile(src, filename ?? "", mode);
                            ps.Execute(script);
                            signature   = PySignature.GetSignature(ps, this.FunctionName);
                            this.Script = script;
                        }
                    });

                    this.SetParserError(null);
                }

                try
                {
                    this.signature = signature;

                    // remove all argument pins that no longer exist
                    var unusedPins = argumentPins.Where(pin => !signature.HasArgument(pin.Id)).ToArray();
                    foreach (var unusedPin in unusedPins)
                    {
                        unusedPin.DisconnectAll();
                        argumentPins.Remove(unusedPin);
                        logger.LogInformation($"Removing input pin: {unusedPin.Id}");
                        inputs.Remove(unusedPin);
                    }

                    foreach (var arg in signature.Arguments)
                    {
                        var existingPin = argumentPins.FirstOrDefault(x => x.Id == arg.Name);
                        if (existingPin == null)
                        {
                            var newPin = this.AddInputPin(arg.Name, PinDataTypeFactory.FromType(arg.Type), PropertyMode.Allow);
                            argumentPins.Add(newPin);
                        }
                        else
                        {
                            // check type
                            if (existingPin.DataType.UnderlyingType != arg.Type)
                            {
                                existingPin.ChangeType(PinDataTypeFactory.FromType(arg.Type));
                            }
                        }
                    }

                    // get all pin ids which are not member of this dynamic pin collection
                    var nonDynamicPinIds = this.inputs.Where(x => !argumentPins.Contains(x)).Select(x => x.ObjectId);

                    // reorder module input pins
                    var orderedArgumentPinObjectIds = signature.Arguments.Select(x => argumentPins.First(y => y.Id == x.Name).ObjectId);
                    var newOrder = nonDynamicPinIds.Concat(orderedArgumentPinObjectIds).ToArray();
                    this.inputs.Reorder(newOrder);

                    // analyse return type of script
                    Type[] returnTypes;
                    if (signature.ReturnType == null)
                    {
                        returnTypes = new Type[0];
                    }
                    else if (TypeHelpers.IsTuple(signature.ReturnType))
                    {
                        returnTypes = TypeHelpers.GetTupleTypes(signature.ReturnType);
                    }
                    else
                    {
                        returnTypes = new Type[] { signature.ReturnType };
                    }

                    // remove pins that are not needed anymore
                    while (resultPins.Count > returnTypes.Length)
                    {
                        var last = resultPins[resultPins.Count - 1];
                        logger.LogInformation($"Removing output pin: {last.Id}");
                        last.DisconnectAll();
                        outputs.Remove(last);
                        resultPins.RemoveAt(resultPins.Count - 1);
                    }

                    for (int i = 0; i < returnTypes.Length; i++)
                    {
                        if (i < resultPins.Count)
                        {
                            var existingPin = resultPins[i];
                            if (existingPin.DataType.UnderlyingType != returnTypes[i])
                            {
                                existingPin.ChangeType(PinDataTypeFactory.FromType(returnTypes[i]));
                            }
                        }
                        else
                        {
                            var newPin = this.AddOutputPin($"output{i}", PinDataTypeFactory.FromType(returnTypes[i]));
                            resultPins.Add(newPin);
                        }
                    }
                }
                catch (Exception e)
                {
                    throw;
                }
            }
        }