PyObject_TYPE() static private method

static private PyObject_TYPE ( IntPtr op ) : IntPtr
op IntPtr
return IntPtr
Exemplo n.º 1
0
        internal static void DumpInst(IntPtr ob)
        {
            IntPtr tp = Runtime.PyObject_TYPE(ob);
            var    sz = (int)Marshal.ReadIntPtr(tp, TypeOffset.tp_basicsize);

            for (var i = 0; i < sz; i += IntPtr.Size)
            {
                var    pp = new IntPtr(ob.ToInt64() + i);
                IntPtr v  = Marshal.ReadIntPtr(pp);
                Console.WriteLine("offset {0}: {1}", i, v);
            }

            Console.WriteLine("");
            Console.WriteLine("");
        }
Exemplo n.º 2
0
 /// <summary>
 /// Given a Python object, return the associated managed object type or null.
 /// </summary>
 internal static ManagedType GetManagedObjectType(IntPtr ob)
 {
     if (ob != IntPtr.Zero)
     {
         IntPtr tp    = Runtime.PyObject_TYPE(ob);
         var    flags = (TypeFlags)Util.ReadCLong(tp, TypeOffset.tp_flags);
         if ((flags & TypeFlags.Managed) != 0)
         {
             tp = Marshal.ReadIntPtr(tp, TypeOffset.magic());
             var gc = (GCHandle)tp;
             return((ManagedType)gc.Target);
         }
     }
     return(null);
 }
Exemplo n.º 3
0
        internal static void DumpInst(BorrowedReference ob)
        {
            BorrowedReference tp = Runtime.PyObject_TYPE(ob);
            nint sz = Util.ReadIntPtr(tp, TypeOffset.tp_basicsize);

            for (nint i = 0; i < sz; i += IntPtr.Size)
            {
                var    pp = new IntPtr(ob.DangerousGetAddress().ToInt64() + i);
                IntPtr v  = Marshal.ReadIntPtr(pp);
                Console.WriteLine("offset {0}: {1}", i, v);
            }

            Console.WriteLine("");
            Console.WriteLine("");
        }
Exemplo n.º 4
0
        public static int tp_clear(IntPtr ob)
        {
            ManagedType self = GetManagedObject(ob);

            bool isTypeObject = Runtime.PyObject_TYPE(ob) == Runtime.PyCLRMetaType;

            if (!isTypeObject)
            {
                ClearObjectDict(ob);
            }
            if (self is not null)
            {
                self.tpHandle = IntPtr.Zero;
            }
            return(0);
        }
Exemplo n.º 5
0
        //====================================================================
        // Metatype __call__ implementation. This is needed to ensure correct
        // initialization (__init__ support), because the tp_call we inherit
        // from PyType_Type won't call __init__ for metatypes it doesnt know.
        //====================================================================

        public static IntPtr tp_call(IntPtr tp, IntPtr args, IntPtr kw)
        {
            IntPtr func = Marshal.ReadIntPtr(tp, TypeOffset.tp_new);

            if (func == IntPtr.Zero)
            {
                return(Exceptions.RaiseTypeError("invalid object"));
            }

            IntPtr obj = NativeCall.Call_3(func, tp, args, kw);

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

            IntPtr py__init__ = Runtime.PyString_FromString("__init__");
            IntPtr type       = Runtime.PyObject_TYPE(obj);
            IntPtr init       = Runtime._PyType_Lookup(type, py__init__);

            Runtime.Decref(py__init__);
            Runtime.PyErr_Clear();

            if (init != IntPtr.Zero)
            {
                IntPtr bound = Runtime.GetBoundArgTuple(obj, args);
                if (bound == IntPtr.Zero)
                {
                    Runtime.Decref(obj);
                    return(IntPtr.Zero);
                }

                IntPtr result = Runtime.PyObject_Call(init, bound, kw);
                Runtime.Decref(bound);

                if (result == IntPtr.Zero)
                {
                    Runtime.Decref(obj);
                    return(IntPtr.Zero);
                }

                Runtime.Decref(result);
            }

            return(obj);
        }
Exemplo n.º 6
0
        private static IntPtr DoInstanceCheck(IntPtr tp, IntPtr args, bool checkType)
        {
            var cb = GetManagedObject(tp) as ClassBase;

            if (cb == null)
            {
                Runtime.XIncref(Runtime.PyFalse);
                return(Runtime.PyFalse);
            }

            Runtime.XIncref(args);
            using (var argsObj = new PyList(args))
            {
                if (argsObj.Length() != 1)
                {
                    return(Exceptions.RaiseTypeError("Invalid parameter count"));
                }

                PyObject arg = argsObj[0];
                PyObject otherType;
                if (checkType)
                {
                    otherType = arg;
                }
                else
                {
                    otherType = arg.GetPythonType();
                }

                if (Runtime.PyObject_TYPE(otherType.Handle) != PyCLRMetaType)
                {
                    Runtime.XIncref(Runtime.PyFalse);
                    return(Runtime.PyFalse);
                }

                var otherCb = GetManagedObject(otherType.Handle) as ClassBase;
                if (otherCb == null)
                {
                    Runtime.XIncref(Runtime.PyFalse);
                    return(Runtime.PyFalse);
                }

                return(Converter.ToPython(cb.type.IsAssignableFrom(otherCb.type)));
            }
        }
Exemplo n.º 7
0
        public new static void tp_dealloc(IntPtr ob)
        {
            var 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);

            Debug.Assert(self.TypeReference == Runtime.PyObject_TYPE(self.ObjectReference));
            SetGCHandle(self.ObjectReference, self.TypeReference, gc);
            self.gcHandle.Free();
            self.gcHandle = gc;
        }
Exemplo n.º 8
0
        internal static bool IsManagedType(IntPtr ob)
        {
            if (ob != IntPtr.Zero)
            {
                IntPtr tp = Runtime.PyObject_TYPE(ob);
                if (tp == Runtime.PyTypeType || tp == Runtime.PyCLRMetaType)
                {
                    tp = ob;
                }

                int flags = (int)Marshal.ReadIntPtr(tp, TypeOffset.tp_flags);
                if ((flags & TypeFlags.Managed) != 0)
                {
                    return(true);
                }
            }
            return(false);
        }
Exemplo n.º 9
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <remarks>
        /// Create a scope based on a Python Module.
        /// </remarks>
        internal PyScope(IntPtr ptr, PyScopeManager manager)
        {
            if (!Runtime.Interop.PyType_IsSubtype(Runtime.PyObject_TYPE(ptr), Runtime.PyModuleType))
            {
                throw new PyScopeException("object is not a module");
            }
            Manager = manager ?? PyScopeManager.Global;
            obj     = ptr;
            //Refcount of the variables not increase
            variables = Runtime.Interop.PyModule_GetDict(obj);
            Runtime.CheckExceptionOccurred();

            Runtime.Interop.PyDict_SetItemString(
                variables, "__builtins__",
                Runtime.Interop.PyEval_GetBuiltins()
                );
            this.Name = this.Get <string>("__name__");
        }
Exemplo n.º 10
0
        //====================================================================
        // Implements __getitem__ for reflected classes and value types.
        //====================================================================

        public static IntPtr mp_subscript(IntPtr ob, IntPtr idx)
        {
            //ManagedType self = GetManagedObject(ob);
            IntPtr    tp  = Runtime.PyObject_TYPE(ob);
            ClassBase cls = (ClassBase)GetManagedObject(tp);

            if (cls.indexer == null || !cls.indexer.CanGet)
            {
                Exceptions.SetError(Exceptions.TypeError,
                                    "unindexable object"
                                    );
                return(IntPtr.Zero);
            }

            // Arg may be a tuple in the case of an indexer with multiple
            // parameters. If so, use it directly, else make a new tuple
            // with the index arg (method binders expect arg tuples).

            IntPtr args = idx;
            bool   free = false;

            if (!Runtime.PyTuple_Check(idx))
            {
                args = Runtime.PyTuple_New(1);
                Runtime.XIncref(idx);
                Runtime.PyTuple_SetItem(args, 0, idx);
                free = true;
            }

            IntPtr value = IntPtr.Zero;

            try
            {
                value = cls.indexer.GetItem(ob, args);
            }
            finally
            {
                if (free)
                {
                    Runtime.XDecref(args);
                }
            }
            return(value);
        }
Exemplo n.º 11
0
        /// <summary>
        /// Given a Python object, return the associated managed object or null.
        /// </summary>
        internal static ManagedType GetManagedObject(IntPtr ob)
        {
            if (ob != IntPtr.Zero)
            {
                IntPtr tp = Runtime.PyObject_TYPE(ob);
                if (tp == Runtime.PyTypeType || tp == Runtime.PyCLRMetaType)
                {
                    tp = ob;
                }

                var flags = (TypeFlags)Util.ReadCLong(tp, TypeOffset.tp_flags);
                if ((flags & TypeFlags.HasClrInstance) != 0)
                {
                    var gc = TryGetGCHandle(new BorrowedReference(ob));
                    return (ManagedType)gc?.Target;
                }
            }
            return null;
        }
Exemplo n.º 12
0
        //====================================================================
        // Implements __call__ for reflected delegate types.
        //====================================================================

        public static IntPtr tp_call(IntPtr ob, IntPtr args, IntPtr kw)
        {
            IntPtr         pytype = Runtime.PyObject_TYPE(ob);
            DelegateObject self   = (DelegateObject)GetManagedObject(pytype);
            CLRObject      o      = GetManagedObject(ob) as CLRObject;

            if (o == null)
            {
                return(Exceptions.RaiseTypeError("invalid argument"));
            }

            Delegate d = o.inst as Delegate;

            if (d == null)
            {
                return(Exceptions.RaiseTypeError("invalid argument"));
            }
            return(self.binder.Invoke(ob, args, kw));
        }
Exemplo n.º 13
0
        internal static unsafe void DecrefTypeAndFree(StolenReference ob)
        {
            if (ob == null)
            {
                throw new ArgumentNullException(nameof(ob));
            }
            var borrowed = new BorrowedReference(ob.DangerousGetAddress());

            var type = Runtime.PyObject_TYPE(borrowed);

            var freePtr = Util.ReadIntPtr(type, TypeOffset.tp_free);

            Debug.Assert(freePtr != IntPtr.Zero);
            var free = (delegate * unmanaged[Cdecl] < StolenReference, void >)freePtr;

            free(ob);

            Runtime.XDecref(StolenReference.DangerousFromPointer(type.DangerousGetAddress()));
        }
Exemplo n.º 14
0
        /// <summary>
        /// Implements __call__ for reflected delegate types.
        /// </summary>
        public static NewReference tp_call(BorrowedReference ob, BorrowedReference args, BorrowedReference kw)
        {
            // TODO: add fast type check!
            BorrowedReference pytype = Runtime.PyObject_TYPE(ob);
            var self = (DelegateObject)GetManagedObject(pytype) !;
            var o    = GetManagedObject(ob) as CLRObject;

            if (o == null)
            {
                return(Exceptions.RaiseTypeError("invalid argument"));
            }

            var d = o.inst as Delegate;

            if (d == null)
            {
                return(Exceptions.RaiseTypeError("invalid argument"));
            }
            return(self.binder.Invoke(ob, args, kw));
        }
Exemplo n.º 15
0
        /// <summary>
        /// Implements __call__ for reflected delegate types.
        /// </summary>
        public static IntPtr tp_call(IntPtr ob, IntPtr args, IntPtr kw)
        {
            // TODO: add fast type check!
            IntPtr pytype = Runtime.PyObject_TYPE(ob);
            var self = (DelegateObject)GetManagedObject(pytype);
            var o = GetManagedObject(ob) as CLRObject;

            if (o == null)
            {
                return Exceptions.RaiseTypeError("invalid argument");
            }

            var d = o.inst as Delegate;

            if (d == null)
            {
                return Exceptions.RaiseTypeError("invalid argument");
            }
            return self.binder.Invoke(ob, args, kw);
        }
Exemplo n.º 16
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <remarks>
        /// Create a scope based on a Python Module.
        /// </remarks>
        internal PyScope(ref NewReference ptr, PyScopeManager manager)
        {
            if (!Runtime.PyType_IsSubtype(Runtime.PyObject_TYPE(ptr), Runtime.PyModuleType))
            {
                throw new PyScopeException("object is not a module");
            }
            Manager = manager ?? PyScopeManager.Global;
            obj     = ptr.MoveToPyObject();
            //Refcount of the variables not increase
            variables = Runtime.PyModule_GetDict(Reference).DangerousGetAddress();
            PythonException.ThrowIfIsNull(variables);

            int res = Runtime.PyDict_SetItem(
                VarsRef, PyIdentifier.__builtins__,
                Runtime.PyEval_GetBuiltins()
                );

            PythonException.ThrowIfIsNotZero(res);
            this.Name = this.Get <string>("__name__");
        }
Exemplo n.º 17
0
        internal static IntPtr GetExceptionInstanceWrapper(IntPtr real)
        {
            // Given the pointer to a new-style class instance representing a
            // managed exception, return an appropriate old-style class
            // wrapper instance that delegates to the wrapped instance.
            IntPtr tp = Runtime.PyObject_TYPE(real);

            if (Runtime.PyObject_TYPE(tp) == Runtime.PyInstanceType)
            {
                return(real);
            }
            // Get / generate a class wrapper, instantiate it and set its
            // _inner attribute to the real new-style exception instance.
            IntPtr ct = GetExceptionClassWrapper(tp);
            IntPtr op = Runtime.PyInstance_NewRaw(ct, IntPtr.Zero);
            IntPtr d  = Runtime.PyObject_GetAttrString(op, "__dict__");

            Runtime.PyDict_SetItemString(d, "_inner", real);
            Runtime.Decref(d);
            return(op);
        }
Exemplo n.º 18
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 bool SetError(Exception e)
        {
            Debug.Assert(e is not null);

            // 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)
            {
                pe.Restore();
                return(true);
            }

            using var instance = Converter.ToPythonReference(e);
            if (instance.IsNull())
            {
                return(false);
            }

            var exceptionInfo = ExceptionDispatchInfo.Capture(e);

            using var pyInfo = Converter.ToPythonReference(exceptionInfo);

            if (Runtime.PyObject_SetAttrString(instance, DispatchInfoAttribute, pyInfo) != 0)
            {
                return(false);
            }

            Debug.Assert(Runtime.PyObject_TypeCheck(instance, new BorrowedReference(BaseException)));

            var type = Runtime.PyObject_TYPE(instance);

            Runtime.PyErr_SetObject(type, instance);
            return(true);
        }
Exemplo n.º 19
0
        internal IntPtr tpHandle;   // PyType *


        //====================================================================
        // Given a Python object, return the associated managed object or null.
        //====================================================================

        internal static ManagedType GetManagedObject(IntPtr ob)
        {
            if (ob != IntPtr.Zero)
            {
                IntPtr tp = Runtime.PyObject_TYPE(ob);
                if (tp == Runtime.PyTypeType || tp == Runtime.PyCLRMetaType)
                {
                    tp = ob;
                }

                int flags = (int)Marshal.ReadIntPtr(tp, TypeOffset.tp_flags);
                if ((flags & TypeFlags.Managed) != 0)
                {
                    IntPtr op = (tp == ob)
                        ? Marshal.ReadIntPtr(tp, TypeOffset.magic())
                        : Marshal.ReadIntPtr(ob, ObjectOffset.magic(ob));
                    GCHandle gc = (GCHandle)op;
                    return((ManagedType)gc.Target);
                }
            }
            return(null);
        }
Exemplo n.º 20
0
        internal IntPtr tpHandle;   // PyType *


        //====================================================================
        // Given a Python object, return the associated managed object or null.
        //====================================================================

        internal static ManagedType GetManagedObject(IntPtr ob)
        {
            if (ob != IntPtr.Zero)
            {
                IntPtr tp = Runtime.PyObject_TYPE(ob);
                if (tp == Runtime.PyTypeType || tp == Runtime.PyCLRMetaType)
                {
                    tp = ob;
                }

                int flags = (int)Marshal.ReadIntPtr(tp, TypeOffset.tp_flags);
                if ((flags & TypeFlags.Managed) != 0)
                {
                    IntPtr op = (tp == ob) ?
                                Marshal.ReadIntPtr(tp, TypeOffset.magic()) :
                                Marshal.ReadIntPtr(ob, ObjectOffset.magic());
                    GCHandle gc = (GCHandle)op;
                    return((ManagedType)gc.Target);
                }

                // In certain situations, we need to recognize a wrapped
                // exception class and be willing to unwrap the class :(

                if (Runtime.wrap_exceptions)
                {
                    IntPtr e = Exceptions.UnwrapExceptionClass(ob);
                    if ((e != IntPtr.Zero) && (e != ob))
                    {
                        ManagedType m = GetManagedObject(e);
                        Runtime.Decref(e);
                        return(m);
                    }
                }
            }
            return(null);
        }
Exemplo n.º 21
0
        //====================================================================
        // Type __setattr__ implementation for reflected types. Note that this
        // is slightly different than the standard setattr implementation for
        // the normal Python metatype (PyTypeType). We need to look first in
        // the type object of a reflected type for a descriptor in order to
        // support the right setattr behavior for static fields and properties.
        //====================================================================

        public static int tp_setattro(IntPtr tp, IntPtr name, IntPtr value)
        {
            IntPtr descr = Runtime._PyType_Lookup(tp, name);

            if (descr != IntPtr.Zero)
            {
                IntPtr dt = Runtime.PyObject_TYPE(descr);
                IntPtr fp = Marshal.ReadIntPtr(dt, TypeOffset.tp_descr_set);
                if (fp != IntPtr.Zero)
                {
                    return(NativeCall.Impl.Int_Call_3(fp, descr, name, value));
                }
                Exceptions.SetError(Exceptions.AttributeError,
                                    "attribute is read-only");
                return(-1);
            }

            if (Runtime.PyObject_GenericSetAttr(tp, name, value) < 0)
            {
                return(-1);
            }

            return(0);
        }
Exemplo n.º 22
0
        /// <summary>
        /// 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.
        /// </summary>
        public static IntPtr tp_call(IntPtr ob, IntPtr args, IntPtr kw)
        {
            //ManagedType self = GetManagedObject(ob);
            IntPtr tp = Runtime.PyObject_TYPE(ob);
            var    cb = (ClassBase)GetManagedObject(tp);

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

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

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

            return(binder.Invoke(ob, args, kw));
        }
Exemplo n.º 23
0
        internal IntPtr tpHandle;   // PyType *


        /// <summary>
        /// Given a Python object, return the associated managed object or null.
        /// </summary>
        internal static ManagedType GetManagedObject(IntPtr ob)
        {
            if (ob != IntPtr.Zero)
            {
                IntPtr tp = Runtime.PyObject_TYPE(ob);
                if (tp == Runtime.PyTypeType || tp == Runtime.PyCLRMetaType)
                {
                    tp = ob;
                }

                var flags = Util.ReadCLong(tp, TypeOffset.tp_flags);
                if ((flags & TypeFlags.Managed) != 0)
                {
                    IntPtr op = tp == ob
                        ? Marshal.ReadIntPtr(tp, TypeOffset.magic())
                        : Marshal.ReadIntPtr(ob, ObjectOffset.magic(ob));

                    var gc = (GCHandle)op;
                    // Console.WriteLine("GetManagedObject " + gc.Target);
                    return((ManagedType)gc.Target);
                }
            }
            return(null);
        }
Exemplo n.º 24
0
        internal static bool ToManagedValue(IntPtr value, Type obType,
                                            out object result, bool setError)
        {
            if (obType == typeof(PyObject))
            {
                Runtime.XIncref(value); // PyObject() assumes ownership
                result = new PyObject(value);
                return(true);
            }

            // Common case: if the Python value is a wrapped managed object
            // instance, just return the wrapped object.
            ManagedType mt = ManagedType.GetManagedObject(value);

            result = null;

            if (mt != null)
            {
                if (mt is CLRObject)
                {
                    object tmp = ((CLRObject)mt).inst;
                    if (obType.IsInstanceOfType(tmp))
                    {
                        result = tmp;
                        return(true);
                    }
                    Exceptions.SetError(Exceptions.TypeError, $"value cannot be converted to {obType}");
                    return(false);
                }
                if (mt is ClassBase)
                {
                    var cb = (ClassBase)mt;
                    if (!cb.type.Valid)
                    {
                        Exceptions.SetError(Exceptions.TypeError, cb.type.DeletedMessage);
                        return(false);
                    }
                    result = cb.type.Value;
                    return(true);
                }
                // shouldn't happen
                return(false);
            }

            if (value == Runtime.PyNone && !obType.IsValueType)
            {
                result = null;
                return(true);
            }

            if (obType.IsGenericType && obType.GetGenericTypeDefinition() == typeof(Nullable <>))
            {
                if (value == Runtime.PyNone)
                {
                    result = null;
                    return(true);
                }
                // Set type to underlying type
                obType = obType.GetGenericArguments()[0];
            }

            if (obType.IsArray)
            {
                return(ToArray(value, obType, out result, setError));
            }

            if (obType.IsEnum)
            {
                return(ToEnum(value, obType, out result, setError));
            }

            // Conversion to 'Object' is done based on some reasonable default
            // conversions (Python string -> managed string, Python int -> Int32 etc.).
            if (obType == objectType)
            {
                if (Runtime.IsStringType(value))
                {
                    return(ToPrimitive(value, stringType, out result, setError));
                }

                if (Runtime.PyBool_Check(value))
                {
                    return(ToPrimitive(value, boolType, out result, setError));
                }

                if (Runtime.PyInt_Check(value))
                {
                    return(ToPrimitive(value, int32Type, out result, setError));
                }

                if (Runtime.PyLong_Check(value))
                {
                    return(ToPrimitive(value, int64Type, out result, setError));
                }

                if (Runtime.PyFloat_Check(value))
                {
                    return(ToPrimitive(value, doubleType, out result, setError));
                }

                // give custom codecs a chance to take over conversion of sequences
                IntPtr pyType = Runtime.PyObject_TYPE(value);
                if (PyObjectConversions.TryDecode(value, pyType, obType, out result))
                {
                    return(true);
                }

                if (Runtime.PySequence_Check(value))
                {
                    return(ToArray(value, typeof(object[]), out result, setError));
                }

                Runtime.XIncref(value); // PyObject() assumes ownership
                result = new PyObject(value);
                return(true);
            }

            // Conversion to 'Type' is done using the same mappings as above for objects.
            if (obType == typeType)
            {
                if (value == Runtime.PyStringType)
                {
                    result = stringType;
                    return(true);
                }

                if (value == Runtime.PyBoolType)
                {
                    result = boolType;
                    return(true);
                }

                if (value == Runtime.PyIntType)
                {
                    result = int32Type;
                    return(true);
                }

                if (value == Runtime.PyLongType)
                {
                    result = int64Type;
                    return(true);
                }

                if (value == Runtime.PyFloatType)
                {
                    result = doubleType;
                    return(true);
                }

                if (value == Runtime.PyListType || value == Runtime.PyTupleType)
                {
                    result = typeof(object[]);
                    return(true);
                }

                if (setError)
                {
                    Exceptions.SetError(Exceptions.TypeError, "value cannot be converted to Type");
                }

                return(false);
            }

            TypeCode typeCode = Type.GetTypeCode(obType);

            if (typeCode == TypeCode.Object)
            {
                IntPtr pyType = Runtime.PyObject_TYPE(value);
                if (PyObjectConversions.TryDecode(value, pyType, obType, out result))
                {
                    return(true);
                }
            }

            return(ToPrimitive(value, obType, out result, setError));
        }
Exemplo n.º 25
0
        /// <summary>
        /// Implements __setitem__ for reflected classes and value types.
        /// </summary>
        public static int mp_ass_subscript(IntPtr ob, IntPtr idx, IntPtr v)
        {
            IntPtr tp  = Runtime.PyObject_TYPE(ob);
            var    cls = (ClassBase)GetManagedObject(tp);

            if (cls.indexer == null || !cls.indexer.CanSet)
            {
                Exceptions.SetError(Exceptions.TypeError, "object doesn't support item assignment");
                return(-1);
            }

            // Arg may be a tuple in the case of an indexer with multiple
            // parameters. If so, use it directly, else make a new tuple
            // with the index arg (method binders expect arg tuples).
            IntPtr args = idx;
            var    free = false;

            if (!Runtime.PyTuple_Check(idx))
            {
                args = Runtime.PyTuple_New(1);
                Runtime.XIncref(idx);
                Runtime.PyTuple_SetItem(args, 0, idx);
                free = true;
            }

            // Get the args passed in.
            var    i                = Runtime.PyTuple_Size(args);
            IntPtr defaultArgs      = cls.indexer.GetDefaultArgs(args);
            var    numOfDefaultArgs = Runtime.PyTuple_Size(defaultArgs);
            var    temp             = i + numOfDefaultArgs;
            IntPtr real             = Runtime.PyTuple_New(temp + 1);

            for (var n = 0; n < i; n++)
            {
                IntPtr item = Runtime.PyTuple_GetItem(args, n);
                Runtime.XIncref(item);
                Runtime.PyTuple_SetItem(real, n, item);
            }

            // Add Default Args if needed
            for (var n = 0; n < numOfDefaultArgs; n++)
            {
                IntPtr item = Runtime.PyTuple_GetItem(defaultArgs, n);
                Runtime.XIncref(item);
                Runtime.PyTuple_SetItem(real, n + i, item);
            }
            // no longer need defaultArgs
            Runtime.XDecref(defaultArgs);
            i = temp;

            // Add value to argument list
            Runtime.XIncref(v);
            Runtime.PyTuple_SetItem(real, i, v);

            try
            {
                cls.indexer.SetItem(ob, real);
            }
            finally
            {
                Runtime.XDecref(real);

                if (free)
                {
                    Runtime.XDecref(args);
                }
            }

            if (Exceptions.ErrorOccurred())
            {
                return(-1);
            }

            return(0);
        }
Exemplo n.º 26
0
        /// <summary>
        /// Convert a Python value to an instance of a primitive managed type.
        /// </summary>
        private static bool ToPrimitive(IntPtr value, Type obType, out object result, bool setError)
        {
            TypeCode tc = Type.GetTypeCode(obType);

            result = null;
            IntPtr op = IntPtr.Zero;

            switch (tc)
            {
            case TypeCode.String:
                string st = Runtime.GetManagedString(value);
                if (st == null)
                {
                    goto type_error;
                }
                result = st;
                return(true);

            case TypeCode.Int32:
            {
                // Python3 always use PyLong API
                long num = Runtime.PyLong_AsLongLong(value);
                if (num == -1 && Exceptions.ErrorOccurred())
                {
                    goto convert_error;
                }
                if (num > Int32.MaxValue || num < Int32.MinValue)
                {
                    goto overflow;
                }
                result = (int)num;
                return(true);
            }

            case TypeCode.Boolean:
                result = Runtime.PyObject_IsTrue(value) != 0;
                return(true);

            case TypeCode.Byte:
            {
                if (Runtime.PyObject_TypeCheck(value, Runtime.PyBytesType))
                {
                    if (Runtime.PyBytes_Size(value) == 1)
                    {
                        op     = Runtime.PyBytes_AS_STRING(value);
                        result = (byte)Marshal.ReadByte(op);
                        return(true);
                    }
                    goto type_error;
                }

                int num = Runtime.PyLong_AsLong(value);
                if (num == -1 && Exceptions.ErrorOccurred())
                {
                    goto convert_error;
                }
                if (num > Byte.MaxValue || num < Byte.MinValue)
                {
                    goto overflow;
                }
                result = (byte)num;
                return(true);
            }

            case TypeCode.SByte:
            {
                if (Runtime.PyObject_TypeCheck(value, Runtime.PyBytesType))
                {
                    if (Runtime.PyBytes_Size(value) == 1)
                    {
                        op     = Runtime.PyBytes_AS_STRING(value);
                        result = (byte)Marshal.ReadByte(op);
                        return(true);
                    }
                    goto type_error;
                }

                int num = Runtime.PyLong_AsLong(value);
                if (num == -1 && Exceptions.ErrorOccurred())
                {
                    goto convert_error;
                }
                if (num > SByte.MaxValue || num < SByte.MinValue)
                {
                    goto overflow;
                }
                result = (sbyte)num;
                return(true);
            }

            case TypeCode.Char:
            {
                if (Runtime.PyObject_TypeCheck(value, Runtime.PyBytesType))
                {
                    if (Runtime.PyBytes_Size(value) == 1)
                    {
                        op     = Runtime.PyBytes_AS_STRING(value);
                        result = (byte)Marshal.ReadByte(op);
                        return(true);
                    }
                    goto type_error;
                }
                else if (Runtime.PyObject_TypeCheck(value, Runtime.PyUnicodeType))
                {
                    if (Runtime.PyUnicode_GetSize(value) == 1)
                    {
                        op = Runtime.PyUnicode_AsUnicode(value);
                        Char[] buff = new Char[1];
                        Marshal.Copy(op, buff, 0, 1);
                        result = buff[0];
                        return(true);
                    }
                    goto type_error;
                }
                int num = Runtime.PyLong_AsLong(value);
                if (num == -1 && Exceptions.ErrorOccurred())
                {
                    goto convert_error;
                }
                if (num > Char.MaxValue || num < Char.MinValue)
                {
                    goto overflow;
                }
                result = (char)num;
                return(true);
            }

            case TypeCode.Int16:
            {
                int num = Runtime.PyLong_AsLong(value);
                if (num == -1 && Exceptions.ErrorOccurred())
                {
                    goto convert_error;
                }
                if (num > Int16.MaxValue || num < Int16.MinValue)
                {
                    goto overflow;
                }
                result = (short)num;
                return(true);
            }

            case TypeCode.Int64:
            {
                long num = (long)Runtime.PyLong_AsLongLong(value);
                if (num == -1 && Exceptions.ErrorOccurred())
                {
                    goto convert_error;
                }
                result = num;
                return(true);
            }

            case TypeCode.UInt16:
            {
                long num = Runtime.PyLong_AsLong(value);
                if (num == -1 && Exceptions.ErrorOccurred())
                {
                    goto convert_error;
                }
                if (num > UInt16.MaxValue || num < UInt16.MinValue)
                {
                    goto overflow;
                }
                result = (ushort)num;
                return(true);
            }

            case TypeCode.UInt32:
            {
                op = value;
                if (Runtime.PyObject_TYPE(value) != Runtime.PyLongType)
                {
                    op = Runtime.PyNumber_Long(value);
                    if (op == IntPtr.Zero)
                    {
                        goto convert_error;
                    }
                }
                if (Runtime.Is32Bit || Runtime.IsWindows)
                {
                    uint num = Runtime.PyLong_AsUnsignedLong32(op);
                    if (num == uint.MaxValue && Exceptions.ErrorOccurred())
                    {
                        goto convert_error;
                    }
                    result = num;
                }
                else
                {
                    ulong num = Runtime.PyLong_AsUnsignedLong64(op);
                    if (num == ulong.MaxValue && Exceptions.ErrorOccurred())
                    {
                        goto convert_error;
                    }
                    try
                    {
                        result = Convert.ToUInt32(num);
                    }
                    catch (OverflowException)
                    {
                        // Probably wasn't an overflow in python but was in C# (e.g. if cpython
                        // longs are 64 bit then 0xFFFFFFFF + 1 will not overflow in
                        // PyLong_AsUnsignedLong)
                        goto overflow;
                    }
                }
                return(true);
            }

            case TypeCode.UInt64:
            {
                op = value;
                if (Runtime.PyObject_TYPE(value) != Runtime.PyLongType)
                {
                    op = Runtime.PyNumber_Long(value);
                    if (op == IntPtr.Zero)
                    {
                        goto convert_error;
                    }
                }
                ulong num = Runtime.PyLong_AsUnsignedLongLong(op);
                if (num == ulong.MaxValue && Exceptions.ErrorOccurred())
                {
                    goto overflow;
                }
                result = num;
                return(true);
            }

            case TypeCode.Single:
            {
                double num = Runtime.PyFloat_AsDouble(value);
                if (num == -1.0 && Exceptions.ErrorOccurred())
                {
                    goto convert_error;
                }
                if (num > Single.MaxValue || num < Single.MinValue)
                {
                    if (!double.IsInfinity(num))
                    {
                        goto overflow;
                    }
                }
                result = (float)num;
                return(true);
            }

            case TypeCode.Double:
            {
                double num = Runtime.PyFloat_AsDouble(value);
                if (num == -1.0 && Exceptions.ErrorOccurred())
                {
                    goto convert_error;
                }
                result = num;
                return(true);
            }

            default:
                goto type_error;
            }

convert_error:
            if (op != value)
            {
                Runtime.XDecref(op);
            }
            if (!setError)
            {
                Exceptions.Clear();
            }
            return(false);

type_error:
            if (setError)
            {
                string tpName = Runtime.PyObject_GetTypeName(value);
                Exceptions.SetError(Exceptions.TypeError, $"'{tpName}' value cannot be converted to {obType}");
            }
            return(false);

overflow:
            // C# level overflow error
            if (op != value)
            {
                Runtime.XDecref(op);
            }
            if (setError)
            {
                Exceptions.SetError(Exceptions.OverflowError, "value too large to convert");
            }
            return(false);
        }
Exemplo n.º 27
0
        /// <summary>
        /// Standard comparison implementation for instances of reflected types.
        /// </summary>
        public static IntPtr tp_richcompare(IntPtr ob, IntPtr other, int op)
        {
            CLRObject co1;
            CLRObject co2;
            IntPtr    tp  = Runtime.PyObject_TYPE(ob);
            var       cls = (ClassBase)GetManagedObject(tp);

            // C# operator methods take precedence over IComparable.
            // We first check if there's a comparison operator by looking up the richcompare table,
            // otherwise fallback to checking if an IComparable interface is handled.
            if (cls.richcompare.TryGetValue(op, out var methodObject))
            {
                // Wrap the `other` argument of a binary comparison operator in a PyTuple.
                IntPtr args = Runtime.PyTuple_New(1);
                Runtime.XIncref(other);
                Runtime.PyTuple_SetItem(args, 0, other);

                IntPtr value;
                try
                {
                    value = methodObject.Invoke(ob, args, IntPtr.Zero);
                }
                finally
                {
                    Runtime.XDecref(args);  // Free args pytuple
                }
                return(value);
            }

            switch (op)
            {
            case Runtime.Py_EQ:
            case Runtime.Py_NE:
                IntPtr pytrue  = Runtime.PyTrue;
                IntPtr pyfalse = Runtime.PyFalse;

                // swap true and false for NE
                if (op != Runtime.Py_EQ)
                {
                    pytrue  = Runtime.PyFalse;
                    pyfalse = Runtime.PyTrue;
                }

                if (ob == other)
                {
                    Runtime.XIncref(pytrue);
                    return(pytrue);
                }

                co1 = GetManagedObject(ob) as CLRObject;
                co2 = GetManagedObject(other) as CLRObject;
                if (null == co2)
                {
                    Runtime.XIncref(pyfalse);
                    return(pyfalse);
                }

                object o1 = co1.inst;
                object o2 = co2.inst;

                if (Equals(o1, o2))
                {
                    Runtime.XIncref(pytrue);
                    return(pytrue);
                }

                Runtime.XIncref(pyfalse);
                return(pyfalse);

            case Runtime.Py_LT:
            case Runtime.Py_LE:
            case Runtime.Py_GT:
            case Runtime.Py_GE:
                co1 = GetManagedObject(ob) as CLRObject;
                co2 = GetManagedObject(other) as CLRObject;
                if (co1 == null || co2 == null)
                {
                    return(Exceptions.RaiseTypeError("Cannot get managed object"));
                }
                var co1Comp = co1.inst as IComparable;
                if (co1Comp == null)
                {
                    Type co1Type = co1.GetType();
                    return(Exceptions.RaiseTypeError($"Cannot convert object of type {co1Type} to IComparable"));
                }
                try
                {
                    int cmp = co1Comp.CompareTo(co2.inst);

                    IntPtr pyCmp;
                    if (cmp < 0)
                    {
                        if (op == Runtime.Py_LT || op == Runtime.Py_LE)
                        {
                            pyCmp = Runtime.PyTrue;
                        }
                        else
                        {
                            pyCmp = Runtime.PyFalse;
                        }
                    }
                    else if (cmp == 0)
                    {
                        if (op == Runtime.Py_LE || op == Runtime.Py_GE)
                        {
                            pyCmp = Runtime.PyTrue;
                        }
                        else
                        {
                            pyCmp = Runtime.PyFalse;
                        }
                    }
                    else
                    {
                        if (op == Runtime.Py_GE || op == Runtime.Py_GT)
                        {
                            pyCmp = Runtime.PyTrue;
                        }
                        else
                        {
                            pyCmp = Runtime.PyFalse;
                        }
                    }
                    Runtime.XIncref(pyCmp);
                    return(pyCmp);
                }
                catch (ArgumentException e)
                {
                    return(Exceptions.RaiseTypeError(e.Message));
                }

            default:
                Runtime.XIncref(Runtime.PyNotImplemented);
                return(Runtime.PyNotImplemented);
            }
        }
Exemplo n.º 28
0
        /// <summary>
        /// MethodBinding  __call__ implementation.
        /// </summary>
        public static IntPtr tp_call(IntPtr ob, IntPtr args, IntPtr kw)
        {
            var self = (MethodBinding)GetManagedObject(ob);

            // This works around a situation where the wrong generic method is picked,
            // for example this method in the tests: string Overloaded<T>(int arg1, int arg2, string arg3)
            if (self.info != null)
            {
                if (self.info.IsGenericMethod)
                {
                    var    len   = Runtime.PyTuple_Size(args); //FIXME: Never used
                    Type[] sigTp = Runtime.PythonArgsToTypeArray(args, true);
                    if (sigTp != null)
                    {
                        Type[]     genericTp   = self.info.GetGenericArguments();
                        MethodInfo betterMatch = MethodBinder.MatchSignatureAndParameters(self.m.info, genericTp, sigTp);
                        if (betterMatch != null)
                        {
                            self.info = betterMatch;
                        }
                    }
                }
            }

            // This supports calling a method 'unbound', passing the instance
            // as the first argument. Note that this is not supported if any
            // of the overloads are static since we can't know if the intent
            // was to call the static method or the unbound instance method.
            var disposeList = new List <IntPtr>();

            try
            {
                IntPtr target = self.target;

                if (target == IntPtr.Zero && !self.m.IsStatic())
                {
                    var len = Runtime.PyTuple_Size(args);
                    if (len < 1)
                    {
                        Exceptions.SetError(Exceptions.TypeError, "not enough arguments");
                        return(IntPtr.Zero);
                    }
                    target = Runtime.PyTuple_GetItem(args, 0);
                    Runtime.XIncref(target);
                    disposeList.Add(target);

                    args = Runtime.PyTuple_GetSlice(args, 1, len);
                    disposeList.Add(args);
                }

                // if the class is a IPythonDerivedClass and target is not the same as self.targetType
                // (eg if calling the base class method) then call the original base class method instead
                // of the target method.
                IntPtr superType = IntPtr.Zero;
                if (Runtime.PyObject_TYPE(target) != self.targetType)
                {
                    var inst = GetManagedObject(target) as CLRObject;
                    if (inst?.inst is IPythonDerivedType)
                    {
                        var baseType = GetManagedObject(self.targetType) as ClassBase;
                        if (baseType != null)
                        {
                            string baseMethodName = "_" + baseType.type.Name + "__" + self.m.name;
                            IntPtr baseMethod     = Runtime.PyObject_GetAttrString(target, baseMethodName);
                            if (baseMethod != IntPtr.Zero)
                            {
                                var baseSelf = GetManagedObject(baseMethod) as MethodBinding;
                                if (baseSelf != null)
                                {
                                    self = baseSelf;
                                }
                                Runtime.XDecref(baseMethod);
                            }
                            else
                            {
                                Runtime.PyErr_Clear();
                            }
                        }
                    }
                }

                return(self.m.Invoke(target, args, kw, self.info));
            }
            finally
            {
                foreach (IntPtr ptr in disposeList)
                {
                    Runtime.XDecref(ptr);
                }
            }
        }
Exemplo n.º 29
0
        protected static void SetObjectDict(IntPtr ob, IntPtr value)
        {
            IntPtr type = Runtime.PyObject_TYPE(ob);

            Marshal.WriteIntPtr(ob, ObjectOffset.TypeDictOffset(type), value);
        }
Exemplo n.º 30
0
        protected static IntPtr GetObjectDict(IntPtr ob)
        {
            IntPtr type = Runtime.PyObject_TYPE(ob);

            return(Marshal.ReadIntPtr(ob, ObjectOffset.TypeDictOffset(type)));
        }