[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/chid/pythonnet/develop/pythonnet/src/runtime/generictype.cs [Back]  [Original]

// ==========================================================================
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.
// ==========================================================================

using System;
using System.Reflection;

namespace Python.Runtime {

    /// 
    /// Implements reflected generic types. Note that the Python behavior
    /// is the same for both generic type definitions and constructed open
    /// generic types. Both are essentially factories for creating closed
    /// types based on the required generic type parameters.
    /// 

    internal class GenericType : ClassBase {

        internal GenericType(Type tp) : base(tp) {}

        //====================================================================
        // Implements __new__ for reflected generic types.
        //====================================================================

        public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw) {
            Exceptions.SetError(Exceptions.TypeError, 
                               "cannot instantiate an open generic type"
                               );
            return IntPtr.Zero;
        }


        //====================================================================
        // Implements __call__ for reflected generic types.
        //====================================================================

        public static IntPtr tp_call(IntPtr ob, IntPtr args, IntPtr kw) {
            Exceptions.SetError(Exceptions.TypeError, 
                                "object is not callable");
            return IntPtr.Zero;
        }

        //====================================================================
        // Implements subscript syntax for reflected generic types. A closed 
        // type is created by binding the generic type via subscript syntax:
        // inst = List[str]()
        //====================================================================

        public override IntPtr type_subscript(IntPtr idx) {
            Type[] types = Runtime.PythonArgsToTypeArray(idx);
            if (types == null) {
                return Exceptions.RaiseTypeError("type(s) expected");
            }
            if (!this.type.IsGenericTypeDefinition) {
                return Exceptions.RaiseTypeError(
                                  "type is not a generic type definition"
                                  );
            }

            // This is a little tricky, because an instance of GenericType
            // may represent either a specific generic type, or act as an
            // alias for one or more generic types with the same base name.

            if (this.type.ContainsGenericParameters) {
                Type[] args = this.type.GetGenericArguments();
                Type target = null;

                if (args.Length == types.Length) {
                    target = this.type;
                }
                else {
                    foreach (Type t in 
                             GenericUtil.GenericsForType(this.type)) {
                        if (t.GetGenericArguments().Length == types.Length) {
                            target = t;
                            break;
                        }
                    }
                }

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

            return Exceptions.RaiseTypeError("unsubscriptable object");
        }

    }

}

Web Proxy Viewer  |  New URL  |  Original Page