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 {} } }
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 {} }
public static PyObject Import(string name) { return(PythonEngine.ImportModule(name)); }
/// <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()); }
/// <summary> /// Initialize Method /// </summary> /// <remarks> /// Initialize the Python runtime. It is safe to call this method /// more than once, though initialization will only happen on the /// first call. It is *not* necessary to hold the Python global /// interpreter lock (GIL) to call this method. /// initSigs can be set to 1 to do default python signal configuration. This will override the way signals are handled by the application. /// </remarks> public static void Initialize(IEnumerable <string> args, bool setSysArgv = true, bool initSigs = false) { if (!initialized) { // Creating the delegateManager MUST happen before Runtime.Initialize // is called. If it happens afterwards, DelegateManager's CodeGenerator // throws an exception in its ctor. This exception is eaten somehow // during an initial "import clr", and the world ends shortly thereafter. // This is probably masking some bad mojo happening somewhere in Runtime.Initialize(). delegateManager = new DelegateManager(); Runtime.Initialize(initSigs); initialized = true; Exceptions.Clear(); // Make sure we clean up properly on app domain unload. AppDomain.CurrentDomain.DomainUnload += OnDomainUnload; // Remember to shut down the runtime. AddShutdownHandler(Runtime.Shutdown); // The global scope gets used implicitly quite early on, remember // to clear it out when we shut down. AddShutdownHandler(PyScopeManager.Global.Clear); if (setSysArgv) { Py.SetArgv(args); } // register the atexit callback (this doesn't use Py_AtExit as the C atexit // callbacks are called after python is fully finalized but the python ones // are called while the python engine is still running). string code = "import atexit, clr\n" + "atexit.register(clr._AtExit)\n"; PythonEngine.Exec(code); // Load the clr.py resource into the clr module IntPtr clr = Python.Runtime.ImportHook.GetCLRModule(); IntPtr clr_dict = Runtime.PyModule_GetDict(clr); var locals = new PyDict(); try { IntPtr module = Runtime.PyImport_AddModule("clr._extras"); IntPtr module_globals = Runtime.PyModule_GetDict(module); IntPtr builtins = Runtime.PyEval_GetBuiltins(); Runtime.PyDict_SetItemString(module_globals, "__builtins__", builtins); Assembly assembly = Assembly.GetExecutingAssembly(); string[] names = assembly.GetManifestResourceNames(); using (Stream stream = assembly.GetManifestResourceStream("Python.Runtime.NetCore.resources.clr.py")) using (var reader = new StreamReader(stream)) { // add the contents of clr.py to the module string clr_py = reader.ReadToEnd(); Exec(clr_py, module_globals, locals.Handle); } // add the imported module to the clr module, and copy the API functions // and decorators into the main clr module. Runtime.PyDict_SetItemString(clr_dict, "_extras", module); foreach (PyObject key in locals.Keys()) { if (!key.ToString().StartsWith("_") || key.ToString().Equals("__version__")) { PyObject value = locals[key]; Runtime.PyDict_SetItem(clr_dict, key.Handle, value.Handle); value.Dispose(); } key.Dispose(); } } finally { locals.Dispose(); } } }
internal GILState() { state = PythonEngine.AcquireLock(); }
public void Dispose() { PythonEngine.ReleaseLock(state); GC.SuppressFinalize(this); }
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)); }
static Converter() { nfi = NumberFormatInfo.InvariantInfo; objectType = typeof(Object); stringType = typeof(String); int16Type = typeof(Int16); int32Type = typeof(Int32); int64Type = typeof(Int64); singleType = typeof(Single); doubleType = typeof(Double); decimalType = typeof(Decimal); flagsType = typeof(FlagsAttribute); boolType = typeof(Boolean); typeType = typeof(Type); IntPtr decimalMod = Runtime.PyImport_ImportModule("decimal"); if (decimalMod == null) { throw new PythonException(); } IntPtr dateTimeMod = Runtime.PyImport_ImportModule("datetime"); if (dateTimeMod == null) { throw new PythonException(); } decimalCtor = Runtime.PyObject_GetAttrString(decimalMod, "Decimal"); if (decimalCtor == null) { throw new PythonException(); } dateTimeCtor = Runtime.PyObject_GetAttrString(dateTimeMod, "datetime"); if (dateTimeCtor == null) { throw new PythonException(); } timeSpanCtor = Runtime.PyObject_GetAttrString(dateTimeMod, "timedelta"); if (timeSpanCtor == null) { throw new PythonException(); } IntPtr tzInfoMod = PythonEngine.ModuleFromString("custom_tzinfo", "from datetime import timedelta, tzinfo\n" + "class GMT(tzinfo):\n" + " def __init__(self, hours, minutes):\n" + " self.hours = hours\n" + " self.minutes = minutes\n" + " def utcoffset(self, dt):\n" + " return timedelta(hours=self.hours, minutes=self.minutes)\n" + " def tzname(self, dt):\n" + " return \"GMT {0:00}:{1:00}\".format(self.hours, self.minutes)\n" + " def dst (self, dt):\n" + " return timedelta(0)\n").Handle; tzInfoCtor = Runtime.PyObject_GetAttrString(tzInfoMod, "GMT"); if (tzInfoCtor == null) { throw new PythonException(); } }
/// <summary> /// Initialize Method /// </summary> /// /// <remarks> /// Initialize the Python runtime. It is safe to call this method /// more than once, though initialization will only happen on the /// first call. It is *not* necessary to hold the Python global /// interpreter lock (GIL) to call this method. /// </remarks> public static void Initialize() { if (!initialized) { // Creating the delegateManager MUST happen before Runtime.Initialize // is called. If it happens afterwards, DelegateManager's CodeGenerator // throws an exception in its ctor. This exception is eaten somehow // during an initial "import clr", and the world ends shortly thereafter. // This is probably masking some bad mojo happening somewhere in Runtime.Initialize(). delegateManager = new DelegateManager(); Runtime.Initialize(); initialized = true; Exceptions.Clear(); // register the atexit callback (this doesn't use Py_AtExit as the C atexit // callbacks are called after python is fully finalized but the python ones // are called while the python engine is still running). string code = "import atexit, clr\n" + "atexit.register(clr._AtExit)\n"; PyObject r = PythonEngine.RunString(code); if (r != null) { r.Dispose(); } // Load the clr.py resource into the clr module IntPtr clr = Python.Runtime.ImportHook.GetCLRModule(); IntPtr clr_dict = Runtime.PyModule_GetDict(clr); PyDict locals = new PyDict(); try { IntPtr module = Runtime.PyImport_AddModule("clr._extras"); IntPtr module_globals = Runtime.PyModule_GetDict(module); IntPtr builtins = Runtime.PyEval_GetBuiltins(); Runtime.PyDict_SetItemString(module_globals, "__builtins__", builtins); var assembly = Assembly.GetExecutingAssembly(); using (Stream stream = assembly.GetManifestResourceStream("clr.py")) using (StreamReader reader = new StreamReader(stream)) { // add the contents of clr.py to the module string clr_py = reader.ReadToEnd(); PyObject result = RunString(clr_py, module_globals, locals.Handle); if (null == result) { throw new PythonException(); } result.Dispose(); } // add the imported module to the clr module, and copy the API functions // and decorators into the main clr module. Runtime.PyDict_SetItemString(clr_dict, "_extras", module); foreach (PyObject key in locals.Keys()) { if (!key.ToString().StartsWith("_")) { PyObject value = locals[key]; Runtime.PyDict_SetItem(clr_dict, key.Handle, value.Handle); value.Dispose(); } key.Dispose(); } } finally { locals.Dispose(); } } }
/// <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); } }
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]}"); } 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}"); } else if (list.Count > 0 && list[0].Valid) { value.Append($" for {list[0].Value.Name}"); } value.Append(": "); Runtime.PyErr_Fetch(out var errType, out var errVal, out var errTrace); AppendArgumentTypes(to: value, args); Runtime.PyErr_Restore(errType.StealNullable(), errVal.StealNullable(), errTrace.StealNullable()); Exceptions.RaiseTypeError(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, if any, 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 > 0) { ParameterInfo[] pi = mi.GetParameters(); int c = pi.Length; var n = 0; bool isVoid = mi.ReturnType == typeof(void); int tupleSize = binding.outs + (isVoid ? 0 : 1); IntPtr t = Runtime.PyTuple_New(tupleSize); if (!isVoid) { 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 (pt.IsByRef) { IntPtr v = Converter.ToPython(binding.args[i], pt.GetElementType()); Runtime.PyTuple_SetItem(t, n, v); n++; } } if (binding.outs == 1 && mi.ReturnType == typeof(void)) { IntPtr v = Runtime.PyTuple_GetItem(t, 0); Runtime.XIncref(v); Runtime.XDecref(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) { Binding binding = Bind(inst, args, kw, info, methodinfo); object result; IntPtr ts = IntPtr.Zero; if (binding == null) { Exceptions.SetError(Exceptions.TypeError, "No method matches given arguments for " + methodinfo[0].Name); 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)); }
protected PyClrTypeBase(string pyType, Type clrType) { this.PythonType = PythonEngine.Eval(pyType); this.ClrType = clrType; }