public static IntPtr ToPython(object value) { if (value == null) { return(Py_None); } PythonObject result = PythonObject.From(value); if (result != null) { return(result); } if (ClrToPython.ContainsKey(value)) { return((PythonObject)ClrToPython[value]); } Type type = value.GetType(); PythonClass pythonType = TypeManager.ToPython(type); result = pythonType.CreateEmpty(); Register(value, result); return(result); }
public static void Initialize(string name) { Py_NoSiteFlag = true; Py_Initialize(); PythonModule = new PythonModule(name); PythonModule.AddFunction(nameof(AddReference), a => AddReference(null, a)); PythonModule.AddFunction(nameof(Break), a => Break(null, null)); PythonModule.SetAttribute(nameof(System), new ClrNamespace(nameof(System))); ClrClass = new PythonClass("clr"); ClrClass.AddMethod(nameof(__getattr__), __getattr__); ClrClass.AddMethod(nameof(__str__), __str__); ClrClass.AddMethod(nameof(AddReference), AddReference); ClrClass.AddMethod(nameof(Break), Break); //ClrClass.AddMethod("Method", Method); //ClrClass.AddProperty("Property", GetProperty, SetProperty); ClrObject = ClrClass.Create(); PythonModule.SetAttribute("clr", ClrObject); }
private PythonObject __init__(PythonObject self, PythonTuple args, PythonDictionary kw) { object clrObject; if (kw.Pointer != IntPtr.Zero) { return(Py_None); } if (Type.IsAbstract) { clrObject = new object(); } else { ConstructorInfo[] constructors = Type.GetConstructors(BindingFlags.Public | BindingFlags.Instance); if (!TryCallMethod(constructors, null, args, out clrObject)) { throw new ArgumentException("Could not find any overload matching the specified arguments"); } } ClrObject pythonObject = new ClrObject(self, clrObject); ObjectManager.Register(clrObject, pythonObject.Pointer); return(Py_None); }
public static object FromPython(IntPtr pointer) { if (pointer == IntPtr.Zero) { return(null); // FIXME: Throw exception ? } if (pointer == Py_None) { return(null); } if (PythonToClr.ContainsKey(pointer)) { return(PythonToClr[pointer]); } object result = PythonObject.Convert(pointer); if (result != null) { return(result); } // TODO: Build a .NET wrapper // Return the wrapper return(null); }
public static PythonObject AddReference(PythonObject self, PythonTuple args) { string name = (args[0] as PythonString).ToString(); Assembly assembly = LoadAssembly(name); return(ObjectManager.ToPython(assembly)); }
public Task <PythonObject> LoadScript(string code, CancellationToken ct) { ct.ThrowIfCancellationRequested(); return(RunSTA(() => { using (_py.GIL()) { Trace.TraceInformation($"Trying to load Python script"); object module = null; Stopwatch sw = Stopwatch.StartNew(); try { // using a Guid for "name" import module = _pyEngine.ModuleFromString(GetModuleName(code), code); var result = new PythonObject(module); return result; } catch (TargetInvocationException e) { Trace.TraceError($"Python LoadScript exception: {e.ToString()}"); ExceptionDispatchInfo.Capture(e.InnerException ?? e).Throw(); return null; } finally { sw.Stop(); Trace.TraceInformation($"Load script took {sw.ElapsedMilliseconds} ms"); } } })); }
public Task <PythonObject> InvokeMethod(PythonObject instance, string method, IEnumerable <object> args, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return(Task.Run(() => { using (_py.GIL()) { args = args ?? Enumerable.Empty <object>(); object[] paramsObj = args.Select((obj) => _toPythonMethod.Invoke(null, new object[] { obj })).ToArray(); Array paramsPy = Array.CreateInstance(_pyObjType, paramsObj.Length); Array.Copy(paramsObj, paramsPy, paramsObj.Length); Trace.TraceInformation($"Trying to execute Python method"); object result = null; Stopwatch sw = Stopwatch.StartNew(); try { result = _pyObjInvokeMethod.Invoke(instance.PyObject, new object[] { method, paramsPy }); } catch (TargetInvocationException e) { Trace.TraceError($"Python InvokeMethod exception: {e.ToString()}"); ExceptionDispatchInfo.Capture(e.InnerException ?? e).Throw(); } finally { sw.Stop(); Trace.TraceInformation($"Method execution took {sw.ElapsedMilliseconds} ms"); } return new PythonObject(result); } })); }
public static object EvaluateAndConvert(string code, params object[] args) { PythonObject pythonResult = Evaluate(code, args); object clrResult = ObjectManager.FromPython(pythonResult); return(clrResult); }
public object Convert(PythonObject obj, Type t) { using (_py.GIL()) { Trace.TraceInformation($"Trying to convert Python object to type {t}"); return(obj.AsManagedType(t)); } }
internal IMember MakeObject(ObjectIdentityHandle obj) { if (obj.IsNull) { return(null); } lock (this) { if (_members.TryGetValue(obj, out var res)) { return(res); } switch (_remote.GetObjectKind(obj)) { case ObjectKind.Module: res = new IronPythonModule(this, obj); break; case ObjectKind.Type: res = new IronPythonType(this, obj); break; case ObjectKind.ConstructorFunction: res = new IronPythonConstructorFunction(this, _remote.GetConstructorFunctionTargets(obj), GetTypeFromType(_remote.GetConstructorFunctionDeclaringType(obj))); break; case ObjectKind.BuiltinFunction: res = new IronPythonBuiltinFunction(this, obj); break; case ObjectKind.BuiltinMethodDesc: res = new IronPythonBuiltinMethodDescriptor(this, obj); break; case ObjectKind.ReflectedEvent: res = new IronPythonEvent(this, obj); break; case ObjectKind.ReflectedExtensionProperty: res = new IronPythonExtensionProperty(this, obj); break; case ObjectKind.ReflectedField: res = new IronPythonField(this, obj); break; case ObjectKind.ReflectedProperty: res = new IronPythonProperty(this, obj); break; case ObjectKind.TypeGroup: res = new IronPythonTypeGroup(this, obj); break; case ObjectKind.NamespaceTracker: res = new IronPythonNamespace(this, obj); break; case ObjectKind.Constant: res = new IronPythonConstant(this, obj); break; case ObjectKind.ClassMethod: res = new IronPythonGenericMember(this, obj, PythonMemberType.Method); break; case ObjectKind.Method: res = new IronPythonGenericMember(this, obj, PythonMemberType.Method); break; case ObjectKind.PythonTypeSlot: res = new IronPythonGenericMember(this, obj, PythonMemberType.Property); break; case ObjectKind.PythonTypeTypeSlot: res = new IronPythonGenericMember(this, obj, PythonMemberType.Property); break; case ObjectKind.Unknown: res = new PythonObject(this, obj); break; default: throw new InvalidOperationException(); } _members[obj] = res; return(res); } }
public Task <PythonObject> InvokeMethod(PythonObject instance, string method, IEnumerable <object> args, CancellationToken ct) { ct.ThrowIfCancellationRequested(); return(Task.Run(() => { ct.ThrowIfCancellationRequested(); return new PythonObject(_proxy.InvokeMethod(instance.Id, method, args.EmptyIfNull().Select(elem => new Argument(elem)))); }, ct)); }
private static PythonObject __hash__(PythonObject self, PythonTuple args) { object value = ObjectManager.FromPython(self); if (value == null) { return(Py_None); } return((PythonNumber)value.GetHashCode()); }
private static PythonObject __str__(PythonObject self, PythonTuple args) { object value = ObjectManager.FromPython(self); if (value == null) { return(Py_None); } return((PythonString)value.ToString()); }
private static PythonObject __exit__(PythonObject self, PythonTuple args) { object value = ObjectManager.FromPython(self); if (value == null) { return(Py_None); } (value as IDisposable).Dispose(); return(Py_None); }
public static PythonObject Break(PythonObject self, PythonTuple args) { if (!Debugger.IsAttached) { Debugger.Launch(); } else { Debugger.Break(); } return(null); }
private static PythonObject MethodProxy(MethodInfo[] methods, PythonObject self, PythonTuple args) { object clrObject = self == null ? null : ObjectManager.FromPython(self); object result; if (!TryCallMethod(methods, clrObject, args, out result)) { throw new ArgumentException("Could not find any overload matching the specified arguments"); } return(ObjectManager.ToPython(result)); }
private static PythonObject MethodProxy(MethodInfo method, PythonObject self, PythonTuple args) { object clrObject = self == null ? null : ObjectManager.FromPython(self); object[] parameters = new object[args.Size]; for (int i = 0; i < parameters.Length; i++) { parameters[i] = Convert(args[i]); } object clrResult = method.Invoke(clrObject, parameters); return(ObjectManager.ToPython(clrResult)); }
public Guid LoadScript(string code) { try { PythonObject obj = _engine.LoadScript(code, _ct).Result; obj.Id = Guid.NewGuid(); _objectCache.Add(obj.Id, obj); return(obj.Id); } catch (Exception ex) { ExceptionDispatchInfo.Capture(ex.InnerException ?? ex).Throw(); return(Guid.Empty); } }
public static PythonObject __getattr__(PythonObject self, PythonTuple args) { string name = (args[0] as PythonString).ToString(); Type type = AppDomain.CurrentDomain.GetAssemblies() .Select(a => a.GetType(name)) .FirstOrDefault(t => t != null); if (type == null) { return(new ClrNamespace(name)); } else { return(TypeManager.ToPython(type)); } }
public static IntPtr ConstructorProxy(object instance, IntPtr type, object[] args) { int length = args?.Length ?? 0; PythonTuple tuple = new PythonTuple(length); for (int i = 0; i < length; i++) { tuple[i] = PythonObject.From(args[i]); } PythonObject result; using (PythonException.Checker) result = PyObject_CallObject(type, tuple); ObjectManager.Register(instance, result); return(result); }
public Guid InvokeMethod(Guid instance, string method, IEnumerable <Argument> args) { try { if (!_objectCache.TryGetValue(instance, out PythonObject pyObj)) { throw new ArgumentException(nameof(instance)); } PythonObject obj = _engine.InvokeMethod(pyObj, method, args.Select(elem => elem?.Unwrap()), _ct).Result; obj.Id = Guid.NewGuid(); _objectCache.Add(obj.Id, obj); return(obj.Id); } catch (Exception ex) { ExceptionDispatchInfo.Capture(ex.InnerException ?? ex).Throw(); return(Guid.Empty); } }
//[DebuggerHidden] public static object MethodProxy(IntPtr instance, IntPtr method, object[] args) { int length = args?.Length ?? 0; PythonTuple parameters = new PythonTuple(length + 1); parameters[0] = instance; for (int i = 0; i < length; i++) { parameters[i + 1] = PythonObject.From(args[i]); } PythonObject result; using (PythonException.Checker) result = PyObject_CallObject(method, parameters); return(ObjectManager.FromPython(result)); // TODO: Send a type hint ? }
private static PythonObject __getattr__(PythonObject self, PythonTuple args) { ClrNamespace me = instances[self]; string name = (args[0] as PythonString).ToString(); string fullName = me.ToIdentifier() + "." + name; Type type = AppDomain.CurrentDomain.GetAssemblies() .Select(a => a.GetType(fullName)) .FirstOrDefault(t => t != null); if (type == null) { return(new ClrNamespace(name, me)); } else { return(TypeManager.ToPython(type)); } }
protected async override Task <Action <AsyncCodeActivityContext> > ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken) { IEngine pythonEngine = PythonScope.GetPythonEngine(context); string scriptFile = ScriptFile.Get(context); string scriptCode = Code.Get(context); // safeguard checks if (scriptFile.IsNullOrEmpty() && scriptCode.IsNullOrEmpty()) { throw new InvalidOperationException(Resources.NoScriptSpecifiedException); } if (!scriptFile.IsNullOrEmpty() && !File.Exists(scriptFile)) { throw new FileNotFoundException(Resources.ScriptFileNotFoundException, scriptFile); } // load script from file if not specified if (scriptCode.IsNullOrEmpty()) { scriptCode = File.ReadAllText(ScriptFile.Get(context)); } PythonObject result = null; try { result = await pythonEngine.LoadScript(scriptCode, cancellationToken); } catch (Exception e) { Trace.TraceError($"Error loading Python script: {e.ToString()}"); throw new InvalidOperationException(Resources.LoadScriptException, e); } return((asyncCodeActivityContext) => { Result.Set(asyncCodeActivityContext, result); }); }
private static PythonObject __getattr__(PythonObject self, PythonTuple args) { object value = ObjectManager.FromPython(self); if (value == null) { return(Py_None); } string name = (args[0] as PythonString)?.Value; if (name == null) { throw new Exception("AttributeError"); } // TODO: Ugly hack to handle .NET PythonObject classes // Handle this case in TypeManager.ToPython ... if (value is PythonObject) { IntPtr pointer = (value as PythonObject).Pointer; if (PyObject_HasAttrString(pointer, name) != 0) { return((value as PythonObject).GetAttribute(name)); } } IEnumerable <MethodInfo> extensions = CollectExtensionMethods(value.GetType(), name); if (extensions.Any()) { return(new PythonFunction(name, (a, b) => ExtensionMethodCallback(value, extensions, (PythonTuple)(PythonObject)b))); // TODO: return virtual method object } else { throw new Exception("AttributeError"); } }
protected async override Task <Action <AsyncCodeActivityContext> > ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken) { IEngine pythonEngine = PythonScope.GetPythonEngine(context); if (pythonEngine == null) { throw new InvalidOperationException(Resources.PythonEngineNotFoundException); } PythonObject pyObject = Instance.Get(context); string methodName = Name.Get(context); IEnumerable <object> parameters = Parameters.Get(context); // safeguard checks if (methodName.IsNullOrEmpty()) { throw new InvalidOperationException(Resources.InvalidMethodNameException); } PythonObject result = null; try { result = await pythonEngine.InvokeMethod(pyObject, methodName, parameters, cancellationToken); } catch (Exception e) { Trace.TraceError($"Error invoking Python function: {e.ToString()}"); throw new InvalidOperationException(Resources.InvokeException, e); } return(asyncCodeActivityContext => { Result.Set(asyncCodeActivityContext, result); }); }
protected override void Execute(CodeActivityContext context) { IEngine pythonEngine = PythonScope.GetPythonEngine(context); PythonObject pyObject = PythonObject.Get(context); if (null == pyObject) { throw new ArgumentNullException(nameof(PythonObject)); } T result; try { result = (T)pythonEngine.Convert(pyObject, typeof(T)); } catch (Exception e) { Trace.TraceError($"Error casting Python object: {e}"); throw new InvalidOperationException(Resources.ConvertException, e); } Result.Set(context, result); }
public override TileObject Activate() { PythonObject instance = new PythonObject(_prefabInstance.SourceCode, this); return(instance); }
public static Type FromPython(IntPtr pointer, Type baseType = null) { if (pointer == IntPtr.Zero) { throw new ArgumentNullException("The specified pointer is null"); } if (ObjectManager.PythonToClr.ContainsKey(pointer)) { return((Type)ObjectManager.PythonToClr[pointer]); } // Get Python type name PythonObject pythonObject = pointer; string typeName = null; if (pythonObject is PythonType) { typeName = (pythonObject as PythonType).Name; } else if (pythonObject is PythonClass) { typeName = (pythonObject as PythonClass).Name; } else if (pythonObject is PythonModule) { typeName = (pythonObject as PythonModule).Name; } else { throw new ArgumentNullException("The specified pointer cannot be converted to .NET type"); } // Convert base type if (baseType == null) { if (pythonObject is PythonClass) { PythonTuple bases = (pythonObject as PythonClass).Bases; int basesCount = bases.Size; if (basesCount > 1) { throw new NotSupportedException("Cannot convert python type with multiple base classes"); } else if (basesCount == 1) { baseType = FromPython(bases[0]); } } } // Setup builders AssemblyName assemblyName = new AssemblyName(typeName + "_Assembly"); AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndCollect); ModuleBuilder module = assemblyBuilder.DefineDynamicModule(typeName + "_Module"); // Find class specs if (baseType == null) { baseType = typeof(object); } // Proxy methods MethodInfo constructorProxy = typeof(FromPythonHelper).GetMethod(nameof(FromPythonHelper.ConstructorProxy)); MethodInfo methodProxy = typeof(FromPythonHelper).GetMethod(nameof(FromPythonHelper.MethodProxy)); // Build type TypeBuilder typeBuilder = module.DefineType(typeName, TypeAttributes.Public | TypeAttributes.Class, baseType); FieldInfo pointerField = typeBuilder.DefineField("pointer", typeof(IntPtr), FieldAttributes.Private); List <ConstructorBuilder> constructorBuilders = new List <ConstructorBuilder>(); foreach (var member in pythonObject) { PythonType memberType = member.Value.Type; switch (memberType.Name) { // Properties case "property": { PythonObject pythonGetMethod = member.Value.GetAttribute("fget"); PythonObject pythonSetMethod = member.Value.GetAttribute("fset"); PropertyInfo clrProperty = baseType.GetProperty(member.Key); MethodInfo clrGetMethod = clrProperty?.GetGetMethod(true); MethodInfo clrSetMethod = clrProperty?.GetSetMethod(true); MethodBuilder getMethodBuilder = null, setMethodBuilder = null; Type propertyType = clrProperty?.PropertyType ?? typeof(object); if (pythonGetMethod != Py_None) { getMethodBuilder = FromPythonHelper.AddMethodProxy(typeBuilder, "get_" + member.Key, pythonGetMethod.Pointer, pointerField, clrGetMethod, propertyType, Type.EmptyTypes, true); } if (pythonSetMethod != Py_None) { setMethodBuilder = FromPythonHelper.AddMethodProxy(typeBuilder, "set_" + member.Key, pythonSetMethod.Pointer, pointerField, clrSetMethod, typeof(void), new Type[] { propertyType }, true); } if (clrProperty == null) { PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(member.Key, PropertyAttributes.None, typeof(object), Type.EmptyTypes); if (getMethodBuilder != null) { propertyBuilder.SetGetMethod(getMethodBuilder); } if (setMethodBuilder != null) { propertyBuilder.SetSetMethod(setMethodBuilder); } } break; } // Methods case "instancemethod": { if (member.Key == typeName) // Constructor { } else { switch (member.Key) { // Object case "__str__": break; case "__hash__": break; // IDisposable case "__enter__": break; case "__exit__": break; // Methods default: { MethodInfo method = baseType.GetMethod(member.Key); if (method?.IsFinal == true) { continue; } if (method == null) { FromPythonHelper.AddGenericMethodProxy(typeBuilder, member.Key, member.Value.Pointer, pointerField); } else { FromPythonHelper.AddMethodProxy(typeBuilder, member.Key, member.Value.Pointer, pointerField, method, method.ReturnType, method.GetParameters().Select(p => p.ParameterType).ToArray()); } break; } } } break; } } } // Build a default constructor if needed if (constructorBuilders.Count == 0) { ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes); ILGenerator ilGenerator = constructorBuilder.GetILGenerator(); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Dup); // instance if (IntPtr.Size == 4) { ilGenerator.Emit(OpCodes.Ldc_I4, pointer.ToInt32()); // type } else if (IntPtr.Size == 8) { ilGenerator.Emit(OpCodes.Ldc_I8, pointer.ToInt64()); // type } ilGenerator.Emit(OpCodes.Ldnull); // null ilGenerator.EmitCall(OpCodes.Call, constructorProxy, Type.EmptyTypes); // CallProxy ilGenerator.Emit(OpCodes.Stfld, pointerField); ilGenerator.Emit(OpCodes.Ret); } // Build type and check for abstract methods TypeInfo typeInfo = typeBuilder.CreateTypeInfo(); // Register type and return it FromPythonHelper.BuiltTypes.Add(typeInfo); ObjectManager.Register(typeInfo, pointer); return(typeInfo); }
private static PythonObject __str__(PythonObject self, PythonTuple args) { ClrNamespace me = instances[self]; return(me.ToString()); }