diff -r 509e4801c378 -r 22878952f6e2 srcanamdw/codescanner/pyinstaller/mf.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/srcanamdw/codescanner/pyinstaller/mf.py Thu Feb 18 12:29:02 2010 +0530 @@ -0,0 +1,645 @@ +# Copyright (C) 2005, Giovanni Bajo +# Based on previous work under copyright (c) 2002 McMillan Enterprises, Inc. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +import sys, string, os, imp, marshal + +#=======================Owners==========================# +# An Owner does imports from a particular piece of turf +# That is, there's an Owner for each thing on sys.path +# There are owners for directories and .pyz files. +# There could be owners for zip files, or even URLs. +# Note that they replace the string in sys.path, +# but str(sys.path[n]) should yield the original string. + +STRINGTYPE = type('') + +class Owner: + def __init__(self, path): + self.path = path + def __str__(self): + return self.path + def getmod(self, nm): + return None + +class DirOwner(Owner): + def __init__(self, path): + if path == '': + path = os.getcwd() + if not os.path.isdir(path): + raise ValueError, "%s is not a directory" % path + Owner.__init__(self, path) + def getmod(self, nm, getsuffixes=imp.get_suffixes, loadco=marshal.loads): + pth = os.path.join(self.path, nm) + possibles = [(pth, 0, None)] + if os.path.isdir(pth): + possibles.insert(0, (os.path.join(pth, '__init__'), 1, pth)) + py = pyc = None + for pth, ispkg, pkgpth in possibles: + for ext, mode, typ in getsuffixes(): + attempt = pth+ext + try: + st = os.stat(attempt) + except: + pass + else: + if typ == imp.C_EXTENSION: + return ExtensionModule(nm, attempt) + elif typ == imp.PY_SOURCE: + py = (attempt, st) + else: + pyc = (attempt, st) + if py or pyc: + break + if py is None and pyc is None: + return None + while 1: + if pyc is None or py and pyc[1][8] < py[1][8]: + try: + co = compile(open(py[0], 'r').read()+'\n', py[0], 'exec') + if __debug__: + pth = py[0] + 'c' + else: + pth = py[0] + 'o' + break + except SyntaxError, e: + print "Syntax error in", py[0] + print e.args + raise + elif pyc: + stuff = open(pyc[0], 'rb').read() + try: + co = loadco(stuff[8:]) + pth = pyc[0] + break + except (ValueError, EOFError): + print "W: bad .pyc found (%s)" % pyc[0] + pyc = None + else: + return None + if not os.path.isabs(pth): + pth = os.path.abspath(pth) + if ispkg: + mod = PkgModule(nm, pth, co) + else: + mod = PyModule(nm, pth, co) + return mod + +class PYZOwner(Owner): + def __init__(self, path): + import archive + self.pyz = archive.ZlibArchive(path) + Owner.__init__(self, path) + def getmod(self, nm): + rslt = self.pyz.extract(nm) + if rslt: + ispkg, co = rslt + if ispkg: + return PkgInPYZModule(nm, co, self) + return PyModule(nm, self.path, co) + +_globalownertypes = [ + DirOwner, + PYZOwner, + Owner, +] + +#===================Import Directors====================================# +# ImportDirectors live on the metapath +# There's one for builtins, one for frozen modules, and one for sys.path +# Windows gets one for modules gotten from the Registry +# There should be one for Frozen modules +# Mac would have them for PY_RESOURCE modules etc. +# A generalization of Owner - their concept of "turf" is broader + +class ImportDirector(Owner): + pass +class BuiltinImportDirector(ImportDirector): + def __init__(self): + self.path = 'Builtins' + def getmod(self, nm, isbuiltin=imp.is_builtin): + if isbuiltin(nm): + return BuiltinModule(nm) + return None +class FrozenImportDirector(ImportDirector): + def __init__(self): + self.path = 'FrozenModules' + def getmod(self, nm, isfrozen=imp.is_frozen): + if isfrozen(nm): + return FrozenModule(nm) + return None +class RegistryImportDirector(ImportDirector): + # for Windows only + def __init__(self): + self.path = "WindowsRegistry" + self.map = {} + try: + import win32api + import win32con + except ImportError: + pass + else: + subkey = r"Software\Python\PythonCore\%s\Modules" % sys.winver + for root in (win32con.HKEY_CURRENT_USER, win32con.HKEY_LOCAL_MACHINE): + try: + #hkey = win32api.RegOpenKeyEx(root, subkey, 0, win32con.KEY_ALL_ACCESS) + hkey = win32api.RegOpenKeyEx(root, subkey, 0, win32con.KEY_READ) + except: + pass + else: + numsubkeys, numvalues, lastmodified = win32api.RegQueryInfoKey(hkey) + for i in range(numsubkeys): + subkeyname = win32api.RegEnumKey(hkey, i) + #hskey = win32api.RegOpenKeyEx(hkey, subkeyname, 0, win32con.KEY_ALL_ACCESS) + hskey = win32api.RegOpenKeyEx(hkey, subkeyname, 0, win32con.KEY_READ) + val = win32api.RegQueryValueEx(hskey, '') + desc = getDescr(val[0]) + #print " RegistryImportDirector got %s %s" % (val[0], desc) #XXX + self.map[subkeyname] = (val[0], desc) + hskey.Close() + hkey.Close() + break + def getmod(self, nm): + stuff = self.map.get(nm) + if stuff: + fnm, (suffix, mode, typ) = stuff + if typ == imp.C_EXTENSION: + return ExtensionModule(nm, fnm) + elif typ == imp.PY_SOURCE: + try: + co = compile(open(fnm, 'r').read()+'\n', fnm, 'exec') + except SyntaxError, e: + print "Invalid syntax in %s" % py[0] + print e.args + raise + else: + stuff = open(fnm, 'rb').read() + co = loadco(stuff[8:]) + return PyModule(nm, fnm, co) + return None +class PathImportDirector(ImportDirector): + def __init__(self, pathlist=None, importers=None, ownertypes=None): + if pathlist is None: + self.path = sys.path + else: + self.path = pathlist + if ownertypes == None: + self.ownertypes = _globalownertypes + else: + self.ownertypes = ownertypes + if importers: + self.shadowpath = importers + else: + self.shadowpath = {} + self.inMakeOwner = 0 + self.building = {} + def getmod(self, nm): + mod = None + for thing in self.path: + if type(thing) is STRINGTYPE: + owner = self.shadowpath.get(thing, -1) + if owner == -1: + owner = self.shadowpath[thing] = self.makeOwner(thing) + if owner: + mod = owner.getmod(nm) + else: + mod = thing.getmod(nm) + if mod: + break + return mod + def makeOwner(self, path): + if self.building.get(path): + return None + self.building[path] = 1 + owner = None + for klass in self.ownertypes: + try: + # this may cause an import, which may cause recursion + # hence the protection + owner = klass(path) + except: + pass + else: + break + del self.building[path] + return owner + + +def getDescr(fnm): + ext = os.path.splitext(fnm)[1] + for (suffix, mode, typ) in imp.get_suffixes(): + if suffix == ext: + return (suffix, mode, typ) + +#=================Import Tracker============================# +# This one doesn't really import, just analyzes +# If it *were* importing, it would be the one-and-only ImportManager +# ie, the builtin import +UNTRIED = -1 + +imptyps = ['top-level', 'conditional', 'delayed', 'delayed, conditional'] +import hooks + +class ImportTracker: + # really the equivalent of builtin import + def __init__(self, xpath=None, hookspath=None, excludes=None): + self.path = [] + self.warnings = {} + if xpath: + self.path = xpath + self.path.extend(sys.path) + self.modules = {} + self.metapath = [ + BuiltinImportDirector(), + FrozenImportDirector(), + RegistryImportDirector(), + PathImportDirector(self.path) + ] + if hookspath: + hooks.__path__.extend(hookspath) + self.excludes = excludes + if excludes is None: + self.excludes = [] + def analyze_r(self, nm, importernm=None): + importer = importernm + if importer is None: + importer = '__main__' + seen = {} + nms = self.analyze_one(nm, importernm) + nms = map(None, nms, [importer]*len(nms)) + i = 0 + while i < len(nms): + nm, importer = nms[i] + if seen.get(nm,0): + del nms[i] + mod = self.modules[nm] + if mod: + mod.xref(importer) + else: + i = i + 1 + seen[nm] = 1 + j = i + mod = self.modules[nm] + if mod: + mod.xref(importer) + for name, isdelayed, isconditional in mod.imports: + imptyp = isdelayed * 2 + isconditional + newnms = self.analyze_one(name, nm, imptyp) + newnms = map(None, newnms, [nm]*len(newnms)) + nms[j:j] = newnms + j = j + len(newnms) + return map(lambda a: a[0], nms) + def analyze_one(self, nm, importernm=None, imptyp=0): + # first see if we could be importing a relative name + contexts = [None] + _all = None + if importernm: + if self.ispackage(importernm): + contexts.insert(0,importernm) + else: + pkgnm = string.join(string.split(importernm, '.')[:-1], '.') + if pkgnm: + contexts.insert(0,pkgnm) + # so contexts is [pkgnm, None] or just [None] + # now break the name being imported up so we get: + # a.b.c -> [a, b, c] + nmparts = string.split(nm, '.') + if nmparts[-1] == '*': + del nmparts[-1] + _all = [] + nms = [] + for context in contexts: + ctx = context + for i in range(len(nmparts)): + nm = nmparts[i] + if ctx: + fqname = ctx + '.' + nm + else: + fqname = nm + mod = self.modules.get(fqname, UNTRIED) + if mod is UNTRIED: + mod = self.doimport(nm, ctx, fqname) + if mod: + nms.append(mod.__name__) + ctx = fqname + else: + break + else: + # no break, point i beyond end + i = i + 1 + if i: + break + # now nms is the list of modules that went into sys.modules + # just as result of the structure of the name being imported + # however, each mod has been scanned and that list is in mod.imports + if i IMPORT_NAME mod ; IMPORT_STAR +#JUMP_IF_FALSE / JUMP_IF_TRUE / JUMP_FORWARD + +def pass1(code): + instrs = [] + i = 0 + n = len(code) + curline = 0 + incondition = 0 + out = 0 + while i < n: + if i >= out: + incondition = 0 + c = code[i] + i = i+1 + op = ord(c) + if op >= dis.HAVE_ARGUMENT: + oparg = ord(code[i]) + ord(code[i+1])*256 + i = i+2 + else: + oparg = None + if not incondition and op in COND_OPS: + incondition = 1 + out = i + oparg + elif incondition and op == JUMP_FORWARD: + out = max(out, i + oparg) + if op == SET_LINENO: + curline = oparg + else: + instrs.append((op, oparg, incondition, curline)) + return instrs + +def scan_code(co, m=None, w=None, nested=0): + instrs = pass1(co.co_code) + if m is None: + m = [] + if w is None: + w = [] + all = None + lastname = None + for i in range(len(instrs)): + op, oparg, conditional, curline = instrs[i] + if op == IMPORT_NAME: + name = lastname = co.co_names[oparg] + m.append((name, nested, conditional)) + elif op == IMPORT_FROM: + name = co.co_names[oparg] + m.append((lastname+'.'+name, nested, conditional)) + assert lastname is not None + elif op == IMPORT_STAR: + m.append((lastname+'.*', nested, conditional)) + elif op == STORE_NAME: + if co.co_names[oparg] == "__all__": + j = i - 1 + pop, poparg, pcondtl, pline = instrs[j] + if pop != BUILD_LIST: + w.append("W: __all__ is built strangely at line %s" % pline) + else: + all = [] + while j > 0: + j = j - 1 + pop, poparg, pcondtl, pline = instrs[j] + if pop == LOAD_CONST: + all.append(co.co_consts[poparg]) + else: + break + elif op in STORE_OPS: + pass + elif op == LOAD_GLOBAL: + name = co.co_names[oparg] + cndtl = ['', 'conditional'][conditional] + lvl = ['top-level', 'delayed'][nested] + if name == "__import__": + w.append("W: %s %s __import__ hack detected at line %s" % (lvl, cndtl, curline)) + elif name == "eval": + w.append("W: %s %s eval hack detected at line %s" % (lvl, cndtl, curline)) + elif op == EXEC_STMT: + cndtl = ['', 'conditional'][conditional] + lvl = ['top-level', 'delayed'][nested] + w.append("W: %s %s exec statement detected at line %s" % (lvl, cndtl, curline)) + else: + lastname = None + for c in co.co_consts: + if isinstance(c, type(co)): + scan_code(c, m, w, 1) + return m, w, all