/// <summary> /// Gateway into importing ... called from Ops. This is called after /// importing the module and is used to return individual items from /// the module. The outer modules dictionary is then updated with the /// result. /// </summary> internal static object ImportFrom(ICallerContext context, object mod, string name) { PythonModule from = mod as PythonModule; if (from != null) { object ret; if (from.TryGetAttr(from, SymbolTable.StringToId(name), out ret)) { return(ret); } else { return(ImportNested(from, name)); } } else { object ret; if (Ops.TryGetAttr(context, mod, SymbolTable.StringToId(name), out ret)) { return(ret); } else { throw Ops.ImportError("No module named {0}", name); } } }
private static List ResolveSearchPath(PythonModule mod, out string baseName) { baseName = mod.ModuleName; object path; if (!mod.TryGetAttr(DefaultContext.Default, SymbolTable.Path, out path)) { List basePath = path as List; for (; ;) { int lastDot = baseName.LastIndexOf('.'); if (lastDot < 0) { baseName = "__main__"; break; } baseName = baseName.Substring(0, lastDot); object package = mod.SystemState.modules[baseName]; if (Ops.TryGetAttr(package, SymbolTable.Path, out path)) { if (path is List) { basePath = (List)path; } break; } } return(basePath); } return(path as List); // trouble if __path__ is not a List }
private static object ImportNested(PythonModule mod, string name) { object ret; if (mod.TryGetAttr(mod, SymbolTable.StringToId(name), out ret)) { return(ret); } string baseName; List path = ResolveSearchPath(mod, out baseName); string fullName = CreateFullName(baseName, name); if (TryGetExistingModule(mod.SystemState, fullName, out ret)) { return(ret); } if (path != null) { ret = ImportFromPath(mod.SystemState, name, fullName, path); if (ret != null) { mod.SetAttr(mod, SymbolTable.StringToId(name), ret); return(ret); } } throw Ops.ImportError("cannot import {0} from {1}", name, mod.ModuleName); }
private static object FindImportFunction(PythonModule mod) { object import; if (mod != null) { if (mod.TryGetAttr(mod, SymbolTable.Import, out import)) { return(import); } object builtin = Ops.GetAttr(mod, mod, SymbolTable.Builtins); if (Ops.TryGetAttr(mod, builtin, SymbolTable.Import, out import)) { return(import); } } throw Ops.ImportError("cannot find __import__"); }
private static bool TryGetNestedModule(PythonModule mod, string name, out object nested) { if (mod.TryGetAttr(mod, SymbolTable.StringToId(name), out nested)) { if (nested is PythonModule) return true; // This allows from System.Math import * if (nested is ReflectedType) return true; } return false; }
/// <summary> /// Interrogates the importing module for __name__ and __path__, which determine /// whether the imported module (whose name is 'name') is being imported as nested /// module (__path__ is present) or as sibling. /// /// For sibling import, the full name of the imported module is parent.sibling /// For nested import, the full name of the imported module is parent.module.nested /// where parent.module is the mod.__name__ /// </summary> /// <param name="context"></param> /// <param name="mod">The module that triggered import</param> /// <param name="name">Name of the module to be imported</param> /// <param name="full">Output - full name of the module being imported</param> /// <param name="path">Path to use to search for "full"</param> /// <returns></returns> private static bool TryGetNameAndPath(ICallerContext context, PythonModule mod, string name, out string full, out List path) { // Unless we can find enough information to perform relative import, // we are going to import the module whose name we got full = name; path = null; // We need to get __name__ to find the name of the imported module. // If absent, fall back to absolute import object attribute; if (!mod.TryGetAttr(context, SymbolTable.Name, out attribute)) { return false; } // And the __name__ needs to be string string modName = attribute as string; if (modName == null) { return false; } // If the module has __path__ (and __path__ is list), nested module is being imported // otherwise, importing sibling to the importing module if (mod.TryGetAttr(context, SymbolTable.Path, out attribute) && (path = attribute as List) != null) { // found __path__, importing nested module. The actual name of the nested module // is the name of the mod plus the name of the imported module full = modName + "." + name; return true; } // importing sibling. The name of the imported module replaces // the last element in the importing module name int lastDot = modName.LastIndexOf('.'); if (lastDot < 0) { // name doesn't include dot, only absolute import possible return false; } string parentName = modName.Substring(0, lastDot); object parentObject; // Try lookup parent module in the sys.modules if (!mod.SystemState.modules.TryGetValue(parentName, out parentObject)) { // parent module not found in sys.modules, fallback to absolute import return false; } PythonModule parentModule; if ((parentModule = parentObject as PythonModule) == null) { // the sys.module entry is not PythonModule, fallback to absolute import return false; } // The parentModule now needs to have __path__ - list if (parentModule.TryGetAttr(context, SymbolTable.Path, out attribute) && (path = attribute as List) != null) { // combine the module names full = parentName + "." + name; return true; } // not enough information - absolute import return false; }
private static List ResolveSearchPath(PythonModule mod, out string baseName) { baseName = mod.ModuleName; object path; if (!mod.TryGetAttr(DefaultContext.Default, SymbolTable.Path, out path)) { List basePath = path as List; for (; ; ) { int lastDot = baseName.LastIndexOf('.'); if (lastDot < 0) { baseName = null; break; } baseName = baseName.Substring(0, lastDot); object package = mod.SystemState.modules[baseName]; if (Ops.TryGetAttr(package, SymbolTable.Path, out path)) { if (path is List) { basePath = (List)path; } break; } } return basePath; } return path as List; // trouble if __path__ is not a List }
private static object FindImportFunction(PythonModule mod) { object import; if (mod != null) { if (mod.TryGetAttr(mod, SymbolTable.Import, out import)) { return import; } object builtin = Ops.GetAttr(mod, mod, SymbolTable.Builtins); if (Ops.TryGetAttr(mod, builtin, SymbolTable.Import, out import)) { return import; } } throw Ops.ImportError("cannot find __import__"); }