Beispiel #1
0
        //====================================================================
        // Create a new ClassBase-derived instance that implements a reflected
        // managed type. The new object will be associated with a generated
        // Python type object.
        //====================================================================
        private static ClassBase CreateClass(Type type)
        {
            // Next, select the appropriate managed implementation class.
            // Different kinds of types, such as array types or interface
            // types, want to vary certain implementation details to make
            // sure that the type semantics are consistent in Python.

            ClassBase impl;

            // Check to see if the given type extends System.Exception. This
            // lets us check once (vs. on every lookup) in case we need to
            // wrap Exception-derived types in old-style classes

            if (type.ContainsGenericParameters)
            {
                impl = new GenericType(type);
            }

            else if (type.IsSubclassOf(dtype))
            {
                impl = new DelegateObject(type);
            }

            else if (type.IsArray)
            {
                impl = new ArrayObject(type);
            }

            else if (type.IsInterface)
            {
                impl = new InterfaceObject(type);
            }

            else if (type == typeof(Exception) ||
                     type.IsSubclassOf(typeof(Exception)))
            {
                impl = new ExceptionClassObject(type);
            }

            else if (null != type.GetField("__pyobj__"))
            {
                impl = new ClassDerivedObject(type);
            }

            else
            {
                impl = new ClassObject(type);
            }

            return impl;
        }
        //====================================================================
        // Create a new ClassBase-derived instance that implements a reflected
        // managed type. The new object will be associated with a generated
        // Python type object.
        //====================================================================
        private static ClassBase CreateClass(Type type)
        {
            // First, we introspect the managed type and build some class
            // information, including generating the member descriptors
            // that we'll be putting in the Python class __dict__.

            ClassInfo info = GetClassInfo(type);

            // Next, select the appropriate managed implementation class.
            // Different kinds of types, such as array types or interface
            // types, want to vary certain implementation details to make
            // sure that the type semantics are consistent in Python.

            ClassBase impl;

            // Check to see if the given type extends System.Exception. This
            // lets us check once (vs. on every lookup) in case we need to
            // wrap Exception-derived types in old-style classes

            if (type.ContainsGenericParameters) {
                impl = new GenericType(type);
            }

            else if (type.IsSubclassOf(dtype)) {
                impl = new DelegateObject(type);
            }

            else if (type.IsArray) {
                impl = new ArrayObject(type);
            }

            else if (type.IsInterface) {
                impl = new InterfaceObject(type);
            }

            else if (type == typeof(Exception) ||
                    type.IsSubclassOf(typeof(Exception))) {
                impl = new ExceptionClassObject(type);
            }

            else if (null != type.GetField("__pyobj__")) {
                impl = new ClassDerivedObject(type);
            }

            else
            {
                impl = new ClassObject(type);
            }

            impl.indexer = info.indexer;

            // Now we allocate the Python type object to reflect the given
            // managed type, filling the Python type slots with thunks that
            // point to the managed methods providing the implementation.

            IntPtr tp = TypeManager.GetTypeHandle(impl, type);
            impl.tpHandle = tp;

            // Finally, initialize the class __dict__ and return the object.
            IntPtr dict = Marshal.ReadIntPtr(tp, TypeOffset.tp_dict);

            IDictionaryEnumerator iter = info.members.GetEnumerator();
            while(iter.MoveNext()) {
                ManagedType item = (ManagedType)iter.Value;
                string name = (string)iter.Key;
                Runtime.PyDict_SetItemString(dict, name, item.pyHandle);
            }

            // If class has constructors, generate an __doc__ attribute.

            IntPtr doc;
            Type marker = typeof(DocStringAttribute);
            Attribute[] attrs = (Attribute[])type.GetCustomAttributes(marker, false);
            if (attrs.Length == 0) {
                doc = IntPtr.Zero;
            }
            else {
                DocStringAttribute attr = (DocStringAttribute)attrs[0];
                string docStr = attr.DocString;
                doc = Runtime.PyString_FromString(docStr);
                Runtime.PyDict_SetItemString(dict, "__doc__", doc);
                Runtime.Decref(doc);
            }

            ClassObject co = impl as ClassObject;
            // If this is a ClassObject AND it has constructors, generate a __doc__ attribute.
            // required that the ClassObject.ctors be changed to internal
            if (co != null) {
                if (co.ctors.Length > 0) {
                    // Implement Overloads on the class object
                    if (!CLRModule._SuppressOverloads)
                    {
                        ConstructorBinding ctors = new ConstructorBinding(type, tp, co.binder);
                        // ExtensionType types are untracked, so don't Incref() them.
                        // XXX deprecate __overloads__ soon...
                        Runtime.PyDict_SetItemString(dict, "__overloads__", ctors.pyHandle);
                        Runtime.PyDict_SetItemString(dict, "Overloads", ctors.pyHandle);
                    }
                    if (!CLRModule._SuppressDocs)
                    {
                        doc = co.GetDocString();
                        Runtime.PyDict_SetItemString(dict, "__doc__", doc);
                        Runtime.Decref(doc);
                    }
                }
            }

            return impl;
        }