[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/attackgithub/pythonnet/mac-osx/src/runtime/classbase.cs [Back]  [Original]

using System;
using System.Collections;
using System.Reflection;
using System.Security;
using System.Runtime.InteropServices;

namespace Python.Runtime
{
    /// 
    /// Base class for Python types that reflect managed types / classes.
    /// Concrete subclasses include ClassObject and DelegateObject. This
    /// class provides common attributes and common machinery for doing
    /// class initialization (initialization of the class __dict__). The
    /// concrete subclasses provide slot implementations appropriate for
    /// each variety of reflected type.
    /// 
    internal class ClassBase : ManagedType
    {
        internal Indexer indexer;
        internal Type type;

        internal ClassBase(Type tp) : base()
        {
            indexer = null;
            type = tp;
        }

        internal virtual bool CanSubclass()
        {
            return (!this.type.IsEnum);
        }

        //====================================================================
        // Implements __init__ for reflected classes and value types.
        //====================================================================

        public static int tp_init(IntPtr ob, IntPtr args, IntPtr kw)
        {
            return 0;
        }

        //====================================================================
        // Default implementation of [] semantics for reflected types.
        //====================================================================

        public virtual IntPtr type_subscript(IntPtr idx)
        {
            Type[] types = Runtime.PythonArgsToTypeArray(idx);
            if (types == null)
            {
                return Exceptions.RaiseTypeError("type(s) expected");
            }

            Type target = GenericUtil.GenericForType(this.type, types.Length);

            if (target != null)
            {
                Type t = target.MakeGenericType(types);
                ManagedType c = (ManagedType)ClassManager.GetClass(t);
                Runtime.Incref(c.pyHandle);
                return c.pyHandle;
            }

            return Exceptions.RaiseTypeError("no type matches params");
        }

        //====================================================================
        // Standard comparison implementation for instances of reflected types.
        //====================================================================
#if (PYTHON32 || PYTHON33 || PYTHON34 || PYTHON35)
        public static IntPtr tp_richcompare(IntPtr ob, IntPtr other, int op) {
            if (op != Runtime.Py_EQ && op != Runtime.Py_NE)
            {
                Runtime.Incref(Runtime.PyNotImplemented);
                return Runtime.PyNotImplemented;
            }

            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.Incref(pytrue);
                return pytrue;
            }

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

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

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

            Runtime.Incref(pyfalse);
            return pyfalse;
        }
#else
        public static int tp_compare(IntPtr ob, IntPtr other)
        {
            if (ob == other)
            {
                return 0;
            }

            CLRObject co1 = GetManagedObject(ob) as CLRObject;
            CLRObject co2 = GetManagedObject(other) as CLRObject;
            Object o1 = co1.inst;
            Object o2 = co2.inst;

            if (Object.Equals(o1, o2))
            {
                return 0;
            }
            return -1;
        }
#endif


        //====================================================================
        // 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;
        }


        //====================================================================
        // 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());
        }


        //====================================================================
        // 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");
            }
            try
            {
                return Runtime.PyString_FromString(co.inst.ToString());
            }
            catch (Exception e)
            {
                if (e.InnerException != null)
                {
                    e = e.InnerException;
                }
                Exceptions.SetError(e);
                return IntPtr.Zero;
            }
        }


        //====================================================================
        // Default implementations for required Python GC support.
        //====================================================================

        public static int tp_traverse(IntPtr ob, IntPtr func, IntPtr args)
        {
            return 0;
        }

        public static int tp_clear(IntPtr ob)
        {
            return 0;
        }

        public static int tp_is_gc(IntPtr type)
        {
            return 1;
        }

        //====================================================================
        // Standard dealloc implementation for instances of reflected types.
        //====================================================================

        public static void tp_dealloc(IntPtr ob)
        {
            ManagedType self = GetManagedObject(ob);
            IntPtr dict = Marshal.ReadIntPtr(ob, ObjectOffset.DictOffset(ob));
            if (dict != IntPtr.Zero)
            {
                Runtime.Decref(dict);
            }
            Runtime.PyObject_GC_UnTrack(self.pyHandle);
            Runtime.PyObject_GC_Del(self.pyHandle);
            Runtime.Decref(self.tpHandle);
            self.gcHandle.Free();
        }
    }
}

Web Proxy Viewer  |  New URL  |  Original Page