/// <summary> /// Implementation of [] semantics for reflected types. This exists /// both to implement the Array[int] syntax for creating arrays and /// to support generic name overload resolution using []. /// </summary> public override IntPtr type_subscript(IntPtr idx) { // If this type is the Array type, the [<type>] means we need to // construct and return an array type of the given element type. if (type == typeof(Array)) { if (Runtime.PyTuple_Check(idx)) { return(Exceptions.RaiseTypeError("type expected")); } var c = GetManagedObject(idx) as ClassBase; Type t = c != null ? c.type : Converter.GetTypeByAlias(idx); if (t == null) { return(Exceptions.RaiseTypeError("type expected")); } Type a = t.MakeArrayType(); ClassBase o = ClassManager.GetClass(a); Runtime.XIncref(o.pyHandle); return(o.pyHandle); } // If there are generics in our namespace with the same base name // as the current type, then [<type>] means the caller wants to // bind the generic type matching the given type parameters. Type[] types = Runtime.PythonArgsToTypeArray(idx); if (types == null) { return(Exceptions.RaiseTypeError("type(s) expected")); } Type gtype = AssemblyManager.LookupType($"{type.FullName}`{types.Length}"); if (gtype != null) { var g = ClassManager.GetClass(gtype) as GenericType; return(g.type_subscript(idx)); //Runtime.XIncref(g.pyHandle); //return g.pyHandle; } return(Exceptions.RaiseTypeError("unsubscriptable object")); }
public static List <Type> GenericsByName(string ns, string basename) { Dictionary <string, List <string> > nsmap = null; mapping.TryGetValue(ns, out nsmap); if (nsmap == null) { return(null); } int tick = basename.IndexOf("`"); if (tick > -1) { basename = basename.Substring(0, tick); } List <string> names = null; nsmap.TryGetValue(basename, out names); if (names == null) { return(null); } var result = new List <Type>(); foreach (string name in names) { string qname = ns + "." + name; Type o = AssemblyManager.LookupType(qname); if (o != null) { result.Add(o); } } return(result); }
/// <summary> /// Returns a ClassBase object representing a type that appears in /// this module's namespace or a ModuleObject representing a child /// namespace (or null if the name is not found). This method does /// not increment the Python refcount of the returned object. /// </summary> public ManagedType GetAttribute(string name, bool guess) { ManagedType cached = null; cache.TryGetValue(name, out cached); if (cached != null) { return(cached); } ModuleObject m; ClassBase c; Type type; //if (AssemblyManager.IsValidNamespace(name)) //{ // IntPtr py_mod_name = Runtime.PyString_FromString(name); // IntPtr modules = Runtime.PyImport_GetModuleDict(); // IntPtr module = Runtime.PyDict_GetItem(modules, py_mod_name); // if (module != IntPtr.Zero) // return (ManagedType)this; // return null; //} string qname = _namespace == string.Empty ? name : _namespace + "." + name; // If the fully-qualified name of the requested attribute is // a namespace exported by a currently loaded assembly, return // a new ModuleObject representing that namespace. if (AssemblyManager.IsValidNamespace(qname)) { m = new ModuleObject(qname); StoreAttribute(name, m); return(m); } // Look for a type in the current namespace. Note that this // includes types, delegates, enums, interfaces and structs. // Only public namespace members are exposed to Python. type = AssemblyManager.LookupType(qname); if (type != null) { if (!type.IsPublic) { return(null); } c = ClassManager.GetClass(type); StoreAttribute(name, c); return(c); } // This is a little repetitive, but it ensures that the right // thing happens with implicit assembly loading at a reasonable // cost. Ask the AssemblyManager to do implicit loading for each // of the steps in the qualified name, then try it again. bool ignore = name.StartsWith("__"); if (AssemblyManager.LoadImplicit(qname, !ignore)) { if (AssemblyManager.IsValidNamespace(qname)) { m = new ModuleObject(qname); StoreAttribute(name, m); return(m); } type = AssemblyManager.LookupType(qname); if (type != null) { if (!type.IsPublic) { return(null); } c = ClassManager.GetClass(type); StoreAttribute(name, c); return(c); } } // We didn't find the name, so we may need to see if there is a // generic type with this base name. If so, we'll go ahead and // return it. Note that we store the mapping of the unmangled // name to generic type - it is technically possible that some // future assembly load could contribute a non-generic type to // the current namespace with the given basename, but unlikely // enough to complicate the implementation for now. if (guess) { string gname = GenericUtil.GenericNameForBaseName(_namespace, name); if (gname != null) { ManagedType o = GetAttribute(gname, false); if (o != null) { StoreAttribute(name, o); return(o); } } } return(null); }