Inheritance: ManagedType
Example #1
0
        /// <summary>
        /// DelegateObject __new__ implementation. The result of this is a new
        /// PyObject whose type is DelegateObject and whose ob_data is a handle
        /// to an actual delegate instance. The method wrapped by the actual
        /// delegate instance belongs to an object generated to relay the call
        /// to the Python callable passed in.
        /// </summary>
        public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw)
        {
            var self = (DelegateObject)GetManagedObject(tp);

            if (!self.type.Valid)
            {
                return(Exceptions.RaiseTypeError(self.type.DeletedMessage));
            }
            Type type = self.type.Value;

            if (Runtime.PyTuple_Size(args) != 1)
            {
                return(Exceptions.RaiseTypeError("class takes exactly one argument"));
            }

            IntPtr method = Runtime.PyTuple_GetItem(args, 0);

            if (Runtime.PyCallable_Check(method) != 1)
            {
                return(Exceptions.RaiseTypeError("argument must be callable"));
            }

            Delegate d = PythonEngine.DelegateManager.GetDelegate(type, method);

            return(CLRObject.GetInstHandle(d, self.pyHandle));
        }
Example #2
0
        /// <summary>
        /// Set the 'args' slot on a python exception object that wraps
        /// a CLR exception. This is needed for pickling CLR exceptions as
        /// BaseException_reduce will only check the slots, bypassing the
        /// __getattr__ implementation, and thus dereferencing a NULL
        /// pointer.
        /// </summary>
        /// <param name="ob">The python object wrapping </param>
        internal static void SetArgsAndCause(Exception e, IntPtr ob)
        {
            IntPtr args;

            if (!string.IsNullOrEmpty(e.Message))
            {
                args = Runtime.PyTuple_New(1);
                IntPtr msg = Runtime.PyUnicode_FromString(e.Message);
                Runtime.PyTuple_SetItem(args, 0, msg);
            }
            else
            {
                args = Runtime.PyTuple_New(0);
            }

            if (Runtime.PyObject_SetAttrString(ob, "args", args) != 0)
            {
                throw new PythonException();
            }

            if (e.InnerException != null)
            {
                // Note: For an AggregateException, InnerException is only the first of the InnerExceptions.
                using var cause = CLRObject.GetReference(e.InnerException);
                Runtime.PyException_SetCause(ob, cause.DangerousMoveToPointer());
            }
        }
Example #3
0
        internal static IntPtr GetInstHandle(object ob, Type type)
        {
            ClassBase cc = ClassManager.GetClass(type);
            CLRObject co = GetInstance(ob, cc.tpHandle);

            return(co.pyHandle);
        }
Example #4
0
        /// <summary>
        /// SetError Method
        /// </summary>
        ///
        /// <remarks>
        /// Sets the current Python exception given a CLR exception
        /// object. The CLR exception instance is wrapped as a Python
        /// object, allowing it to be handled naturally from Python.
        /// </remarks>

        public static void SetError(Exception e)
        {
            // Because delegates allow arbitrary nestings of Python calling
            // managed calling Python calling... etc. it is possible that we
            // might get a managed exception raised that is a wrapper for a
            // Python exception. In that case we'd rather have the real thing.

            PythonException pe = e as PythonException;

            if (pe != null)
            {
                Runtime.PyErr_SetObject(pe.PyType, pe.PyValue);
                return;
            }

            IntPtr op = CLRObject.GetInstHandle(e);

            // XXX - hack to raise a compatible old-style exception ;(
            if (Runtime.wrap_exceptions)
            {
                op = GetExceptionInstanceWrapper(op);
            }
            IntPtr etype = Runtime.PyObject_GetAttrString(op, "__class__");

            Runtime.PyErr_SetObject(etype, op);
            Runtime.Decref(etype);
            Runtime.Decref(op);
        }
Example #5
0
        //====================================================================
        // This is a hack. Generally, no managed class is considered callable
        // from Python - with the exception of System.Delegate. It is useful
        // to be able to call a System.Delegate instance directly, especially
        // when working with multicast delegates.
        //====================================================================

        public static IntPtr tp_call(IntPtr ob, IntPtr args, IntPtr kw)
        {
            //ManagedType self = GetManagedObject(ob);
            IntPtr    tp = Runtime.PyObject_TYPE(ob);
            ClassBase cb = (ClassBase)GetManagedObject(tp);

            if (cb.type != typeof(System.Delegate))
            {
                Exceptions.SetError(Exceptions.TypeError,
                                    "object is not callable");
                return(IntPtr.Zero);
            }

            CLRObject    co    = (CLRObject)ManagedType.GetManagedObject(ob);
            Delegate     d     = co.inst as Delegate;
            BindingFlags flags = BindingFlags.Public |
                                 BindingFlags.NonPublic |
                                 BindingFlags.Instance |
                                 BindingFlags.Static;

            MethodInfo   method = d.GetType().GetMethod("Invoke", flags);
            MethodBinder binder = new MethodBinder(method);

            return(binder.Invoke(ob, args, kw));
        }
Example #6
0
        // Called from Converter.ToPython for types that are python subclasses of managed types.
        // The referenced python object is returned instead of a new wrapper.
        internal static IntPtr ToPython(IPythonDerivedType obj)
        {
            // derived types have a __pyobj__ field that gets set to the python
            // object in the overriden constructor
            FieldInfo fi   = obj.GetType().GetField("__pyobj__");
            CLRObject self = (CLRObject)fi.GetValue(obj);

            Runtime.Incref(self.pyHandle);

            // when the C# constructor creates the python object it starts as a weak
            // reference with a reference count of 0. Now we're passing this object
            // to Python the reference count needs to be incremented and the reference
            // needs to be replaced with a strong reference to stop the C# object being
            // collected while Python still has a reference to it.
            if (Runtime.Refcount(self.pyHandle) == 1)
            {
                GCHandle gc = GCHandle.Alloc(self, GCHandleType.Normal);
                Marshal.WriteIntPtr(self.pyHandle, ObjectOffset.magic(self.tpHandle), (IntPtr)gc);
                self.gcHandle.Free();
                self.gcHandle = gc;

                // now the object has a python reference it's safe for the python GC to track it
                Runtime.PyObject_GC_Track(self.pyHandle);
            }

            return(self.pyHandle);
        }
Example #7
0
        /// <summary>
        /// SetError Method
        /// </summary>
        /// <remarks>
        /// Sets the current Python exception given a CLR exception
        /// object. The CLR exception instance is wrapped as a Python
        /// object, allowing it to be handled naturally from Python.
        /// </remarks>
        public static void SetError(Exception e)
        {
            // Because delegates allow arbitrary nesting of Python calling
            // managed calling Python calling... etc. it is possible that we
            // might get a managed exception raised that is a wrapper for a
            // Python exception. In that case we'd rather have the real thing.

            var pe = e as PythonException;

            if (pe != null)
            {
                Runtime.XIncref(pe.PyType);
                Runtime.XIncref(pe.PyValue);
                Runtime.XIncref(pe.PyTB);
                Runtime.PyErr_Restore(pe.PyType, pe.PyValue, pe.PyTB);
                return;
            }

            IntPtr op    = CLRObject.GetInstHandle(e);
            IntPtr etype = Runtime.PyObject_GetAttr(op, PyIdentifier.__class__);

            Runtime.PyErr_SetObject(new BorrowedReference(etype), new BorrowedReference(op));
            Runtime.XDecref(etype);
            Runtime.XDecref(op);
        }
Example #8
0
        /// <summary>
        /// DelegateObject __new__ implementation. The result of this is a new
        /// PyObject whose type is DelegateObject and whose ob_data is a handle
        /// to an actual delegate instance. The method wrapped by the actual
        /// delegate instance belongs to an object generated to relay the call
        /// to the Python callable passed in.
        /// </summary>
        public static NewReference tp_new(BorrowedReference tp, BorrowedReference args, BorrowedReference kw)
        {
            var self = (DelegateObject)GetManagedObject(tp) !;

            if (!self.type.Valid)
            {
                return(Exceptions.RaiseTypeError(self.type.DeletedMessage));
            }
            Type type = self.type.Value;

            if (Runtime.PyTuple_Size(args) != 1)
            {
                return(Exceptions.RaiseTypeError("class takes exactly one argument"));
            }

            BorrowedReference method = Runtime.PyTuple_GetItem(args, 0);

            if (Runtime.PyCallable_Check(method) != 1)
            {
                return(Exceptions.RaiseTypeError("argument must be callable"));
            }

            Delegate d = PythonEngine.DelegateManager.GetDelegate(type, new PyObject(method));

            return(CLRObject.GetReference(d, ClassManager.GetClass(type)));
        }
Example #9
0
        //====================================================================
        // Standard iteration support for instances of reflected types. This
        // allows natural iteration over objects that either are IEnumerable
        // or themselves support IEnumerator directly.
        //====================================================================

        public static IntPtr tp_iter(IntPtr ob)
        {
            CLRObject co = GetManagedObject(ob) as CLRObject;

            if (co == null)
            {
                return(Exceptions.RaiseTypeError("invalid object"));
            }

            IEnumerable e = co.inst as IEnumerable;
            IEnumerator o;

            if (e != null)
            {
                o = e.GetEnumerator();
            }
            else
            {
                o = co.inst as IEnumerator;

                if (o == null)
                {
                    string message = "iteration over non-sequence";
                    return(Exceptions.RaiseTypeError(message));
                }
            }

            return(new Iterator(o).pyHandle);
        }
Example #10
0
        public static void Finalize(IPythonDerivedType obj)
        {
            FieldInfo fi   = obj.GetType().GetField("__pyobj__");
            CLRObject self = (CLRObject)fi.GetValue(obj);

            // delete the python object in an asnyc task as we may not be able to acquire
            // the GIL immediately and we don't want to block the GC thread.
            var t = Task.Factory.StartNew(() =>
            {
                // If python's been terminated then there's nothing to do
                if (0 == Runtime.Py_IsInitialized())
                {
                    return;
                }

                IntPtr gs = Runtime.PyGILState_Ensure();
                try
                {
                    // the C# object is being destroyed which must mean there are no more
                    // references to the Python object as well so now we can dealloc the
                    // python object.
                    IntPtr dict = Marshal.ReadIntPtr(self.pyHandle, ObjectOffset.DictOffset(self.pyHandle));
                    if (dict != IntPtr.Zero)
                    {
                        Runtime.Decref(dict);
                    }
                    Runtime.PyObject_GC_Del(self.pyHandle);
                    self.gcHandle.Free();
                }
                finally
                {
                    Runtime.PyGILState_Release(gs);
                }
            });
        }
Example #11
0
        /// <summary>
        /// Set the 'args' slot on a python exception object that wraps
        /// a CLR exception. This is needed for pickling CLR exceptions as
        /// BaseException_reduce will only check the slots, bypassing the
        /// __getattr__ implementation, and thus dereferencing a NULL
        /// pointer.
        /// </summary>
        /// <param name="ob">The python object wrapping </param>
        internal static void SetArgsAndCause(IntPtr ob)
        {
            // e: A CLR Exception
            Exception e = ExceptionClassObject.ToException(ob);

            if (e == null)
            {
                return;
            }

            IntPtr args;

            if (!string.IsNullOrEmpty(e.Message))
            {
                args = Runtime.PyTuple_New(1);
                IntPtr msg = Runtime.PyUnicode_FromString(e.Message);
                Runtime.PyTuple_SetItem(args, 0, msg);
            }
            else
            {
                args = Runtime.PyTuple_New(0);
            }

            Marshal.WriteIntPtr(ob, ExceptionOffset.args, args);

#if PYTHON3
            if (e.InnerException != null)
            {
                IntPtr cause = CLRObject.GetInstHandle(e.InnerException);
                Marshal.WriteIntPtr(ob, ExceptionOffset.cause, cause);
            }
#endif
        }
        //====================================================================
        // Implements __len__ for array types.
        //====================================================================

        public static int mp_length(IntPtr ob)
        {
            CLRObject self  = (CLRObject)ManagedType.GetManagedObject(ob);
            Array     items = self.inst as Array;

            return(items.Length);
        }
Example #13
0
        /// <summary>
        /// Set the 'args' slot on a python exception object that wraps
        /// a CLR exception. This is needed for pickling CLR exceptions as
        /// BaseException_reduce will only check the slots, bypassing the
        /// __getattr__ implementation, and thus dereferencing a NULL
        /// pointer.
        /// </summary>
        internal static bool SetArgsAndCause(BorrowedReference ob, Exception e)
        {
            NewReference args;

            if (!string.IsNullOrEmpty(e.Message))
            {
                args          = Runtime.PyTuple_New(1);
                using var msg = Runtime.PyString_FromString(e.Message);
                Runtime.PyTuple_SetItem(args.Borrow(), 0, msg.StealOrThrow());
            }
            else
            {
                args = Runtime.PyTuple_New(0);
            }

            using (args)
            {
                if (Runtime.PyObject_SetAttrString(ob, "args", args.Borrow()) != 0)
                {
                    return(false);
                }
            }

            if (e.InnerException != null)
            {
                // Note: For an AggregateException, InnerException is only the first of the InnerExceptions.
                using var cause = CLRObject.GetReference(e.InnerException);
                Runtime.PyException_SetCause(ob, cause.Steal());
            }

            return(true);
        }
Example #14
0
        /// <summary>
        /// Set the 'args' slot on a python exception object that wraps
        /// a CLR exception. This is needed for pickling CLR exceptions as
        /// BaseException_reduce will only check the slots, bypassing the
        /// __getattr__ implementation, and thus dereferencing a NULL
        /// pointer.
        /// </summary>
        internal static void SetArgsAndCause(BorrowedReference ob, Exception e)
        {
            IntPtr args;

            if (!string.IsNullOrEmpty(e.Message))
            {
                args = Runtime.PyTuple_New(1);
                IntPtr msg = Runtime.PyString_FromString(e.Message);
                Runtime.PyTuple_SetItem(args, 0, msg);
            }
            else
            {
                args = Runtime.PyTuple_New(0);
            }

            using var argsTuple = NewReference.DangerousFromPointer(args);

            if (Runtime.PyObject_SetAttrString(ob, "args", argsTuple) != 0)
            {
                throw PythonException.ThrowLastAsClrException();
            }

            if (e.InnerException != null)
            {
                // Note: For an AggregateException, InnerException is only the first of the InnerExceptions.
                using var cause = CLRObject.GetReference(e.InnerException);
                Runtime.PyException_SetCause(ob, cause.Steal());
            }
        }
Example #15
0
        public static void InvokeMethodVoid(IPythonDerivedType obj, string methodName, string origMethodName, Object[] args)
        {
            FieldInfo fi   = obj.GetType().GetField("__pyobj__");
            CLRObject self = (CLRObject)fi.GetValue(obj);

            if (null != self)
            {
                List <PyObject> disposeList = new List <PyObject>();
                IntPtr          gs          = Runtime.PyGILState_Ensure();
                try
                {
                    Runtime.Incref(self.pyHandle);
                    PyObject pyself = new PyObject(self.pyHandle);
                    disposeList.Add(pyself);

                    Runtime.Incref(Runtime.PyNone);
                    PyObject pynone = new PyObject(Runtime.PyNone);
                    disposeList.Add(pynone);

                    PyObject method = pyself.GetAttr(methodName, pynone);
                    disposeList.Add(method);
                    if (method.Handle != Runtime.PyNone)
                    {
                        // if the method hasn't been overriden then it will be a managed object
                        ManagedType managedMethod = ManagedType.GetManagedObject(method.Handle);
                        if (null == managedMethod)
                        {
                            PyObject[] pyargs = new PyObject[args.Length];
                            for (int i = 0; i < args.Length; ++i)
                            {
                                pyargs[i] = new PyObject(Converter.ToPython(args[i], args[i].GetType()));
                                disposeList.Add(pyargs[i]);
                            }

                            PyObject py_result = method.Invoke(pyargs);
                            disposeList.Add(py_result);
                            return;
                        }
                    }
                }
                finally
                {
                    foreach (PyObject x in disposeList)
                    {
                        if (x != null)
                        {
                            x.Dispose();
                        }
                    }
                    Runtime.PyGILState_Release(gs);
                }
            }

            obj.GetType().InvokeMember(origMethodName,
                                       BindingFlags.InvokeMethod,
                                       null,
                                       obj,
                                       args);
        }
Example #16
0
        //====================================================================
        // Remove the given Python object event handler.
        //====================================================================

        internal bool RemoveEventHandler(IntPtr target, IntPtr handler)
        {
            Object obj = null;

            if (target != IntPtr.Zero)
            {
                CLRObject co = (CLRObject)ManagedType.GetManagedObject(target);
                obj = co.inst;
            }

            IntPtr hash = Runtime.PyObject_Hash(handler);

            if (Exceptions.ErrorOccurred() || (reg == null))
            {
                Exceptions.SetError(Exceptions.ValueError,
                                    "unknown event handler"
                                    );
                return(false);
            }

            object    key  = (obj != null) ? obj : this.info.ReflectedType;
            ArrayList list = reg[key] as ArrayList;

            if (list == null)
            {
                Exceptions.SetError(Exceptions.ValueError,
                                    "unknown event handler"
                                    );
                return(false);
            }

            object[]   args = { null };
            MethodInfo mi   = this.info.GetRemoveMethod(true);

            for (int i = 0; i < list.Count; i++)
            {
                Handler item = (Handler)list[i];
                if (item.hash != hash)
                {
                    continue;
                }
                args[0] = item.del;
                try
                {
                    mi.Invoke(obj, BindingFlags.Default, null, args, null);
                }
                catch
                {
                    continue;
                }
                list.RemoveAt(i);
                return(true);
            }

            Exceptions.SetError(Exceptions.ValueError,
                                "unknown event handler"
                                );
            return(false);
        }
Example #17
0
        /// <summary>
        /// Gets raw Python proxy for this object (bypasses all conversions,
        /// except <c>null</c> &lt;==&gt; <c>None</c>)
        /// </summary>
        public static PyObject GetRawPythonProxy(this object o)
        {
            if (o is null)
            {
                return(new PyObject(new BorrowedReference(Runtime.PyNone)));
            }

            return(CLRObject.MakeNewReference(o).MoveToPyObject());
        }
Example #18
0
        /// <summary>
        /// Implements __new__ for reflected classes and value types.
        /// </summary>
        public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw)
        {
            var self = GetManagedObject(tp) as ClassObject;

            // Sanity check: this ensures a graceful error if someone does
            // something intentially wrong like use the managed metatype for
            // a class that is not really derived from a managed class.
            if (self == null)
            {
                return(Exceptions.RaiseTypeError("invalid object"));
            }

            Type type = self.type;

            // Primitive types do not have constructors, but they look like
            // they do from Python. If the ClassObject represents one of the
            // convertible primitive types, just convert the arg directly.
            if (type.IsPrimitive || type == typeof(string))
            {
                if (Runtime.PyTuple_Size(args) != 1)
                {
                    Exceptions.SetError(Exceptions.TypeError, "no constructors match given arguments");
                    return(IntPtr.Zero);
                }

                IntPtr op = Runtime.PyTuple_GetItem(args, 0);
                object result;

                if (!Converter.ToManaged(op, type, out result, true))
                {
                    return(IntPtr.Zero);
                }

                return(CLRObject.GetInstHandle(result, tp));
            }

            if (type.IsAbstract)
            {
                Exceptions.SetError(Exceptions.TypeError, "cannot instantiate abstract class");
                return(IntPtr.Zero);
            }

            if (type.IsEnum)
            {
                Exceptions.SetError(Exceptions.TypeError, "cannot instantiate enumeration");
                return(IntPtr.Zero);
            }

            object obj = self.binder.InvokeRaw(IntPtr.Zero, args, kw);

            if (obj == null)
            {
                return(IntPtr.Zero);
            }

            return(CLRObject.GetInstHandle(obj, tp));
        }
Example #19
0
        //====================================================================
        // 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.
        //====================================================================

        public static IntPtr tp_descr_get(IntPtr ds, IntPtr ob, IntPtr tp)
        {
            PropertyObject self   = (PropertyObject)GetManagedObject(ds);
            MethodInfo     getter = self.getter;
            Object         result;


            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);
                }

                try
                {
                    result = self.info.GetValue(null, null);
                    return(Converter.ToPython(result, self.info.PropertyType));
                }
                catch (Exception e)
                {
                    return(Exceptions.RaiseTypeError(e.Message));
                }
            }

            CLRObject co = GetManagedObject(ob) as CLRObject;

            if (co == null)
            {
                return(Exceptions.RaiseTypeError("invalid target"));
            }

            try
            {
                result = self.info.GetValue(co.inst, null);
                return(Converter.ToPython(result, self.info.PropertyType));
            }
            catch (Exception e)
            {
                if (e.InnerException != null)
                {
                    e = e.InnerException;
                }
                Exceptions.SetError(e);
                return(IntPtr.Zero);
            }
        }
Example #20
0
        public static IntPtr tp_new(IntPtr tpRaw, IntPtr args, IntPtr kw)
        {
            if (kw != IntPtr.Zero)
            {
                return(Exceptions.RaiseTypeError("array constructor takes no keyword arguments"));
            }

            var tp = new BorrowedReference(tpRaw);

            var self = GetManagedObject(tp) as ArrayObject;

            if (!self.type.Valid)
            {
                return(Exceptions.RaiseTypeError(self.type.DeletedMessage));
            }
            Type arrType = self.type.Value;

            long[] dimensions = new long[Runtime.PyTuple_Size(args)];
            if (dimensions.Length == 0)
            {
                return(Exceptions.RaiseTypeError("array constructor requires at least one integer argument or an object convertible to array"));
            }
            if (dimensions.Length != 1)
            {
                return(CreateMultidimensional(arrType.GetElementType(), dimensions,
                                              shapeTuple: new BorrowedReference(args),
                                              pyType: tp)
                       .DangerousMoveToPointerOrNull());
            }

            IntPtr op = Runtime.PyTuple_GetItem(args, 0);

            // create single dimensional array
            if (Runtime.PyInt_Check(op))
            {
                dimensions[0] = Runtime.PyLong_AsSignedSize_t(op);
                if (dimensions[0] == -1 && Exceptions.ErrorOccurred())
                {
                    Exceptions.Clear();
                }
                else
                {
                    return(NewInstance(arrType.GetElementType(), tp, dimensions)
                           .DangerousMoveToPointerOrNull());
                }
            }
            object result;

            // this implements casting to Array[T]
            if (!Converter.ToManaged(op, arrType, out result, true))
            {
                return(IntPtr.Zero);
            }
            return(CLRObject.GetInstHandle(result, tp)
                   .DangerousGetAddress());
        }
Example #21
0
        //====================================================================
        // Standard __str__ implementation for instances of reflected types.
        //====================================================================

        public static IntPtr tp_str(IntPtr ob)
        {
            CLRObject co = GetManagedObject(ob) as CLRObject;

            if (co == null)
            {
                return(Exceptions.RaiseTypeError("invalid object"));
            }
            return(Runtime.PyString_FromString(co.inst.ToString()));
        }
Example #22
0
        //====================================================================
        // Standard __hash__ implementation for instances of reflected types.
        //====================================================================

        public static IntPtr tp_hash(IntPtr ob)
        {
            CLRObject co = GetManagedObject(ob) as CLRObject;

            if (co == null)
            {
                return(Exceptions.RaiseTypeError("unhashable type"));
            }
            return(new IntPtr(co.inst.GetHashCode()));
        }
Example #23
0
        //====================================================================
        // Given a PyObject pointer to an instance of a delegate type, return
        // the true managed delegate the Python object represents (or null).
        //====================================================================

        private static Delegate GetTrueDelegate(IntPtr op)
        {
            CLRObject o = GetManagedObject(op) as CLRObject;

            if (o != null)
            {
                Delegate d = o.inst as Delegate;
                return(d);
            }
            return(null);
        }
Example #24
0
        internal static CLRObject Restore(object ob, IntPtr pyHandle, InterDomainContext context)
        {
            CLRObject co = new CLRObject()
            {
                inst     = ob,
                pyHandle = pyHandle,
                tpHandle = Runtime.PyObject_TYPE(pyHandle)
            };

            co.Load(context);
            return(co);
        }
Example #25
0
        /// <summary>
        /// FromManagedObject Method
        /// </summary>
        /// <remarks>
        /// Given an arbitrary managed object, return a Python instance that
        /// reflects the managed object.
        /// </remarks>
        public static PyObject FromManagedObject(object ob)
        {
            // Special case: if ob is null, we return None.
            if (ob == null)
            {
                Runtime.XIncref(Runtime.PyNone);
                return(new PyObject(Runtime.PyNone));
            }
            IntPtr op = CLRObject.GetInstHandle(ob);

            return(new PyObject(op));
        }
Example #26
0
        internal static Exception ToException(IntPtr ob)
        {
            CLRObject co = GetManagedObject(ob) as CLRObject;

            if (co == null)
            {
                return(null);
            }
            Exception e = co.inst as Exception;

            if (e == null)
            {
                return(null);
            }
            return(e);
        }
Example #27
0
        //====================================================================
        // Descriptor __get__ implementation. This method returns the
        // value of the field on the given object. The returned value
        // is converted to an appropriately typed Python object.
        //====================================================================

        public static IntPtr tp_descr_get(IntPtr ds, IntPtr ob, IntPtr tp)
        {
            FieldObject self = (FieldObject)GetManagedObject(ds);
            Object      result;

            if (self == null)
            {
                return(IntPtr.Zero);
            }

            FieldInfo info = self.info;

            if ((ob == IntPtr.Zero) || (ob == Runtime.PyNone))
            {
                if (!info.IsStatic)
                {
                    Exceptions.SetError(Exceptions.TypeError,
                                        "instance attribute must be accessed " +
                                        "through a class instance"
                                        );
                    return(IntPtr.Zero);
                }
                try
                {
                    result = info.GetValue(null);
                    return(Converter.ToPython(result, info.FieldType));
                }
                catch (Exception e)
                {
                    Exceptions.SetError(Exceptions.TypeError, e.Message);
                    return(IntPtr.Zero);
                }
            }

            try
            {
                CLRObject co = (CLRObject)GetManagedObject(ob);
                result = info.GetValue(co.inst);
                return(Converter.ToPython(result, info.FieldType));
            }
            catch (Exception e)
            {
                Exceptions.SetError(Exceptions.TypeError, e.Message);
                return(IntPtr.Zero);
            }
        }
Example #28
0
        public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw)
        {
            var self = GetManagedObject(tp) as ArrayObject;

            if (Runtime.Interop.PyTuple_Size(args) != 1)
            {
                return(Exceptions.RaiseTypeError("array expects 1 argument"));
            }
            IntPtr op = Runtime.Interop.PyTuple_GetItem(args, 0);
            object result;

            if (!Converter.ToManaged(op, self.type, out result, true))
            {
                return(IntPtr.Zero);
            }
            return(CLRObject.GetInstHandle(result, tp));
        }
        //====================================================================
        // Register a new Python object event handler with the event.
        //====================================================================

        internal bool AddEventHandler(IntPtr target, IntPtr handler)
        {
            Object obj = null;

            if (target != IntPtr.Zero)
            {
                CLRObject co = (CLRObject)ManagedType.GetManagedObject(target);
                obj = co.inst;
            }

            // Create a true delegate instance of the appropriate type to
            // wrap the Python handler. Note that wrapper delegate creation
            // always succeeds, though calling the wrapper may fail.

            Type     type = this.info.EventHandlerType;
            Delegate d    = PythonEngine.DelegateManager.GetDelegate(type, handler);

            // Now register the handler in a mapping from instance to pairs
            // of (handler hash, delegate) so we can lookup to remove later.
            // All this is done lazily to avoid overhead until an event is
            // actually subscribed to by a Python event handler.

            if (reg == null)
            {
                reg = new Hashtable();
            }
            object    key  = (obj != null) ? obj : this.info.ReflectedType;
            ArrayList list = reg[key] as ArrayList;

            if (list == null)
            {
                list     = new ArrayList();
                reg[key] = list;
            }
            list.Add(new Handler(Runtime.PyObject_Hash(handler), d));

            // Note that AddEventHandler helper only works for public events,
            // so we have to get the underlying add method explicitly.

            object[]   args = { d };
            MethodInfo mi   = this.info.GetAddMethod(true);

            mi.Invoke(obj, BindingFlags.Default, null, args, null);

            return(true);
        }
Example #30
0
        new public static void tp_dealloc(IntPtr ob)
        {
            CLRObject self = (CLRObject)GetManagedObject(ob);

            // don't let the python GC destroy this object
            Runtime.PyObject_GC_UnTrack(self.pyHandle);

            // The python should now have a ref count of 0, but we don't actually want to
            // deallocate the object until the C# object that references it is destroyed.
            // So we don't call PyObject_GC_Del here and instead we set the python
            // reference to a weak reference so that the C# object can be collected.
            GCHandle gc = GCHandle.Alloc(self, GCHandleType.Weak);

            Marshal.WriteIntPtr(self.pyHandle, ObjectOffset.magic(self.tpHandle), (IntPtr)gc);
            self.gcHandle.Free();
            self.gcHandle = gc;
        }