Example #1
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 #2
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 #3
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 #4
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 #5
0
        internal static NewReference ToPython(object?value, Type type)
        {
            if (value is PyObject pyObj)
            {
                return(new NewReference(pyObj));
            }

            // Null always converts to None in Python.
            if (value == null)
            {
                return(new NewReference(Runtime.PyNone));
            }

            if (EncodableByUser(type, value))
            {
                var encoded = PyObjectConversions.TryEncode(value, type);
                if (encoded != null)
                {
                    return(new NewReference(encoded));
                }
            }

            if (type.IsInterface)
            {
                var ifaceObj = (InterfaceObject)ClassManager.GetClassImpl(type);
                return(ifaceObj.TryWrapObject(value));
            }

            if (type.IsArray || type.IsEnum)
            {
                return(CLRObject.GetReference(value, type));
            }

            // it the type is a python subclass of a managed type then return the
            // underlying python object rather than construct a new wrapper object.
            var pyderived = value as IPythonDerivedType;

            if (null != pyderived)
            {
                if (!IsTransparentProxy(pyderived))
                {
                    return(ClassDerivedObject.ToPython(pyderived));
                }
            }

            // ModuleObjects are created in a way that their wrapping them as
            // a CLRObject fails, the ClassObject has no tpHandle. Return the
            // pyHandle as is, do not convert.
            if (value is ModuleObject modobj)
            {
                throw new NotImplementedException();
            }

            // hmm - from Python, we almost never care what the declared
            // type is. we'd rather have the object bound to the actual
            // implementing class.

            type = value.GetType();

            if (type.IsEnum)
            {
                return(CLRObject.GetReference(value, type));
            }

            TypeCode tc = Type.GetTypeCode(type);

            switch (tc)
            {
            case TypeCode.Object:
                return(CLRObject.GetReference(value, type));

            case TypeCode.String:
                return(Runtime.PyString_FromString((string)value));

            case TypeCode.Int32:
                return(Runtime.PyInt_FromInt32((int)value));

            case TypeCode.Boolean:
                if ((bool)value)
                {
                    return(new NewReference(Runtime.PyTrue));
                }
                return(new NewReference(Runtime.PyFalse));

            case TypeCode.Byte:
                return(Runtime.PyInt_FromInt32((byte)value));

            case TypeCode.Char:
                return(Runtime.PyUnicode_FromOrdinal((int)((char)value)));

            case TypeCode.Int16:
                return(Runtime.PyInt_FromInt32((short)value));

            case TypeCode.Int64:
                return(Runtime.PyLong_FromLongLong((long)value));

            case TypeCode.Single:
                return(Runtime.PyFloat_FromDouble((float)value));

            case TypeCode.Double:
                return(Runtime.PyFloat_FromDouble((double)value));

            case TypeCode.SByte:
                return(Runtime.PyInt_FromInt32((sbyte)value));

            case TypeCode.UInt16:
                return(Runtime.PyInt_FromInt32((ushort)value));

            case TypeCode.UInt32:
                return(Runtime.PyLong_FromUnsignedLongLong((uint)value));

            case TypeCode.UInt64:
                return(Runtime.PyLong_FromUnsignedLongLong((ulong)value));

            default:
                return(CLRObject.GetReference(value, type));
            }
        }