srcanamdw/codescanner/pyinstaller/mf.py
author noe\swadi
Thu, 18 Feb 2010 12:29:02 +0530
changeset 1 22878952f6e2
permissions -rw-r--r--
Committing the CodeScanner Core tool This component has been moved from the StaticAnaApps package. BUG : 5889 (http://developer.symbian.org/webbugs/show_bug.cgi?id=5889).
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
     1
# Copyright (C) 2005, Giovanni Bajo
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
     2
# Based on previous work under copyright (c) 2002 McMillan Enterprises, Inc.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
     3
#
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
     4
# This program is free software; you can redistribute it and/or
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
     5
# modify it under the terms of the GNU General Public License
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
     6
# as published by the Free Software Foundation; either version 2
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
     7
# of the License, or (at your option) any later version.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
     8
#
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
     9
# This program is distributed in the hope that it will be useful,
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    12
# GNU General Public License for more details.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    13
#
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    14
# You should have received a copy of the GNU General Public License
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    15
# along with this program; if not, write to the Free Software
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    17
import sys, string, os, imp, marshal
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    18
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    19
#=======================Owners==========================#
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    20
# An Owner does imports from a particular piece of turf
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    21
# That is, there's an Owner for each thing on sys.path
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    22
# There are owners for directories and .pyz files.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    23
# There could be owners for zip files, or even URLs.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    24
# Note that they replace the string in sys.path,
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    25
# but str(sys.path[n]) should yield the original string.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    26
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    27
STRINGTYPE = type('')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    28
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    29
class Owner:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    30
    def __init__(self, path):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    31
        self.path = path
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    32
    def __str__(self):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    33
        return self.path
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    34
    def getmod(self, nm):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    35
        return None
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    36
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    37
class DirOwner(Owner):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    38
    def __init__(self, path):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    39
        if path == '':
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    40
            path = os.getcwd()
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    41
        if not os.path.isdir(path):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    42
            raise ValueError, "%s is not a directory" % path
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    43
        Owner.__init__(self, path)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    44
    def getmod(self, nm, getsuffixes=imp.get_suffixes, loadco=marshal.loads):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    45
        pth =  os.path.join(self.path, nm)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    46
        possibles = [(pth, 0, None)]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    47
        if os.path.isdir(pth):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    48
            possibles.insert(0, (os.path.join(pth, '__init__'), 1, pth))
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    49
        py = pyc = None
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    50
        for pth, ispkg, pkgpth in possibles:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    51
            for ext, mode, typ in getsuffixes():
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    52
                attempt = pth+ext
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    53
                try:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    54
                    st = os.stat(attempt)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    55
                except:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    56
                    pass
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    57
                else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    58
                    if typ == imp.C_EXTENSION:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    59
                        return ExtensionModule(nm, attempt)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    60
                    elif typ == imp.PY_SOURCE:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    61
                        py = (attempt, st)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    62
                    else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    63
                        pyc = (attempt, st)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    64
            if py or pyc:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    65
                break
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    66
        if py is None and pyc is None:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    67
            return None
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    68
        while 1:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    69
            if pyc is None or py and pyc[1][8] < py[1][8]:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    70
                try:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    71
                    co = compile(open(py[0], 'r').read()+'\n', py[0], 'exec')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    72
                    if __debug__:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    73
                        pth = py[0] + 'c'
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    74
                    else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    75
                        pth = py[0] + 'o'
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    76
                    break
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    77
                except SyntaxError, e:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    78
                    print "Syntax error in", py[0]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    79
                    print e.args
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    80
                    raise
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    81
            elif pyc:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    82
                stuff = open(pyc[0], 'rb').read()
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    83
                try:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    84
                    co = loadco(stuff[8:])
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    85
                    pth = pyc[0]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    86
                    break
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    87
                except (ValueError, EOFError):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    88
                    print "W: bad .pyc found (%s)" % pyc[0]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    89
                    pyc = None
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    90
            else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    91
                return None
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    92
        if not os.path.isabs(pth):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    93
            pth = os.path.abspath(pth)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    94
        if ispkg:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    95
            mod = PkgModule(nm, pth, co)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    96
        else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    97
            mod = PyModule(nm, pth, co)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    98
        return mod
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    99
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   100
class PYZOwner(Owner):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   101
    def __init__(self, path):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   102
        import archive
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   103
        self.pyz = archive.ZlibArchive(path)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   104
        Owner.__init__(self, path)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   105
    def getmod(self, nm):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   106
        rslt = self.pyz.extract(nm)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   107
        if rslt:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   108
            ispkg, co = rslt
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   109
        if ispkg:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   110
            return PkgInPYZModule(nm, co, self)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   111
        return PyModule(nm, self.path, co)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   112
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   113
_globalownertypes = [
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   114
    DirOwner,
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   115
    PYZOwner,
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   116
    Owner,
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   117
]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   118
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   119
#===================Import Directors====================================#
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   120
# ImportDirectors live on the metapath
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   121
# There's one for builtins, one for frozen modules, and one for sys.path
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   122
# Windows gets one for modules gotten from the Registry
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   123
# There should be one for Frozen modules
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   124
# Mac would have them for PY_RESOURCE modules etc.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   125
# A generalization of Owner - their concept of "turf" is broader
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   126
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   127
class ImportDirector(Owner):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   128
    pass
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   129
class BuiltinImportDirector(ImportDirector):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   130
    def __init__(self):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   131
        self.path = 'Builtins'
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   132
    def getmod(self, nm, isbuiltin=imp.is_builtin):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   133
        if isbuiltin(nm):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   134
            return BuiltinModule(nm)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   135
        return None
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   136
class FrozenImportDirector(ImportDirector):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   137
    def __init__(self):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   138
        self.path = 'FrozenModules'
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   139
    def getmod(self, nm, isfrozen=imp.is_frozen):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   140
        if isfrozen(nm):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   141
            return FrozenModule(nm)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   142
        return None
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   143
class RegistryImportDirector(ImportDirector):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   144
    # for Windows only
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   145
    def __init__(self):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   146
        self.path = "WindowsRegistry"
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   147
        self.map = {}
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   148
        try:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   149
            import win32api
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   150
            import win32con
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   151
        except ImportError:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   152
            pass
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   153
        else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   154
            subkey = r"Software\Python\PythonCore\%s\Modules" % sys.winver
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   155
            for root in (win32con.HKEY_CURRENT_USER, win32con.HKEY_LOCAL_MACHINE):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   156
                try:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   157
                    #hkey = win32api.RegOpenKeyEx(root, subkey, 0, win32con.KEY_ALL_ACCESS)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   158
                    hkey = win32api.RegOpenKeyEx(root, subkey, 0, win32con.KEY_READ)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   159
                except:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   160
                    pass
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   161
                else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   162
                    numsubkeys, numvalues, lastmodified = win32api.RegQueryInfoKey(hkey)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   163
                    for i in range(numsubkeys):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   164
                        subkeyname = win32api.RegEnumKey(hkey, i)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   165
                        #hskey = win32api.RegOpenKeyEx(hkey, subkeyname, 0, win32con.KEY_ALL_ACCESS)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   166
                        hskey = win32api.RegOpenKeyEx(hkey, subkeyname, 0, win32con.KEY_READ)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   167
                        val = win32api.RegQueryValueEx(hskey, '')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   168
                        desc = getDescr(val[0])
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   169
                        #print " RegistryImportDirector got %s %s" % (val[0], desc)  #XXX
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   170
                        self.map[subkeyname] = (val[0], desc)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   171
                        hskey.Close()
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   172
                    hkey.Close()
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   173
                    break
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   174
    def getmod(self, nm):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   175
        stuff = self.map.get(nm)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   176
        if stuff:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   177
            fnm, (suffix, mode, typ) = stuff
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   178
            if typ == imp.C_EXTENSION:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   179
                return ExtensionModule(nm, fnm)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   180
            elif typ == imp.PY_SOURCE:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   181
                try:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   182
                    co = compile(open(fnm, 'r').read()+'\n', fnm, 'exec')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   183
                except SyntaxError, e:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   184
                    print "Invalid syntax in %s" % py[0]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   185
                    print e.args
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   186
                    raise
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   187
            else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   188
                stuff = open(fnm, 'rb').read()
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   189
                co = loadco(stuff[8:])
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   190
            return PyModule(nm, fnm, co)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   191
        return None
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   192
class PathImportDirector(ImportDirector):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   193
    def __init__(self, pathlist=None, importers=None, ownertypes=None):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   194
        if pathlist is None:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   195
            self.path = sys.path
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   196
        else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   197
            self.path = pathlist
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   198
        if ownertypes == None:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   199
            self.ownertypes = _globalownertypes
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   200
        else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   201
            self.ownertypes = ownertypes
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   202
        if importers:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   203
            self.shadowpath = importers
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   204
        else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   205
            self.shadowpath = {}
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   206
        self.inMakeOwner = 0
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   207
        self.building = {}
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   208
    def getmod(self, nm):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   209
        mod = None
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   210
        for thing in self.path:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   211
            if type(thing) is STRINGTYPE:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   212
                owner = self.shadowpath.get(thing, -1)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   213
                if owner == -1:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   214
                    owner = self.shadowpath[thing] = self.makeOwner(thing)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   215
                if owner:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   216
                    mod = owner.getmod(nm)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   217
            else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   218
                mod = thing.getmod(nm)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   219
            if mod:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   220
                break
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   221
        return mod
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   222
    def makeOwner(self, path):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   223
        if self.building.get(path):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   224
            return None
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   225
        self.building[path] = 1
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   226
        owner = None
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   227
        for klass in self.ownertypes:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   228
            try:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   229
                # this may cause an import, which may cause recursion
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   230
                # hence the protection
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   231
                owner = klass(path)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   232
            except:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   233
                pass
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   234
            else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   235
                break
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   236
        del self.building[path]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   237
        return owner
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   238
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   239
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   240
def getDescr(fnm):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   241
    ext = os.path.splitext(fnm)[1]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   242
    for (suffix, mode, typ) in imp.get_suffixes():
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   243
        if suffix == ext:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   244
            return (suffix, mode, typ)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   245
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   246
#=================Import Tracker============================#
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   247
# This one doesn't really import, just analyzes
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   248
# If it *were* importing, it would be the one-and-only ImportManager
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   249
# ie, the builtin import
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   250
UNTRIED = -1
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   251
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   252
imptyps = ['top-level', 'conditional', 'delayed', 'delayed, conditional']
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   253
import hooks
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   254
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   255
class ImportTracker:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   256
    # really the equivalent of builtin import
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   257
    def __init__(self, xpath=None, hookspath=None, excludes=None):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   258
        self.path = []
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   259
        self.warnings = {}
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   260
        if xpath:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   261
            self.path = xpath
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   262
        self.path.extend(sys.path)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   263
        self.modules = {}
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   264
        self.metapath = [
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   265
            BuiltinImportDirector(),
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   266
            FrozenImportDirector(),
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   267
            RegistryImportDirector(),
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   268
            PathImportDirector(self.path)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   269
        ]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   270
        if hookspath:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   271
            hooks.__path__.extend(hookspath)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   272
        self.excludes = excludes
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   273
        if excludes is None:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   274
            self.excludes = []
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   275
    def analyze_r(self, nm, importernm=None):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   276
        importer = importernm
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   277
        if importer is None:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   278
            importer = '__main__'
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   279
        seen = {}
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   280
        nms = self.analyze_one(nm, importernm)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   281
        nms = map(None, nms, [importer]*len(nms))
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   282
        i = 0
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   283
        while i < len(nms):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   284
            nm, importer = nms[i]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   285
            if seen.get(nm,0):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   286
                del nms[i]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   287
                mod = self.modules[nm]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   288
                if mod:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   289
                    mod.xref(importer)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   290
            else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   291
                i = i + 1
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   292
                seen[nm] = 1
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   293
                j = i
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   294
                mod = self.modules[nm]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   295
                if mod:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   296
                    mod.xref(importer)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   297
                    for name, isdelayed, isconditional in mod.imports:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   298
                        imptyp = isdelayed * 2 + isconditional
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   299
                        newnms = self.analyze_one(name, nm, imptyp)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   300
                        newnms = map(None, newnms, [nm]*len(newnms))
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   301
                        nms[j:j] = newnms
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   302
                        j = j + len(newnms)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   303
        return map(lambda a: a[0], nms)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   304
    def analyze_one(self, nm, importernm=None, imptyp=0):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   305
        # first see if we could be importing a relative name
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   306
        contexts = [None]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   307
        _all = None
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   308
        if importernm:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   309
            if self.ispackage(importernm):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   310
                contexts.insert(0,importernm)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   311
            else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   312
                pkgnm = string.join(string.split(importernm, '.')[:-1], '.')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   313
                if pkgnm:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   314
                    contexts.insert(0,pkgnm)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   315
        # so contexts is [pkgnm, None] or just [None]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   316
        # now break the name being imported up so we get:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   317
        # a.b.c -> [a, b, c]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   318
        nmparts = string.split(nm, '.')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   319
        if nmparts[-1] == '*':
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   320
            del nmparts[-1]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   321
            _all = []
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   322
        nms = []
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   323
        for context in contexts:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   324
            ctx = context
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   325
            for i in range(len(nmparts)):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   326
                nm = nmparts[i]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   327
                if ctx:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   328
                    fqname = ctx + '.' + nm
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   329
                else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   330
                    fqname = nm
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   331
                mod = self.modules.get(fqname, UNTRIED)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   332
                if mod is UNTRIED:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   333
                    mod = self.doimport(nm, ctx, fqname)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   334
                if mod:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   335
                    nms.append(mod.__name__)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   336
                    ctx = fqname
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   337
                else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   338
                    break
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   339
            else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   340
                # no break, point i beyond end
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   341
                i = i + 1
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   342
            if i:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   343
                break
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   344
        # now nms is the list of modules that went into sys.modules
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   345
        # just as result of the structure of the name being imported
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   346
        # however, each mod has been scanned and that list is in mod.imports
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   347
        if i<len(nmparts):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   348
            if ctx:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   349
                if hasattr(self.modules[ctx], nmparts[i]):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   350
                    return nms
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   351
                if not self.ispackage(ctx):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   352
                    return nms
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   353
            self.warnings["W: no module named %s (%s import by %s)" % (fqname, imptyps[imptyp], importernm or "__main__")] = 1
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   354
            if self.modules.has_key(fqname):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   355
                del self.modules[fqname]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   356
            return nms
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   357
        if _all is None:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   358
            return nms
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   359
        bottommod = self.modules[ctx]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   360
        if bottommod.ispackage():
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   361
            for nm in bottommod._all:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   362
                if not hasattr(bottommod, nm):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   363
                    mod = self.doimport(nm, ctx, ctx+'.'+nm)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   364
                    if mod:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   365
                        nms.append(mod.__name__)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   366
                    else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   367
                        bottommod.warnings.append("W: name %s not found" % nm)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   368
        return nms
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   369
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   370
    def analyze_script(self, fnm):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   371
        try:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   372
            co = compile(open(fnm, 'r').read()+'\n', fnm, 'exec')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   373
        except SyntaxError, e:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   374
            print "Invalid syntax in %s" % fnm
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   375
            print e.args
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   376
            raise
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   377
        mod = PyScript(fnm, co)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   378
        self.modules['__main__'] = mod
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   379
        return self.analyze_r('__main__')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   380
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   381
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   382
    def ispackage(self, nm):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   383
        return self.modules[nm].ispackage()
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   384
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   385
    def doimport(self, nm, parentnm, fqname):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   386
        # Not that nm is NEVER a dotted name at this point
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   387
        if fqname in self.excludes:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   388
            return None
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   389
        if parentnm:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   390
            parent = self.modules[parentnm]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   391
            if parent.ispackage():
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   392
                mod = parent.doimport(nm)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   393
                if mod:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   394
                    setattr(parent, nm, mod)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   395
            else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   396
                return None
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   397
        else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   398
            # now we're dealing with an absolute import
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   399
            for director in self.metapath:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   400
                mod = director.getmod(nm)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   401
                if mod:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   402
                    break
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   403
        if mod:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   404
            mod.__name__ = fqname
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   405
            self.modules[fqname] = mod
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   406
            # now look for hooks
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   407
            # this (and scan_code) are instead of doing "exec co in mod.__dict__"
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   408
            try:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   409
                hookmodnm = 'hook-'+fqname
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   410
                hooks = __import__('hooks', globals(), locals(), [hookmodnm])
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   411
                hook = getattr(hooks, hookmodnm)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   412
                #print `hook`
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   413
            except (ImportError, AttributeError):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   414
                pass
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   415
            else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   416
                # rearranged so that hook() has a chance to mess with hiddenimports & attrs
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   417
                if hasattr(hook, 'hook'):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   418
                    mod = hook.hook(mod)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   419
                if hasattr(hook, 'hiddenimports'):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   420
                    for impnm in hook.hiddenimports:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   421
                        mod.imports.append((impnm, 0, 0))
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   422
                if hasattr(hook, 'attrs'):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   423
                    for attr, val in hook.attrs:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   424
                        setattr(mod, attr, val)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   425
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   426
                if fqname != mod.__name__:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   427
                    print "W: %s is changing it's name to %s" % (fqname, mod.__name__)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   428
                    self.modules[mod.__name__] = mod
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   429
        else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   430
            self.modules[fqname] = None
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   431
        return mod
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   432
    def getwarnings(self):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   433
        warnings = self.warnings.keys()
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   434
        for nm,mod in self.modules.items():
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   435
            if mod:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   436
                for w in mod.warnings:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   437
                    warnings.append(w+' - %s (%s)' % (mod.__name__, mod.__file__))
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   438
        return warnings
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   439
    def getxref(self):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   440
        mods = self.modules.items() # (nm, mod)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   441
        mods.sort()
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   442
        rslt = []
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   443
        for nm, mod in mods:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   444
            if mod:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   445
                importers = mod._xref.keys()
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   446
                importers.sort()
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   447
                rslt.append((nm, importers))
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   448
        return rslt
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   449
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   450
#====================Modules============================#
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   451
# All we're doing here is tracking, not importing
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   452
# If we were importing, these would be hooked to the real module objects
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   453
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   454
class Module:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   455
    _ispkg = 0
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   456
    typ = 'UNKNOWN'
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   457
    def __init__(self, nm):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   458
        self.__name__ = nm
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   459
        self._all = []
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   460
        self.imports = []
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   461
        self.warnings = []
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   462
        self._xref = {}
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   463
    def ispackage(self):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   464
        return self._ispkg
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   465
    def doimport(self, nm):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   466
        pass
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   467
    def xref(self, nm):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   468
        self._xref[nm] = 1
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   469
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   470
class BuiltinModule(Module):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   471
    typ = 'BUILTIN'
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   472
    def __init__(self, nm):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   473
        Module.__init__(self, nm)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   474
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   475
class ExtensionModule(Module):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   476
    typ = 'EXTENSION'
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   477
    def __init__(self, nm, pth):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   478
        Module.__init__(self, nm)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   479
        self.__file__ = pth
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   480
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   481
class PyModule(Module):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   482
    typ = 'PYMODULE'
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   483
    def __init__(self, nm, pth, co):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   484
        Module.__init__(self, nm)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   485
        self.co = co
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   486
        self.__file__ = pth
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   487
        if os.path.splitext(self.__file__)[1] == '.py':
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   488
            if __debug__:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   489
                self.__file__ = self.__file__ + 'c'
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   490
            else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   491
                self.__file__ = self.__file__ + 'o'
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   492
        self.scancode()
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   493
    def scancode(self):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   494
        self.imports, self.warnings, allnms = scan_code(self.co)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   495
        if allnms:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   496
            self._all = allnms
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   497
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   498
class PyScript(PyModule):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   499
    typ = 'PYSOURCE'
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   500
    def __init__(self, pth, co):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   501
        Module.__init__(self, '__main__')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   502
        self.co = co
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   503
        self.__file__ = pth
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   504
        self.scancode()
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   505
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   506
class PkgModule(PyModule):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   507
    typ = 'PYMODULE'
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   508
    def __init__(self, nm, pth, co):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   509
        PyModule.__init__(self, nm, pth, co)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   510
        self._ispkg = 1
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   511
        pth = os.path.dirname(pth)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   512
        self.__path__ = [ pth ]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   513
        self.subimporter = PathImportDirector(self.__path__)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   514
    def doimport(self, nm):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   515
        mod = self.subimporter.getmod(nm)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   516
        if mod:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   517
            mod.__name__ = self.__name__ + '.' + mod.__name__
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   518
        return mod
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   519
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   520
class PkgInPYZModule(PyModule):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   521
    def __init__(self, nm, co, pyzowner):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   522
        PyModule.__init__(self, nm, co.co_filename, co)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   523
        self._ispkg = 1
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   524
        self.__path__ = [ str(pyzowner) ]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   525
        self.owner = pyzowner
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   526
    def doimport(self, nm):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   527
        mod = self.owner.getmod(self.__name__ + '.' + nm)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   528
        return mod
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   529
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   530
#======================== Utility ================================#
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   531
# Scan the code object for imports, __all__ and wierd stuff
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   532
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   533
import dis
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   534
IMPORT_NAME = dis.opname.index('IMPORT_NAME')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   535
IMPORT_FROM = dis.opname.index('IMPORT_FROM')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   536
try:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   537
    IMPORT_STAR = dis.opname.index('IMPORT_STAR')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   538
except:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   539
    IMPORT_STAR = 999
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   540
STORE_NAME = dis.opname.index('STORE_NAME')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   541
STORE_FAST = dis.opname.index('STORE_FAST')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   542
STORE_GLOBAL = dis.opname.index('STORE_GLOBAL')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   543
LOAD_GLOBAL = dis.opname.index('LOAD_GLOBAL')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   544
EXEC_STMT = dis.opname.index('EXEC_STMT')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   545
try:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   546
    SET_LINENO = dis.opname.index('SET_LINENO')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   547
except ValueError:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   548
    SET_LINENO = 999
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   549
BUILD_LIST = dis.opname.index('BUILD_LIST')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   550
LOAD_CONST = dis.opname.index('LOAD_CONST')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   551
JUMP_IF_FALSE = dis.opname.index('JUMP_IF_FALSE')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   552
JUMP_IF_TRUE = dis.opname.index('JUMP_IF_TRUE')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   553
JUMP_FORWARD = dis.opname.index('JUMP_FORWARD')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   554
try:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   555
    STORE_DEREF = dis.opname.index('STORE_DEREF')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   556
except ValueError:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   557
    STORE_DEREF = 999
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   558
COND_OPS = [JUMP_IF_TRUE, JUMP_IF_FALSE]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   559
STORE_OPS = [STORE_NAME, STORE_FAST, STORE_GLOBAL, STORE_DEREF]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   560
#IMPORT_STAR -> IMPORT_NAME mod ; IMPORT_STAR
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   561
#JUMP_IF_FALSE / JUMP_IF_TRUE / JUMP_FORWARD
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   562
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   563
def pass1(code):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   564
    instrs = []
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   565
    i = 0
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   566
    n = len(code)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   567
    curline = 0
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   568
    incondition = 0
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   569
    out = 0
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   570
    while i < n:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   571
        if i >= out:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   572
            incondition = 0
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   573
        c = code[i]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   574
        i = i+1
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   575
        op = ord(c)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   576
        if op >= dis.HAVE_ARGUMENT:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   577
            oparg = ord(code[i]) + ord(code[i+1])*256
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   578
            i = i+2
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   579
        else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   580
            oparg = None
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   581
        if not incondition and op in COND_OPS:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   582
            incondition = 1
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   583
            out = i + oparg
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   584
        elif incondition and op == JUMP_FORWARD:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   585
            out = max(out, i + oparg)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   586
        if op == SET_LINENO:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   587
            curline = oparg
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   588
        else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   589
            instrs.append((op, oparg, incondition, curline))
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   590
    return instrs
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   591
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   592
def scan_code(co, m=None, w=None, nested=0):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   593
    instrs = pass1(co.co_code)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   594
    if m is None:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   595
        m = []
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   596
    if w is None:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   597
        w = []
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   598
    all = None
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   599
    lastname = None
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   600
    for i in range(len(instrs)):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   601
        op, oparg, conditional, curline = instrs[i]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   602
        if op == IMPORT_NAME:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   603
            name = lastname = co.co_names[oparg]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   604
            m.append((name, nested, conditional))
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   605
        elif op == IMPORT_FROM:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   606
            name = co.co_names[oparg]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   607
            m.append((lastname+'.'+name, nested, conditional))
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   608
            assert lastname is not None
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   609
        elif op == IMPORT_STAR:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   610
            m.append((lastname+'.*', nested, conditional))
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   611
        elif op == STORE_NAME:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   612
            if co.co_names[oparg] == "__all__":
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   613
                j = i - 1
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   614
                pop, poparg, pcondtl, pline = instrs[j]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   615
                if pop != BUILD_LIST:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   616
                    w.append("W: __all__ is built strangely at line %s" % pline)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   617
                else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   618
                    all = []
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   619
                    while j > 0:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   620
                        j = j - 1
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   621
                        pop, poparg, pcondtl, pline = instrs[j]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   622
                        if pop == LOAD_CONST:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   623
                            all.append(co.co_consts[poparg])
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   624
                        else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   625
                            break
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   626
        elif op in STORE_OPS:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   627
            pass
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   628
        elif op == LOAD_GLOBAL:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   629
            name = co.co_names[oparg]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   630
            cndtl = ['', 'conditional'][conditional]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   631
            lvl = ['top-level', 'delayed'][nested]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   632
            if name == "__import__":
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   633
                w.append("W: %s %s __import__ hack detected at line %s"  % (lvl, cndtl, curline))
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   634
            elif name == "eval":
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   635
                w.append("W: %s %s eval hack detected at line %s"  % (lvl, cndtl, curline))
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   636
        elif op == EXEC_STMT:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   637
            cndtl = ['', 'conditional'][conditional]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   638
            lvl = ['top-level', 'delayed'][nested]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   639
            w.append("W: %s %s exec statement detected at line %s"  % (lvl, cndtl, curline))
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   640
        else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   641
            lastname = None
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   642
    for c in co.co_consts:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   643
        if isinstance(c, type(co)):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   644
            scan_code(c, m, w, 1)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   645
    return m, w, all