private object ExecutePythonScriptCode(string code) { Python.Included.Installer.SetupPython().Wait(); if (!PythonEngine.IsInitialized) { PythonEngine.Initialize(); PythonEngine.BeginAllowThreads(); } using (Py.GIL()) { var result = Scope.Eval(code); return(CPythonEvaluator.OutputMarshaler.Marshal(result)); } }
public void Dispose() { if (Scope != null) { if (!PythonEngine.IsInitialized) { PythonEngine.Initialize(); PythonEngine.BeginAllowThreads(); } try { using (Py.GIL()) { Scope.Dispose(); } } catch {} } }
internal virtual IntPtr Invoke(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info, MethodInfo[] methodinfo) { Binding binding = this.Bind(inst, args, kw, info, methodinfo); Object result; IntPtr ts = IntPtr.Zero; if (binding == null) { Exceptions.SetError(Exceptions.TypeError, "No method matches given arguments" ); return(IntPtr.Zero); } if (allow_threads) { ts = PythonEngine.BeginAllowThreads(); } try { result = binding.info.Invoke(binding.inst, BindingFlags.Default, null, binding.args, null); } catch (Exception e) { if (e.InnerException != null) { e = e.InnerException; } if (allow_threads) { PythonEngine.EndAllowThreads(ts); } Exceptions.SetError(e); return(IntPtr.Zero); } if (allow_threads) { PythonEngine.EndAllowThreads(ts); } // If there are out parameters, we return a tuple containing // the result followed by the out parameters. If there is only // one out parameter and the return type of the method is void, // we return the out parameter as the result to Python (for // code compatibility with ironpython). MethodInfo mi = (MethodInfo)binding.info; if ((binding.outs == 1) && (mi.ReturnType == typeof(void))) { } if (binding.outs > 0) { ParameterInfo[] pi = mi.GetParameters(); int c = pi.Length; int n = 0; IntPtr t = Runtime.PyTuple_New(binding.outs + 1); IntPtr v = Converter.ToPython(result, mi.ReturnType); Runtime.PyTuple_SetItem(t, n, v); n++; for (int i = 0; i < c; i++) { Type pt = pi[i].ParameterType; if (pi[i].IsOut || pt.IsByRef) { v = Converter.ToPython(binding.args[i], pt); Runtime.PyTuple_SetItem(t, n, v); n++; } } if ((binding.outs == 1) && (mi.ReturnType == typeof(void))) { v = Runtime.PyTuple_GetItem(t, 1); Runtime.Incref(v); Runtime.Decref(t); return(v); } return(t); } return(Converter.ToPython(result, mi.ReturnType)); }
internal virtual IntPtr Invoke(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info, MethodInfo[] methodinfo) { // No valid methods, nothing to bind. if (GetMethods().Length == 0) { var msg = new StringBuilder("The underlying C# method(s) have been deleted"); if (list.Count > 0 && list[0].Name != null) { msg.Append($": {list[0].ToString()}"); } return(Exceptions.RaiseTypeError(msg.ToString()));; } Binding binding = Bind(inst, args, kw, info, methodinfo); object result; IntPtr ts = IntPtr.Zero; if (binding == null) { var value = new StringBuilder("No method matches given arguments"); if (methodinfo != null && methodinfo.Length > 0) { value.Append($" for {methodinfo[0].Name}"); } value.Append(": "); AppendArgumentTypes(to: value, args); Exceptions.SetError(Exceptions.TypeError, value.ToString()); return(IntPtr.Zero); } if (allow_threads) { ts = PythonEngine.BeginAllowThreads(); } try { result = binding.info.Invoke(binding.inst, BindingFlags.Default, null, binding.args, null); } catch (Exception e) { if (e.InnerException != null) { e = e.InnerException; } if (allow_threads) { PythonEngine.EndAllowThreads(ts); } Exceptions.SetError(e); return(IntPtr.Zero); } if (allow_threads) { PythonEngine.EndAllowThreads(ts); } // If there are out parameters, we return a tuple containing // the result followed by the out parameters. If there is only // one out parameter and the return type of the method is void, // we return the out parameter as the result to Python (for // code compatibility with ironpython). var mi = (MethodInfo)binding.info; if (binding.outs == 1 && mi.ReturnType == typeof(void)) { } if (binding.outs > 0) { ParameterInfo[] pi = mi.GetParameters(); int c = pi.Length; var n = 0; IntPtr t = Runtime.PyTuple_New(binding.outs + 1); IntPtr v = Converter.ToPython(result, mi.ReturnType); Runtime.PyTuple_SetItem(t, n, v); n++; for (var i = 0; i < c; i++) { Type pt = pi[i].ParameterType; if (pi[i].IsOut || pt.IsByRef) { v = Converter.ToPython(binding.args[i], pt.GetElementType()); Runtime.PyTuple_SetItem(t, n, v); n++; } } if (binding.outs == 1 && mi.ReturnType == typeof(void)) { v = Runtime.PyTuple_GetItem(t, 1); Runtime.XIncref(v); Runtime.XDecref(t); return(v); } return(t); } return(Converter.ToPython(result, mi.ReturnType)); }
public DSCPythonCodeCompletionProviderCore() { VariableTypes = new Dictionary <string, Type>(); ImportedTypes = new Dictionary <string, Type>(); ClrModules = new HashSet <string>(); BadStatements = new Dictionary <string, int>(); Guid pythonScopeGUID = Guid.NewGuid(); uniquePythonScopeName += pythonScopeGUID.ToString(); // Special case for python variables defined as null ImportedTypes["None"] = null; BasicVariableTypes = new List <Tuple <Regex, Type> >(); BasicVariableTypes.Add(Tuple.Create(STRING_VARIABLE, typeof(PyString))); BasicVariableTypes.Add(Tuple.Create(DOUBLE_VARIABLE, typeof(PyFloat))); BasicVariableTypes.Add(Tuple.Create(INT_VARIABLE, typeof(PyInt))); BasicVariableTypes.Add(Tuple.Create(LIST_VARIABLE, typeof(PyList))); BasicVariableTypes.Add(Tuple.Create(DICT_VARIABLE, typeof(PyDict))); if (!PythonEngine.IsInitialized) { PythonEngine.Initialize(); PythonEngine.BeginAllowThreads(); } try { using (Py.GIL()) { if (GlobalScope == null) { GlobalScope = CreateGlobalScope(); } if (Scope == null) { Scope = CreateUniquePythonScope(); } var assemblies = AppDomain.CurrentDomain.GetAssemblies(); // Determine if the Revit API is available in the given context if (assemblies.Any(x => x.GetName().Name == "RevitAPI")) { // Try to load Revit Type for autocomplete try { var revitImports = "import clr\nclr.AddReference('RevitAPI')\nclr.AddReference('RevitAPIUI')\nfrom Autodesk.Revit.DB import *\nimport Autodesk\n"; Scope.Exec(revitImports); ClrModules.Add("RevitAPI"); ClrModules.Add("RevitAPIUI"); } catch { Log("Failed to load Revit types for autocomplete. Python autocomplete will not see Autodesk namespace types."); } } // Determine if the ProtoGeometry is available in the given context if (assemblies.Any(x => x.GetName().Name == "ProtoGeometry")) { // Try to load ProtoGeometry Type for autocomplete try { var libGImports = "import clr\nclr.AddReference('ProtoGeometry')\nfrom Autodesk.DesignScript.Geometry import *\n"; Scope.Exec(libGImports); ClrModules.Add("ProtoGeometry"); } catch (Exception e) { Log(e.ToString()); Log("Failed to load ProtoGeometry types for autocomplete. Python autocomplete will not see Autodesk namespace types."); } } // PythonNet evaluates basic types as Python native types: // Ex: a = "" // type(a) will have the value {class str} and not the clr System.String // // Populate the basic types after python is initialized // These instance types will correspond to Python basic types (no clr) // ex. PyString("") => Python's {class str} // PyInt(0) => Python's {class int} basicPyObjects = new Dictionary <Type, PyObject>(); basicPyObjects[typeof(PyString)] = new PyString(""); basicPyObjects[typeof(PyFloat)] = new PyFloat(0); basicPyObjects[typeof(PyInt)] = new PyInt(0); basicPyObjects[typeof(PyList)] = new PyList(); basicPyObjects[typeof(PyDict)] = new PyDict(); } } catch {} }
/// <summary> /// Generate completion data for the specified text, while import the given types into the /// scope and discovering variable assignments. /// </summary> /// <param name="code">The code to parse</param> /// <param name="expand">Determines if the entire namespace should be used</param> /// <returns>Return a list of IExternalCodeCompletionData </returns> public override IExternalCodeCompletionData[] GetCompletionData(string code, bool expand = false) { IEnumerable <PythonCodeCompletionDataCore> items = new List <PythonCodeCompletionDataCore>(); if (!PythonEngine.IsInitialized) { PythonEngine.Initialize(); PythonEngine.BeginAllowThreads(); } try { using (Py.GIL()) { if (code.Contains("\"\"\"")) { code = StripDocStrings(code); } UpdateImportedTypes(code); UpdateVariableTypes(code); // Possibly use hindley-milner in the future // If expand param is true use the entire namespace from the line of code // Else just return the last name of the namespace string name = expand ? GetLastNameSpace(code) : GetLastName(code); if (!String.IsNullOrEmpty(name)) { try { // Attempt to get type using naming Type type = expand ? TryGetTypeFromFullName(name) : TryGetType(name); // CLR type if (type != null) { items = EnumerateMembers(type, name).Select(x => new PythonCodeCompletionDataCore(x.Item1, x.Item2, x.Item3, x.Item4, this)); } // Variable assignment types else if (VariableTypes.TryGetValue(name, out type)) { if (basicPyObjects.TryGetValue(type, out PyObject basicObj)) { items = EnumerateMembers(basicObj, name).Select(x => new PythonCodeCompletionDataCore(x.Item1, x.Item2, x.Item3, x.Item4, this)); } else { items = EnumerateMembers(type, name).Select(x => new PythonCodeCompletionDataCore(x.Item1, x.Item2, x.Item3, x.Item4, this)); } } else { // Try to find the corresponding PyObject from the python environment // Most types should be successfully retrieved at this stage var pyObj = LookupObject(name); if (pyObj != null) { items = EnumerateMembers(pyObj, name).Select(x => new PythonCodeCompletionDataCore(x.Item1, x.Item2, x.Item3, x.Item4, this)); } } } catch (Exception ex) { Log(ex.ToString()); } } } } catch {} // If unable to find matching results and expand was set to false, // try again using the full namespace (set expand to true) if (!items.Any() && !expand) { return(GetCompletionData(code, true)); } return(items.ToArray()); }
internal virtual IntPtr Invoke(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info, MethodInfo[] methodinfo) { Binding binding = Bind(inst, args, kw, info, methodinfo); object result; IntPtr ts = IntPtr.Zero; if (binding == null) { var value = new StringBuilder("No method matches given arguments"); if (methodinfo != null && methodinfo.Length > 0) { value.Append($" for {methodinfo[0].Name}"); } long argCount = Runtime.PyTuple_Size(args); value.Append(": ("); for (long argIndex = 0; argIndex < argCount; argIndex++) { var arg = Runtime.PyTuple_GetItem(args, argIndex); if (arg != IntPtr.Zero) { var type = Runtime.PyObject_Type(arg); if (type != IntPtr.Zero) { try { var description = Runtime.PyObject_Unicode(type); if (description != IntPtr.Zero) { value.Append(Runtime.GetManagedString(description)); Runtime.XDecref(description); } } finally { Runtime.XDecref(type); } } } if (argIndex + 1 < argCount) { value.Append(", "); } } value.Append(')'); Exceptions.SetError(Exceptions.TypeError, value.ToString()); return(IntPtr.Zero); } if (allow_threads) { ts = PythonEngine.BeginAllowThreads(); } try { result = binding.info.Invoke(binding.inst, BindingFlags.Default, null, binding.args, null); } catch (Exception e) { if (e.InnerException != null) { e = e.InnerException; } if (allow_threads) { PythonEngine.EndAllowThreads(ts); } Exceptions.SetError(e); return(IntPtr.Zero); } if (allow_threads) { PythonEngine.EndAllowThreads(ts); } // If there are out parameters, we return a tuple containing // the result followed by the out parameters. If there is only // one out parameter and the return type of the method is void, // we return the out parameter as the result to Python (for // code compatibility with ironpython). var mi = (MethodInfo)binding.info; if (binding.outs == 1 && mi.ReturnType == typeof(void)) { } if (binding.outs > 0) { ParameterInfo[] pi = mi.GetParameters(); int c = pi.Length; var n = 0; IntPtr t = Runtime.PyTuple_New(binding.outs + 1); IntPtr v = Converter.ToPython(result, mi.ReturnType); Runtime.PyTuple_SetItem(t, n, v); n++; for (var i = 0; i < c; i++) { Type pt = pi[i].ParameterType; if (pi[i].IsOut || pt.IsByRef) { v = Converter.ToPython(binding.args[i], pt); Runtime.PyTuple_SetItem(t, n, v); n++; } } if (binding.outs == 1 && mi.ReturnType == typeof(void)) { v = Runtime.PyTuple_GetItem(t, 1); Runtime.XIncref(v); Runtime.XDecref(t); return(v); } return(t); } return(Converter.ToPython(result, mi.ReturnType)); }
/// <summary> /// Descriptor __set__ implementation. This method sets the value of /// a property based on the given Python value. The Python value must /// be convertible to the type of the property. /// </summary> public new static int tp_descr_set(IntPtr ds, IntPtr ob, IntPtr val) { var self = (PropertyObject)GetManagedObject(ds); MethodInfo setter = self.setter; object newval; IntPtr ts = IntPtr.Zero; if (val == IntPtr.Zero) { Exceptions.RaiseTypeError("cannot delete property"); return(-1); } if (setter == null) { Exceptions.RaiseTypeError("property is read-only"); return(-1); } if (!Converter.ToManaged(val, self.info.PropertyType, out newval, true)) { return(-1); } bool is_static = setter.IsStatic; if (ob == IntPtr.Zero || ob == Runtime.PyNone) { if (!is_static) { Exceptions.RaiseTypeError("instance property must be set on an instance"); return(-1); } } try { if (!is_static) { var co = GetManagedObject(ob) as CLRObject; if (co == null) { Exceptions.RaiseTypeError("invalid target"); return(-1); } ts = PythonEngine.BeginAllowThreads(); self.info.SetValue(co.inst, newval, null); } else { ts = PythonEngine.BeginAllowThreads(); self.info.SetValue(null, newval, null); } PythonEngine.EndAllowThreads(ts); return(0); } catch (Exception e) { if (e.InnerException != null) { e = e.InnerException; } if (IntPtr.Zero != ts) { PythonEngine.EndAllowThreads(ts); } Exceptions.SetError(e); return(-1); } }
/// <summary> /// Descriptor __get__ implementation. This method returns the /// value of the property on the given object. The returned value /// is converted to an appropriately typed Python object. /// </summary> public static IntPtr tp_descr_get(IntPtr ds, IntPtr ob, IntPtr tp) { var self = (PropertyObject)GetManagedObject(ds); MethodInfo getter = self.getter; object result; IntPtr ts = IntPtr.Zero; if (getter == null) { return(Exceptions.RaiseTypeError("property cannot be read")); } if (ob == IntPtr.Zero || ob == Runtime.PyNone) { if (!getter.IsStatic) { Exceptions.SetError(Exceptions.TypeError, "instance property must be accessed through a class instance"); return(IntPtr.Zero); } ts = PythonEngine.BeginAllowThreads(); try { result = self.info.GetValue(null, null); PythonEngine.EndAllowThreads(ts); return(Converter.ToPython(result, self.info.PropertyType)); } catch (Exception e) { PythonEngine.EndAllowThreads(ts); return(Exceptions.RaiseTypeError(e.Message)); } } var co = GetManagedObject(ob) as CLRObject; if (co == null) { return(Exceptions.RaiseTypeError("invalid target")); } ts = PythonEngine.BeginAllowThreads(); try { result = self.info.GetValue(co.inst, null); PythonEngine.EndAllowThreads(ts); return(Converter.ToPython(result, self.info.PropertyType)); } catch (Exception e) { if (e.InnerException != null) { e = e.InnerException; } PythonEngine.EndAllowThreads(ts); Exceptions.SetError(e); return(IntPtr.Zero); } }