IronPython.Runtime.Types.NewTypeInfo.GetTypeInfo C# (CSharp) Method

GetTypeInfo() public static method

"bases" contains a set of PythonTypes. These can include types defined in Python (say cpy1, cpy2), CLI types (say cCLI1, cCLI2), and CLI interfaces (say iCLI1, iCLI2). Here are some examples of how this works: (bases) => baseType, {interfaceTypes} (cpy1) => System.Object, {} (cpy1, cpy2) => System.Object, {} (cpy1, cCLI1, iCLI1, iCLI2) => cCLI1, {iCLI1, iCLI2} [some type that satisfies the line above] => cCLI1, {iCLI1, iCLI2} (cCLI1, cCLI2) => error
public static GetTypeInfo ( string typeName, PythonTuple bases ) : NewTypeInfo
typeName string
bases PythonTuple
return NewTypeInfo
        public static NewTypeInfo GetTypeInfo(string typeName, PythonTuple bases) {
            List<Type> interfaceTypes = new List<Type>();
            Type baseCLIType = typeof(object); // Pure Python object instances inherit from System.Object
            PythonType basePythonType = null;

            foreach (PythonType curBasePythonType in GetPythonTypes(typeName, bases)) {
                // discover the initial base/interfaces
                IList<Type> baseInterfaces = Type.EmptyTypes;
                Type curTypeToExtend = curBasePythonType.ExtensionType;

                if (curBasePythonType.ExtensionType.IsInterface) {
                    baseInterfaces = new Type[] { curTypeToExtend };
                    curTypeToExtend = typeof(object);
                } else if (NewTypeMaker.IsInstanceType(curTypeToExtend)) {
                    baseInterfaces = new List<Type>();
                    curTypeToExtend = GetBaseTypeFromUserType(curBasePythonType, baseInterfaces, curTypeToExtend.BaseType);
                }

                if (curTypeToExtend == null || typeof(BuiltinFunction).IsAssignableFrom(curTypeToExtend) || typeof(PythonFunction).IsAssignableFrom(curTypeToExtend))
                    throw PythonOps.TypeError(typeName + ": {0} is not an acceptable base type", curBasePythonType.Name);
                if (curTypeToExtend.ContainsGenericParameters)
                    throw PythonOps.TypeError(typeName + ": cannot inhert from open generic instantiation {0}. Only closed instantiations are supported.", curBasePythonType);

                foreach (Type interfaceType in baseInterfaces) {
                    if (interfaceType.ContainsGenericParameters)
                        throw PythonOps.TypeError(typeName + ": cannot inhert from open generic instantiation {0}. Only closed instantiations are supported.", interfaceType);

                    // collecting all the interfaces because we override them all.
                    interfaceTypes.Add(interfaceType);
                }

                // if we're not extending something already in our existing base classes type hierarchy
                // then we better be in some esoteric __slots__ situation
                if (!baseCLIType.IsSubclassOf(curTypeToExtend)) {
                    if (baseCLIType != typeof(object) && baseCLIType != curTypeToExtend &&
                        (!baseCLIType.IsDefined(typeof(DynamicBaseTypeAttribute), false) && !curTypeToExtend.IsSubclassOf(baseCLIType))) {
                        throw PythonOps.TypeError(
                            typeName + ": can only extend one CLI or builtin type, not both {0} (for {1}) and {2} (for {3})",
                            baseCLIType.FullName,
                            basePythonType,
                            curTypeToExtend.FullName,
                            curBasePythonType);
                    }

                    // we have a new base type
                    baseCLIType = curTypeToExtend;
                    basePythonType = curBasePythonType;
                }

            }
            return new NewTypeInfo(baseCLIType, interfaceTypes.Count == 0 ? Type.EmptyTypes : interfaceTypes.ToArray());
        }