Beispiel #1
0
        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);
        }
Beispiel #2
0
    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);
    }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
    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);
         }
     }));
 }
Beispiel #8
0
        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));
     }
 }
Beispiel #10
0
        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);
            }
        }
Beispiel #11
0
 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));
 }
Beispiel #12
0
        private static PythonObject __hash__(PythonObject self, PythonTuple args)
        {
            object value = ObjectManager.FromPython(self);

            if (value == null)
            {
                return(Py_None);
            }

            return((PythonNumber)value.GetHashCode());
        }
Beispiel #13
0
        private static PythonObject __str__(PythonObject self, PythonTuple args)
        {
            object value = ObjectManager.FromPython(self);

            if (value == null)
            {
                return(Py_None);
            }

            return((PythonString)value.ToString());
        }
Beispiel #14
0
        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);
        }
Beispiel #15
0
    public static PythonObject Break(PythonObject self, PythonTuple args)
    {
        if (!Debugger.IsAttached)
        {
            Debugger.Launch();
        }
        else
        {
            Debugger.Break();
        }

        return(null);
    }
Beispiel #16
0
        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));
        }
Beispiel #17
0
        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));
        }
Beispiel #18
0
 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);
     }
 }
Beispiel #19
0
    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));
        }
    }
Beispiel #20
0
            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);
            }
Beispiel #21
0
 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);
     }
 }
Beispiel #22
0
            //[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 ?
            }
Beispiel #23
0
        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));
            }
        }
Beispiel #24
0
        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);
            });
        }
Beispiel #25
0
        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");
            }
        }
Beispiel #26
0
        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);
            });
        }
Beispiel #27
0
        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);
        }
Beispiel #28
0
        public override TileObject Activate()
        {
            PythonObject instance = new PythonObject(_prefabInstance.SourceCode, this);

            return(instance);
        }
Beispiel #29
0
        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);
        }
Beispiel #30
0
        private static PythonObject __str__(PythonObject self, PythonTuple args)
        {
            ClrNamespace me = instances[self];

            return(me.ToString());
        }