13257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel"""Find modules used by a script, using introspection.""" 23257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# This module should be kept compatible with Python 2.2, see PEP 291. 33257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 43257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielfrom __future__ import generators 53257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielimport dis 63257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielimport imp 73257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielimport marshal 83257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielimport os 93257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielimport sys 103257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielimport types 113257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielimport struct 123257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 133257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielif hasattr(sys.__stdout__, "newlines"): 143257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel READ_MODE = "U" # universal line endings 153257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielelse: 163257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # remain compatible with Python < 2.3 173257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel READ_MODE = "r" 183257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 193257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielLOAD_CONST = chr(dis.opname.index('LOAD_CONST')) 203257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielIMPORT_NAME = chr(dis.opname.index('IMPORT_NAME')) 213257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielSTORE_NAME = chr(dis.opname.index('STORE_NAME')) 223257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielSTORE_GLOBAL = chr(dis.opname.index('STORE_GLOBAL')) 233257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielSTORE_OPS = [STORE_NAME, STORE_GLOBAL] 243257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielHAVE_ARGUMENT = chr(dis.HAVE_ARGUMENT) 253257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 263257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# Modulefinder does a good job at simulating Python's, but it can not 273257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# handle __path__ modifications packages make at runtime. Therefore there 283257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# is a mechanism whereby you can register extra paths in this map for a 293257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# package, and it will be honored. 303257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 313257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# Note this is a mapping is lists of paths. 323257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielpackagePathMap = {} 333257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 343257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# A Public interface 353257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanieldef AddPackagePath(packagename, path): 363257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel paths = packagePathMap.get(packagename, []) 373257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel paths.append(path) 383257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel packagePathMap[packagename] = paths 393257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 403257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielreplacePackageMap = {} 413257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 423257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# This ReplacePackage mechanism allows modulefinder to work around the 433257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# way the _xmlplus package injects itself under the name "xml" into 443257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# sys.modules at runtime by calling ReplacePackage("_xmlplus", "xml") 453257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# before running ModuleFinder. 463257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 473257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanieldef ReplacePackage(oldname, newname): 483257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel replacePackageMap[oldname] = newname 493257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 503257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 513257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielclass Module: 523257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 533257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def __init__(self, name, file=None, path=None): 543257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.__name__ = name 553257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.__file__ = file 563257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.__path__ = path 573257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.__code__ = None 583257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # The set of global names that are assigned to in the module. 593257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # This includes those names imported through starimports of 603257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # Python modules. 613257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.globalnames = {} 623257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # The set of starimports this module did that could not be 633257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # resolved, ie. a starimport from a non-Python module. 643257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.starimports = {} 653257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 663257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def __repr__(self): 673257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel s = "Module(%r" % (self.__name__,) 683257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if self.__file__ is not None: 693257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel s = s + ", %r" % (self.__file__,) 703257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if self.__path__ is not None: 713257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel s = s + ", %r" % (self.__path__,) 723257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel s = s + ")" 733257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return s 743257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 753257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielclass ModuleFinder: 763257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 773257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def __init__(self, path=None, debug=0, excludes=[], replace_paths=[]): 783257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if path is None: 793257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel path = sys.path 803257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.path = path 813257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.modules = {} 823257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.badmodules = {} 833257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.debug = debug 843257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.indent = 0 853257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.excludes = excludes 863257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.replace_paths = replace_paths 873257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.processed_paths = [] # Used in debugging only 883257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 893257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def msg(self, level, str, *args): 903257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if level <= self.debug: 913257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel for i in range(self.indent): 923257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel print " ", 933257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel print str, 943257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel for arg in args: 953257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel print repr(arg), 963257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel print 973257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 983257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def msgin(self, *args): 993257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel level = args[0] 1003257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if level <= self.debug: 1013257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.indent = self.indent + 1 1023257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msg(*args) 1033257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 1043257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def msgout(self, *args): 1053257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel level = args[0] 1063257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if level <= self.debug: 1073257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.indent = self.indent - 1 1083257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msg(*args) 1093257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 1103257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def run_script(self, pathname): 1113257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msg(2, "run_script", pathname) 1123257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel with open(pathname, READ_MODE) as fp: 1133257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel stuff = ("", "r", imp.PY_SOURCE) 1143257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.load_module('__main__', fp, pathname, stuff) 1153257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 1163257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def load_file(self, pathname): 1173257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel dir, name = os.path.split(pathname) 1183257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel name, ext = os.path.splitext(name) 1193257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel with open(pathname, READ_MODE) as fp: 1203257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel stuff = (ext, "r", imp.PY_SOURCE) 1213257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.load_module(name, fp, pathname, stuff) 1223257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 1233257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def import_hook(self, name, caller=None, fromlist=None, level=-1): 1243257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msg(3, "import_hook", name, caller, fromlist, level) 1253257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel parent = self.determine_parent(caller, level=level) 1263257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel q, tail = self.find_head_package(parent, name) 1273257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel m = self.load_tail(q, tail) 1283257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if not fromlist: 1293257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return q 1303257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if m.__path__: 1313257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.ensure_fromlist(m, fromlist) 1323257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return None 1333257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 1343257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def determine_parent(self, caller, level=-1): 1353257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msgin(4, "determine_parent", caller, level) 1363257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if not caller or level == 0: 1373257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msgout(4, "determine_parent -> None") 1383257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return None 1393257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel pname = caller.__name__ 1403257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if level >= 1: # relative import 1413257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if caller.__path__: 1423257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel level -= 1 1433257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if level == 0: 1443257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel parent = self.modules[pname] 1453257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel assert parent is caller 1463257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msgout(4, "determine_parent ->", parent) 1473257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return parent 1483257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if pname.count(".") < level: 1493257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel raise ImportError, "relative importpath too deep" 1503257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel pname = ".".join(pname.split(".")[:-level]) 1513257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel parent = self.modules[pname] 1523257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msgout(4, "determine_parent ->", parent) 1533257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return parent 1543257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if caller.__path__: 1553257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel parent = self.modules[pname] 1563257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel assert caller is parent 1573257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msgout(4, "determine_parent ->", parent) 1583257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return parent 1593257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if '.' in pname: 1603257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel i = pname.rfind('.') 1613257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel pname = pname[:i] 1623257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel parent = self.modules[pname] 1633257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel assert parent.__name__ == pname 1643257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msgout(4, "determine_parent ->", parent) 1653257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return parent 1663257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msgout(4, "determine_parent -> None") 1673257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return None 1683257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 1693257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def find_head_package(self, parent, name): 1703257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msgin(4, "find_head_package", parent, name) 1713257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if '.' in name: 1723257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel i = name.find('.') 1733257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel head = name[:i] 1743257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel tail = name[i+1:] 1753257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel else: 1763257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel head = name 1773257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel tail = "" 1783257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if parent: 1793257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel qname = "%s.%s" % (parent.__name__, head) 1803257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel else: 1813257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel qname = head 1823257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel q = self.import_module(head, qname, parent) 1833257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if q: 1843257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msgout(4, "find_head_package ->", (q, tail)) 1853257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return q, tail 1863257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if parent: 1873257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel qname = head 1883257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel parent = None 1893257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel q = self.import_module(head, qname, parent) 1903257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if q: 1913257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msgout(4, "find_head_package ->", (q, tail)) 1923257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return q, tail 1933257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msgout(4, "raise ImportError: No module named", qname) 1943257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel raise ImportError, "No module named " + qname 1953257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 1963257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def load_tail(self, q, tail): 1973257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msgin(4, "load_tail", q, tail) 1983257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel m = q 1993257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel while tail: 2003257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel i = tail.find('.') 2013257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if i < 0: i = len(tail) 2023257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel head, tail = tail[:i], tail[i+1:] 2033257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel mname = "%s.%s" % (m.__name__, head) 2043257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel m = self.import_module(head, mname, m) 2053257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if not m: 2063257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msgout(4, "raise ImportError: No module named", mname) 2073257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel raise ImportError, "No module named " + mname 2083257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msgout(4, "load_tail ->", m) 2093257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return m 2103257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 2113257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def ensure_fromlist(self, m, fromlist, recursive=0): 2123257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msg(4, "ensure_fromlist", m, fromlist, recursive) 2133257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel for sub in fromlist: 2143257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if sub == "*": 2153257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if not recursive: 2163257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel all = self.find_all_submodules(m) 2173257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if all: 2183257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.ensure_fromlist(m, all, 1) 2193257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel elif not hasattr(m, sub): 2203257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel subname = "%s.%s" % (m.__name__, sub) 2213257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel submod = self.import_module(sub, subname, m) 2223257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if not submod: 2233257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel raise ImportError, "No module named " + subname 2243257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 2253257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def find_all_submodules(self, m): 2263257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if not m.__path__: 2273257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return 2283257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel modules = {} 2293257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # 'suffixes' used to be a list hardcoded to [".py", ".pyc", ".pyo"]. 2303257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # But we must also collect Python extension modules - although 2313257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # we cannot separate normal dlls from Python extensions. 2323257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel suffixes = [] 2333257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel for triple in imp.get_suffixes(): 2343257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel suffixes.append(triple[0]) 2353257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel for dir in m.__path__: 2363257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel try: 2373257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel names = os.listdir(dir) 2383257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel except os.error: 2393257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msg(2, "can't list directory", dir) 2403257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel continue 2413257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel for name in names: 2423257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel mod = None 2433257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel for suff in suffixes: 2443257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel n = len(suff) 2453257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if name[-n:] == suff: 2463257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel mod = name[:-n] 2473257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel break 2483257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if mod and mod != "__init__": 2493257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel modules[mod] = mod 2503257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return modules.keys() 2513257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 2523257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def import_module(self, partname, fqname, parent): 2533257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msgin(3, "import_module", partname, fqname, parent) 2543257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel try: 2553257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel m = self.modules[fqname] 2563257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel except KeyError: 2573257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel pass 2583257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel else: 2593257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msgout(3, "import_module ->", m) 2603257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return m 2613257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if fqname in self.badmodules: 2623257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msgout(3, "import_module -> None") 2633257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return None 2643257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if parent and parent.__path__ is None: 2653257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msgout(3, "import_module -> None") 2663257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return None 2673257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel try: 2683257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel fp, pathname, stuff = self.find_module(partname, 2693257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel parent and parent.__path__, parent) 2703257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel except ImportError: 2713257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msgout(3, "import_module ->", None) 2723257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return None 2733257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel try: 2743257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel m = self.load_module(fqname, fp, pathname, stuff) 2753257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel finally: 2763257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if fp: fp.close() 2773257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if parent: 2783257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel setattr(parent, partname, m) 2793257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msgout(3, "import_module ->", m) 2803257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return m 2813257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 2823257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def load_module(self, fqname, fp, pathname, file_info): 2833257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel suffix, mode, type = file_info 2843257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msgin(2, "load_module", fqname, fp and "fp", pathname) 2853257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if type == imp.PKG_DIRECTORY: 2863257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel m = self.load_package(fqname, pathname) 2873257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msgout(2, "load_module ->", m) 2883257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return m 2893257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if type == imp.PY_SOURCE: 2903257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel co = compile(fp.read()+'\n', pathname, 'exec') 2913257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel elif type == imp.PY_COMPILED: 2923257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if fp.read(4) != imp.get_magic(): 2933257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msgout(2, "raise ImportError: Bad magic number", pathname) 2943257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel raise ImportError, "Bad magic number in %s" % pathname 2953257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel fp.read(4) 2963257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel co = marshal.load(fp) 2973257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel else: 2983257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel co = None 2993257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel m = self.add_module(fqname) 3003257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel m.__file__ = pathname 3013257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if co: 3023257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if self.replace_paths: 3033257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel co = self.replace_paths_in_code(co) 3043257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel m.__code__ = co 3053257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.scan_code(co, m) 3063257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msgout(2, "load_module ->", m) 3073257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return m 3083257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 3093257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def _add_badmodule(self, name, caller): 3103257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if name not in self.badmodules: 3113257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.badmodules[name] = {} 3123257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if caller: 3133257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.badmodules[name][caller.__name__] = 1 3143257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel else: 3153257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.badmodules[name]["-"] = 1 3163257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 3173257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def _safe_import_hook(self, name, caller, fromlist, level=-1): 3183257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # wrapper for self.import_hook() that won't raise ImportError 3193257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if name in self.badmodules: 3203257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self._add_badmodule(name, caller) 3213257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return 3223257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel try: 3233257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.import_hook(name, caller, level=level) 3243257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel except ImportError, msg: 3253257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msg(2, "ImportError:", str(msg)) 3263257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self._add_badmodule(name, caller) 3273257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel else: 3283257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if fromlist: 3293257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel for sub in fromlist: 3303257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if sub in self.badmodules: 3313257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self._add_badmodule(sub, caller) 3323257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel continue 3333257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel try: 3343257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.import_hook(name, caller, [sub], level=level) 3353257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel except ImportError, msg: 3363257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msg(2, "ImportError:", str(msg)) 3373257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel fullname = name + "." + sub 3383257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self._add_badmodule(fullname, caller) 3393257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 3403257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def scan_opcodes(self, co, 3413257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel unpack = struct.unpack): 3423257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # Scan the code, and yield 'interesting' opcode combinations 3433257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # Version for Python 2.4 and older 3443257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel code = co.co_code 3453257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel names = co.co_names 3463257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel consts = co.co_consts 3473257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel while code: 3483257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel c = code[0] 3493257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if c in STORE_OPS: 3503257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel oparg, = unpack('<H', code[1:3]) 3513257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel yield "store", (names[oparg],) 3523257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel code = code[3:] 3533257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel continue 3543257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if c == LOAD_CONST and code[3] == IMPORT_NAME: 3553257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel oparg_1, oparg_2 = unpack('<xHxH', code[:6]) 3563257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel yield "import", (consts[oparg_1], names[oparg_2]) 3573257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel code = code[6:] 3583257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel continue 3593257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if c >= HAVE_ARGUMENT: 3603257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel code = code[3:] 3613257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel else: 3623257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel code = code[1:] 3633257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 3643257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def scan_opcodes_25(self, co, 3653257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel unpack = struct.unpack): 3663257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # Scan the code, and yield 'interesting' opcode combinations 3673257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # Python 2.5 version (has absolute and relative imports) 3683257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel code = co.co_code 3693257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel names = co.co_names 3703257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel consts = co.co_consts 3713257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel LOAD_LOAD_AND_IMPORT = LOAD_CONST + LOAD_CONST + IMPORT_NAME 3723257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel while code: 3733257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel c = code[0] 3743257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if c in STORE_OPS: 3753257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel oparg, = unpack('<H', code[1:3]) 3763257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel yield "store", (names[oparg],) 3773257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel code = code[3:] 3783257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel continue 3793257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if code[:9:3] == LOAD_LOAD_AND_IMPORT: 3803257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel oparg_1, oparg_2, oparg_3 = unpack('<xHxHxH', code[:9]) 3813257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel level = consts[oparg_1] 3823257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if level == -1: # normal import 3833257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel yield "import", (consts[oparg_2], names[oparg_3]) 3843257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel elif level == 0: # absolute import 3853257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel yield "absolute_import", (consts[oparg_2], names[oparg_3]) 3863257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel else: # relative import 3873257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel yield "relative_import", (level, consts[oparg_2], names[oparg_3]) 3883257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel code = code[9:] 3893257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel continue 3903257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if c >= HAVE_ARGUMENT: 3913257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel code = code[3:] 3923257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel else: 3933257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel code = code[1:] 3943257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 3953257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def scan_code(self, co, m): 3963257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel code = co.co_code 3973257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if sys.version_info >= (2, 5): 3983257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel scanner = self.scan_opcodes_25 3993257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel else: 4003257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel scanner = self.scan_opcodes 4013257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel for what, args in scanner(co): 4023257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if what == "store": 4033257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel name, = args 4043257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel m.globalnames[name] = 1 4053257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel elif what in ("import", "absolute_import"): 4063257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel fromlist, name = args 4073257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel have_star = 0 4083257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if fromlist is not None: 4093257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if "*" in fromlist: 4103257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel have_star = 1 4113257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel fromlist = [f for f in fromlist if f != "*"] 4123257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if what == "absolute_import": level = 0 4133257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel else: level = -1 4143257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self._safe_import_hook(name, m, fromlist, level=level) 4153257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if have_star: 4163257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # We've encountered an "import *". If it is a Python module, 4173257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # the code has already been parsed and we can suck out the 4183257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # global names. 4193257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel mm = None 4203257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if m.__path__: 4213257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # At this point we don't know whether 'name' is a 4223257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # submodule of 'm' or a global module. Let's just try 4233257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # the full name first. 4243257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel mm = self.modules.get(m.__name__ + "." + name) 4253257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if mm is None: 4263257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel mm = self.modules.get(name) 4273257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if mm is not None: 4283257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel m.globalnames.update(mm.globalnames) 4293257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel m.starimports.update(mm.starimports) 4303257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if mm.__code__ is None: 4313257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel m.starimports[name] = 1 4323257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel else: 4333257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel m.starimports[name] = 1 4343257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel elif what == "relative_import": 4353257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel level, fromlist, name = args 4363257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if name: 4373257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self._safe_import_hook(name, m, fromlist, level=level) 4383257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel else: 4393257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel parent = self.determine_parent(m, level=level) 4403257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self._safe_import_hook(parent.__name__, None, fromlist, level=0) 4413257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel else: 4423257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # We don't expect anything else from the generator. 4433257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel raise RuntimeError(what) 4443257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 4453257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel for c in co.co_consts: 4463257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if isinstance(c, type(co)): 4473257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.scan_code(c, m) 4483257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 4493257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def load_package(self, fqname, pathname): 4503257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msgin(2, "load_package", fqname, pathname) 4513257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel newname = replacePackageMap.get(fqname) 4523257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if newname: 4533257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel fqname = newname 4543257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel m = self.add_module(fqname) 4553257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel m.__file__ = pathname 4563257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel m.__path__ = [pathname] 4573257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 4583257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # As per comment at top of file, simulate runtime __path__ additions. 4593257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel m.__path__ = m.__path__ + packagePathMap.get(fqname, []) 4603257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 4613257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel fp, buf, stuff = self.find_module("__init__", m.__path__) 4623257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.load_module(fqname, fp, buf, stuff) 4633257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msgout(2, "load_package ->", m) 4643257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if fp: 4653257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel fp.close() 4663257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return m 4673257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 4683257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def add_module(self, fqname): 4693257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if fqname in self.modules: 4703257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return self.modules[fqname] 4713257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.modules[fqname] = m = Module(fqname) 4723257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return m 4733257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 4743257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def find_module(self, name, path, parent=None): 4753257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if parent is not None: 4763257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # assert path is not None 4773257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel fullname = parent.__name__+'.'+name 4783257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel else: 4793257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel fullname = name 4803257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if fullname in self.excludes: 4813257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msgout(3, "find_module -> Excluded", fullname) 4823257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel raise ImportError, name 4833257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 4843257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if path is None: 4853257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if name in sys.builtin_module_names: 4863257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return (None, None, ("", "", imp.C_BUILTIN)) 4873257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 4883257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel path = self.path 4893257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return imp.find_module(name, path) 4903257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 4913257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def report(self): 4923257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel """Print a report to stdout, listing the found modules with their 4933257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel paths, as well as modules that are missing, or seem to be missing. 4943257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel """ 4953257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel print 4963257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel print " %-25s %s" % ("Name", "File") 4973257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel print " %-25s %s" % ("----", "----") 4983257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # Print modules found 4993257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel keys = self.modules.keys() 5003257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel keys.sort() 5013257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel for key in keys: 5023257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel m = self.modules[key] 5033257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if m.__path__: 5043257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel print "P", 5053257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel else: 5063257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel print "m", 5073257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel print "%-25s" % key, m.__file__ or "" 5083257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 5093257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # Print missing modules 5103257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel missing, maybe = self.any_missing_maybe() 5113257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if missing: 5123257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel print 5133257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel print "Missing modules:" 5143257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel for name in missing: 5153257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel mods = self.badmodules[name].keys() 5163257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel mods.sort() 5173257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel print "?", name, "imported from", ', '.join(mods) 5183257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # Print modules that may be missing, but then again, maybe not... 5193257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if maybe: 5203257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel print 5213257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel print "Submodules that appear to be missing, but could also be", 5223257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel print "global names in the parent package:" 5233257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel for name in maybe: 5243257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel mods = self.badmodules[name].keys() 5253257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel mods.sort() 5263257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel print "?", name, "imported from", ', '.join(mods) 5273257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 5283257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def any_missing(self): 5293257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel """Return a list of modules that appear to be missing. Use 5303257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel any_missing_maybe() if you want to know which modules are 5313257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel certain to be missing, and which *may* be missing. 5323257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel """ 5333257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel missing, maybe = self.any_missing_maybe() 5343257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return missing + maybe 5353257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 5363257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def any_missing_maybe(self): 5373257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel """Return two lists, one with modules that are certainly missing 5383257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel and one with modules that *may* be missing. The latter names could 5393257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel either be submodules *or* just global names in the package. 5403257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 5413257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel The reason it can't always be determined is that it's impossible to 5423257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel tell which names are imported when "from module import *" is done 5433257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel with an extension module, short of actually importing it. 5443257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel """ 5453257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel missing = [] 5463257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel maybe = [] 5473257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel for name in self.badmodules: 5483257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if name in self.excludes: 5493257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel continue 5503257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel i = name.rfind(".") 5513257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if i < 0: 5523257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel missing.append(name) 5533257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel continue 5543257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel subname = name[i+1:] 5553257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel pkgname = name[:i] 5563257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel pkg = self.modules.get(pkgname) 5573257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if pkg is not None: 5583257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if pkgname in self.badmodules[name]: 5593257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # The package tried to import this module itself and 5603257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # failed. It's definitely missing. 5613257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel missing.append(name) 5623257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel elif subname in pkg.globalnames: 5633257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # It's a global in the package: definitely not missing. 5643257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel pass 5653257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel elif pkg.starimports: 5663257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # It could be missing, but the package did an "import *" 5673257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # from a non-Python module, so we simply can't be sure. 5683257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel maybe.append(name) 5693257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel else: 5703257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # It's not a global in the package, the package didn't 5713257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # do funny star imports, it's very likely to be missing. 5723257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # The symbol could be inserted into the package from the 5733257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # outside, but since that's not good style we simply list 5743257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # it missing. 5753257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel missing.append(name) 5763257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel else: 5773257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel missing.append(name) 5783257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel missing.sort() 5793257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel maybe.sort() 5803257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return missing, maybe 5813257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 5823257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def replace_paths_in_code(self, co): 5833257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel new_filename = original_filename = os.path.normpath(co.co_filename) 5843257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel for f, r in self.replace_paths: 5853257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if original_filename.startswith(f): 5863257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel new_filename = r + original_filename[len(f):] 5873257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel break 5883257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 5893257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if self.debug and original_filename not in self.processed_paths: 5903257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if new_filename != original_filename: 5913257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msgout(2, "co_filename %r changed to %r" \ 5923257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel % (original_filename,new_filename,)) 5933257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel else: 5943257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.msgout(2, "co_filename %r remains unchanged" \ 5953257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel % (original_filename,)) 5963257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self.processed_paths.append(original_filename) 5973257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 5983257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel consts = list(co.co_consts) 5993257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel for i in range(len(consts)): 6003257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if isinstance(consts[i], type(co)): 6013257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel consts[i] = self.replace_paths_in_code(consts[i]) 6023257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 6033257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return types.CodeType(co.co_argcount, co.co_nlocals, co.co_stacksize, 6043257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel co.co_flags, co.co_code, tuple(consts), co.co_names, 6053257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel co.co_varnames, new_filename, co.co_name, 6063257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel co.co_firstlineno, co.co_lnotab, 6073257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel co.co_freevars, co.co_cellvars) 6083257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 6093257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 6103257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanieldef test(): 6113257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # Parse command line 6123257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel import getopt 6133257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel try: 6143257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel opts, args = getopt.getopt(sys.argv[1:], "dmp:qx:") 6153257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel except getopt.error, msg: 6163257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel print msg 6173257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return 6183257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 6193257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # Process options 6203257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel debug = 1 6213257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel domods = 0 6223257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel addpath = [] 6233257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel exclude = [] 6243257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel for o, a in opts: 6253257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if o == '-d': 6263257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel debug = debug + 1 6273257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if o == '-m': 6283257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel domods = 1 6293257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if o == '-p': 6303257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel addpath = addpath + a.split(os.pathsep) 6313257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if o == '-q': 6323257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel debug = 0 6333257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if o == '-x': 6343257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel exclude.append(a) 6353257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 6363257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # Provide default arguments 6373257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if not args: 6383257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel script = "hello.py" 6393257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel else: 6403257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel script = args[0] 6413257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 6423257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # Set the path based on sys.path and the script directory 6433257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel path = sys.path[:] 6443257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel path[0] = os.path.dirname(script) 6453257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel path = addpath + path 6463257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if debug > 1: 6473257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel print "path:" 6483257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel for item in path: 6493257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel print " ", repr(item) 6503257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 6513257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel # Create the module finder and turn its crank 6523257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel mf = ModuleFinder(path, debug, exclude) 6533257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel for arg in args[1:]: 6543257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if arg == '-m': 6553257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel domods = 1 6563257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel continue 6573257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if domods: 6583257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if arg[-2:] == '.*': 6593257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel mf.import_hook(arg[:-2], None, ["*"]) 6603257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel else: 6613257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel mf.import_hook(arg) 6623257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel else: 6633257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel mf.load_file(arg) 6643257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel mf.run_script(script) 6653257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel mf.report() 6663257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return mf # for -i debugging 6673257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 6683257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 6693257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielif __name__ == '__main__': 6703257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel try: 6713257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel mf = test() 6723257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel except KeyboardInterrupt: 6733257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel print "\n[interrupt]" 674