From: Jimmy R. <jr...@us...> - 2008-05-19 08:49:09
|
Update of /cvsroot/py2exe/py2exe/py2exe In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32152/py2exe Modified Files: mf.py Log Message: Merged modulefinder.py r59200 from the Python svn trunk into mf.py in order to support relative imports. Index: mf.py =================================================================== RCS file: /cvsroot/py2exe/py2exe/py2exe/mf.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** mf.py 20 Mar 2006 12:04:11 -0000 1.6 --- mf.py 19 May 2008 08:49:12 -0000 1.7 *************** *** 1,6 **** """Find modules used by a script, using introspection.""" - # This module should be kept compatible with Python 2.2, see PEP 291. import dis import imp --- 1,6 ---- """Find modules used by a script, using introspection.""" # This module should be kept compatible with Python 2.2, see PEP 291. + from __future__ import generators import dis import imp *************** *** 8,12 **** import os import sys ! import new import struct --- 8,12 ---- import os import sys ! import types import struct *************** *** 17,20 **** --- 17,26 ---- READ_MODE = "r" + LOAD_CONST = chr(dis.opname.index('LOAD_CONST')) + IMPORT_NAME = chr(dis.opname.index('IMPORT_NAME')) + STORE_NAME = chr(dis.opname.index('STORE_NAME')) + STORE_GLOBAL = chr(dis.opname.index('STORE_GLOBAL')) + STORE_OPS = [STORE_NAME, STORE_GLOBAL] + HAVE_ARGUMENT = chr(dis.HAVE_ARGUMENT) # !!! NOTE BEFORE INCLUDING IN PYTHON DISTRIBUTION !!! *************** *** 125,131 **** self.load_module(name, fp, pathname, stuff) ! def import_hook(self, name, caller=None, fromlist=None): ! self.msg(3, "import_hook", name, caller, fromlist) ! parent = self.determine_parent(caller) q, tail = self.find_head_package(parent, name) m = self.load_tail(q, tail) --- 131,137 ---- self.load_module(name, fp, pathname, stuff) ! def import_hook(self, name, caller=None, fromlist=None, level=-1): ! self.msg(3, "import_hook", name, caller, fromlist, level) ! parent = self.determine_parent(caller, level=level) q, tail = self.find_head_package(parent, name) m = self.load_tail(q, tail) *************** *** 136,145 **** return None ! def determine_parent(self, caller): ! self.msgin(4, "determine_parent", caller) ! if not caller: self.msgout(4, "determine_parent -> None") return None pname = caller.__name__ if caller.__path__: parent = self.modules[pname] --- 142,165 ---- return None ! def determine_parent(self, caller, level=-1): ! self.msgin(4, "determine_parent", caller, level) ! if not caller or level == 0: self.msgout(4, "determine_parent -> None") return None pname = caller.__name__ + if level >= 1: # relative import + if caller.__path__: + level -= 1 + if level == 0: + parent = self.modules[pname] + assert parent is caller + self.msgout(4, "determine_parent ->", parent) + return parent + if pname.count(".") < level: + raise ImportError, "relative importpath too deep" + pname = ".".join(pname.split(".")[:-level]) + parent = self.modules[pname] + self.msgout(4, "determine_parent ->", parent) + return parent if caller.__path__: parent = self.modules[pname] *************** *** 301,305 **** self.badmodules[name][caller.__name__] = 1 ! def _safe_import_hook(self, name, caller, fromlist): # wrapper for self.import_hook() that won't raise ImportError if name in self.badmodules: --- 321,325 ---- self.badmodules[name][caller.__name__] = 1 ! def _safe_import_hook(self, name, caller, fromlist, level=-1): # wrapper for self.import_hook() that won't raise ImportError if name in self.badmodules: *************** *** 307,311 **** return try: ! self.import_hook(name, caller) except ImportError, msg: self.msg(2, "ImportError:", str(msg)) --- 327,331 ---- return try: ! self.import_hook(name, caller, level=level) except ImportError, msg: self.msg(2, "ImportError:", str(msg)) *************** *** 318,322 **** continue try: ! self.import_hook(name, caller, [sub]) except ImportError, msg: self.msg(2, "ImportError:", str(msg)) --- 338,342 ---- continue try: ! self.import_hook(name, caller, [sub], level=level) except ImportError, msg: self.msg(2, "ImportError:", str(msg)) *************** *** 324,355 **** self._add_badmodule(fullname, caller) ! def scan_code(self, co, m, ! HAVE_ARGUMENT = chr(dis.HAVE_ARGUMENT), ! LOAD_CONST = chr(dis.opname.index('LOAD_CONST')), ! IMPORT_NAME = chr(dis.opname.index('IMPORT_NAME')), ! STORE_OPS = [chr(dis.opname.index('STORE_NAME')), ! chr(dis.opname.index('STORE_GLOBAL'))], ! unpack = struct.unpack ! ): code = co.co_code ! constants = co.co_consts ! n = len(code) ! i = 0 ! fromlist = None ! while i < n: ! c = code[i] ! i = i+1 if c >= HAVE_ARGUMENT: ! i = i+2 ! if c == LOAD_CONST: ! # An IMPORT_NAME is always preceded by a LOAD_CONST, it's ! # a tuple of "from" names, or None for a regular import. ! # The tuple may contain "*" for "from <mod> import *" ! oparg = unpack('<H', code[i-2:i])[0] ! fromlist = constants[oparg] ! elif c == IMPORT_NAME: ! assert fromlist is None or type(fromlist) is tuple ! oparg = unpack('<H', code[i-2:i])[0] ! name = co.co_names[oparg] have_star = 0 if fromlist is not None: --- 344,414 ---- self._add_badmodule(fullname, caller) ! def scan_opcodes(self, co, ! unpack = struct.unpack): ! # Scan the code, and yield 'interesting' opcode combinations ! # Version for Python 2.4 and older code = co.co_code ! names = co.co_names ! consts = co.co_consts ! while code: ! c = code[0] ! if c in STORE_OPS: ! oparg, = unpack('<H', code[1:3]) ! yield "store", (names[oparg],) ! code = code[3:] ! continue ! if c == LOAD_CONST and code[3] == IMPORT_NAME: ! oparg_1, oparg_2 = unpack('<xHxH', code[:6]) ! yield "import", (consts[oparg_1], names[oparg_2]) ! code = code[6:] ! continue if c >= HAVE_ARGUMENT: ! code = code[3:] ! else: ! code = code[1:] ! ! def scan_opcodes_25(self, co, ! unpack = struct.unpack): ! # Scan the code, and yield 'interesting' opcode combinations ! # Python 2.5 version (has absolute and relative imports) ! code = co.co_code ! names = co.co_names ! consts = co.co_consts ! LOAD_LOAD_AND_IMPORT = LOAD_CONST + LOAD_CONST + IMPORT_NAME ! while code: ! c = code[0] ! if c in STORE_OPS: ! oparg, = unpack('<H', code[1:3]) ! yield "store", (names[oparg],) ! code = code[3:] ! continue ! if code[:9:3] == LOAD_LOAD_AND_IMPORT: ! oparg_1, oparg_2, oparg_3 = unpack('<xHxHxH', code[:9]) ! level = consts[oparg_1] ! if level == -1: # normal import ! yield "import", (consts[oparg_2], names[oparg_3]) ! elif level == 0: # absolute import ! yield "absolute_import", (consts[oparg_2], names[oparg_3]) ! else: # relative import ! yield "relative_import", (level, consts[oparg_2], names[oparg_3]) ! code = code[9:] ! continue ! if c >= HAVE_ARGUMENT: ! code = code[3:] ! else: ! code = code[1:] ! ! def scan_code(self, co, m): ! code = co.co_code ! if sys.version_info >= (2, 5): ! scanner = self.scan_opcodes_25 ! else: ! scanner = self.scan_opcodes ! for what, args in scanner(co): ! if what == "store": ! name, = args ! m.globalnames[name] = 1 ! elif what in ("import", "absolute_import"): ! fromlist, name = args have_star = 0 if fromlist is not None: *************** *** 357,361 **** have_star = 1 fromlist = [f for f in fromlist if f != "*"] ! self._safe_import_hook(name, m, fromlist) if have_star: # We've encountered an "import *". If it is a Python module, --- 416,422 ---- have_star = 1 fromlist = [f for f in fromlist if f != "*"] ! if what == "absolute_import": level = 0 ! else: level = -1 ! self._safe_import_hook(name, m, fromlist, level=level) if have_star: # We've encountered an "import *". If it is a Python module, *************** *** 377,386 **** else: m.starimports[name] = 1 ! elif c in STORE_OPS: ! # keep track of all global names that are assigned to ! oparg = unpack('<H', code[i-2:i])[0] ! name = co.co_names[oparg] ! m.globalnames[name] = 1 ! for c in constants: if isinstance(c, type(co)): self.scan_code(c, m) --- 438,453 ---- else: m.starimports[name] = 1 ! elif what == "relative_import": ! level, fromlist, name = args ! if name: ! self._safe_import_hook(name, m, fromlist, level=level) ! else: ! parent = self.determine_parent(m, level=level) ! self._safe_import_hook(parent.__name__, None, fromlist, level=0) ! else: ! # We don't expect anything else from the generator. ! raise RuntimeError(what) ! ! for c in co.co_consts: if isinstance(c, type(co)): self.scan_code(c, m) *************** *** 538,542 **** consts[i] = self.replace_paths_in_code(consts[i]) ! return new.code(co.co_argcount, co.co_nlocals, co.co_stacksize, co.co_flags, co.co_code, tuple(consts), co.co_names, co.co_varnames, new_filename, co.co_name, --- 605,609 ---- consts[i] = self.replace_paths_in_code(consts[i]) ! return types.CodeType(co.co_argcount, co.co_nlocals, co.co_stacksize, co.co_flags, co.co_code, tuple(consts), co.co_names, co.co_varnames, new_filename, co.co_name, *************** *** 643,651 **** Base.run_script(self, pathname) ! def import_hook(self, name, caller=None, fromlist=None): old_last_caller = self._last_caller try: self._last_caller = caller ! return Base.import_hook(self,name,caller,fromlist) finally: self._last_caller = old_last_caller --- 710,718 ---- Base.run_script(self, pathname) ! def import_hook(self, name, caller=None, fromlist=None, level=-1): old_last_caller = self._last_caller try: self._last_caller = caller ! return Base.import_hook(self,name,caller,fromlist,level) finally: self._last_caller = old_last_caller |