srcanamdw/codescanner/pyinstaller/iu.py
changeset 1 22878952f6e2
equal deleted inserted replaced
0:509e4801c378 1:22878952f6e2
       
     1 # Copyright (C) 2005, Giovanni Bajo
       
     2 # Based on previous work under copyright (c) 2002 McMillan Enterprises, Inc.
       
     3 #
       
     4 # This program is free software; you can redistribute it and/or
       
     5 # modify it under the terms of the GNU General Public License
       
     6 # as published by the Free Software Foundation; either version 2
       
     7 # of the License, or (at your option) any later version.
       
     8 #
       
     9 # In addition to the permissions in the GNU General Public License, the
       
    10 # authors give you unlimited permission to link or embed the compiled
       
    11 # version of this file into combinations with other programs, and to
       
    12 # distribute those combinations without any restriction coming from the
       
    13 # use of this file. (The General Public License restrictions do apply in
       
    14 # other respects; for example, they cover modification of the file, and
       
    15 # distribution when not linked into a combine executable.)
       
    16 #
       
    17 # This program is distributed in the hope that it will be useful,
       
    18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    20 # GNU General Public License for more details.
       
    21 #
       
    22 # You should have received a copy of the GNU General Public License
       
    23 # along with this program; if not, write to the Free Software
       
    24 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
       
    25 
       
    26 # **NOTE** This module is used during bootstrap. Import *ONLY* builtin modules.
       
    27 import sys
       
    28 import imp
       
    29 import marshal
       
    30 
       
    31 try:
       
    32     py_version = sys.version_info
       
    33 except AttributeError:
       
    34     py_version = (1,5)
       
    35 
       
    36 #=======================Owners==========================#
       
    37 # An Owner does imports from a particular piece of turf
       
    38 # That is, there's an Owner for each thing on sys.path
       
    39 # There are owners for directories and .pyz files.
       
    40 # There could be owners for zip files, or even URLs.
       
    41 # A shadowpath (a dictionary mapping the names in
       
    42 # sys.path to their owners) is used so that sys.path
       
    43 # (or a package's __path__) is still a bunch of strings,
       
    44 
       
    45 STRINGTYPE = type('')
       
    46 
       
    47 class Owner:
       
    48     def __init__(self, path):
       
    49         self.path = path
       
    50     def __str__(self):
       
    51         return self.path
       
    52     def getmod(self, nm):
       
    53         return None
       
    54 class DirOwner(Owner):
       
    55     def __init__(self, path):
       
    56         if path == '':
       
    57             path = _os_getcwd()
       
    58         if not pathisdir(path):
       
    59             raise ValueError, "%s is not a directory" % path
       
    60         Owner.__init__(self, path)
       
    61     def getmod(self, nm, getsuffixes=imp.get_suffixes, loadco=marshal.loads, newmod=imp.new_module):
       
    62         pth =  _os_path_join(self.path, nm)
       
    63         possibles = [(pth, 0, None)]
       
    64         if pathisdir(pth):
       
    65             possibles.insert(0, (_os_path_join(pth, '__init__'), 1, pth))
       
    66         py = pyc = None
       
    67         for pth, ispkg, pkgpth in possibles:
       
    68             for ext, mode, typ in getsuffixes():
       
    69                 attempt = pth+ext
       
    70                 try:
       
    71                     st = _os_stat(attempt)
       
    72                 except:
       
    73                     pass
       
    74                 else:
       
    75                     if typ == imp.C_EXTENSION:
       
    76                         fp = open(attempt, 'rb')
       
    77                         mod = imp.load_module(nm, fp, attempt, (ext, mode, typ))
       
    78                         mod.__file__ = attempt
       
    79                         return mod
       
    80                     elif typ == imp.PY_SOURCE:
       
    81                         py = (attempt, st)
       
    82                     else:
       
    83                         pyc = (attempt, st)
       
    84             if py or pyc:
       
    85                 break
       
    86         if py is None and pyc is None:
       
    87             return None
       
    88         while 1:
       
    89             if pyc is None or py and pyc[1][8] < py[1][8]:
       
    90                 try:
       
    91                     co = compile(open(py[0], 'r').read()+'\n', py[0], 'exec')
       
    92                     break
       
    93                 except SyntaxError, e:
       
    94                     print "Invalid syntax in %s" % py[0]
       
    95                     print e.args
       
    96                     raise
       
    97             elif pyc:
       
    98                 stuff = open(pyc[0], 'rb').read()
       
    99                 try:
       
   100                     co = loadco(stuff[8:])
       
   101                     break
       
   102                 except (ValueError, EOFError):
       
   103                     pyc = None
       
   104             else:
       
   105                 return None
       
   106         mod = newmod(nm)
       
   107         mod.__file__ = co.co_filename
       
   108         if ispkg:
       
   109             mod.__path__ = [pkgpth]
       
   110             subimporter = PathImportDirector(mod.__path__)
       
   111             mod.__importsub__ = subimporter.getmod
       
   112         mod.__co__ = co
       
   113         return mod
       
   114 
       
   115 _globalownertypes = [
       
   116     DirOwner,
       
   117     Owner,
       
   118 ]
       
   119 
       
   120 #===================Import Directors====================================#
       
   121 # ImportDirectors live on the metapath
       
   122 # There's one for builtins, one for frozen modules, and one for sys.path
       
   123 # Windows gets one for modules gotten from the Registry
       
   124 # Mac would have them for PY_RESOURCE modules etc.
       
   125 # A generalization of Owner - their concept of "turf" is broader
       
   126 
       
   127 class ImportDirector(Owner):
       
   128     pass
       
   129 class BuiltinImportDirector(ImportDirector):
       
   130     def __init__(self):
       
   131         self.path = 'Builtins'
       
   132     def getmod(self, nm, isbuiltin=imp.is_builtin):
       
   133         if isbuiltin(nm):
       
   134             mod = imp.load_module(nm, None, nm, ('','',imp.C_BUILTIN))
       
   135             return mod
       
   136         return None
       
   137 class FrozenImportDirector(ImportDirector):
       
   138     def __init__(self):
       
   139         self.path = 'FrozenModules'
       
   140     def getmod(self, nm, isfrozen=imp.is_frozen):
       
   141         if isfrozen(nm):
       
   142             mod = imp.load_module(nm, None, nm, ('','',imp.PY_FROZEN))
       
   143             if hasattr(mod, '__path__'):
       
   144                 mod.__importsub__ = lambda name, pname=nm, owner=self: owner.getmod(pname+'.'+name)
       
   145             return mod
       
   146         return None
       
   147 class RegistryImportDirector(ImportDirector):
       
   148     # for Windows only
       
   149     def __init__(self):
       
   150         self.path = "WindowsRegistry"
       
   151         self.map = {}
       
   152         try:
       
   153             import win32api
       
   154 ##            import win32con
       
   155         except ImportError:
       
   156             pass
       
   157         else:
       
   158             HKEY_CURRENT_USER = -2147483647
       
   159             HKEY_LOCAL_MACHINE = -2147483646
       
   160             KEY_ALL_ACCESS = 983103
       
   161             KEY_READ = 131097
       
   162             subkey = r"Software\Python\PythonCore\%s\Modules" % sys.winver
       
   163             for root in (HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE):
       
   164                 try:
       
   165                     #hkey = win32api.RegOpenKeyEx(root, subkey, 0, KEY_ALL_ACCESS)
       
   166                     hkey = win32api.RegOpenKeyEx(root, subkey, 0, KEY_READ)
       
   167                 except:
       
   168                     pass
       
   169                 else:
       
   170                     numsubkeys, numvalues, lastmodified = win32api.RegQueryInfoKey(hkey)
       
   171                     for i in range(numsubkeys):
       
   172                         subkeyname = win32api.RegEnumKey(hkey, i)
       
   173                         #hskey = win32api.RegOpenKeyEx(hkey, subkeyname, 0, KEY_ALL_ACCESS)
       
   174                         hskey = win32api.RegOpenKeyEx(hkey, subkeyname, 0, KEY_READ)
       
   175                         val = win32api.RegQueryValueEx(hskey, '')
       
   176                         desc = getDescr(val[0])
       
   177                         self.map[subkeyname] = (val[0], desc)
       
   178                         hskey.Close()
       
   179                     hkey.Close()
       
   180                     break
       
   181     def getmod(self, nm):
       
   182         stuff = self.map.get(nm)
       
   183         if stuff:
       
   184             fnm, desc = stuff
       
   185             fp = open(fnm, 'rb')
       
   186             mod = imp.load_module(nm, fp, fnm, desc)
       
   187             mod.__file__ = fnm
       
   188             return mod
       
   189         return None
       
   190 
       
   191 class PathImportDirector(ImportDirector):
       
   192     def __init__(self, pathlist=None, importers=None, ownertypes=None):
       
   193         if pathlist is None:
       
   194             self.path = sys.path
       
   195         else:
       
   196             self.path = pathlist
       
   197         if ownertypes == None:
       
   198             self.ownertypes = _globalownertypes
       
   199         else:
       
   200             self.ownertypes = ownertypes
       
   201         if importers:
       
   202             self.shadowpath = importers
       
   203         else:
       
   204             self.shadowpath = {}
       
   205         self.inMakeOwner = 0
       
   206         self.building = {}
       
   207     def getmod(self, nm):
       
   208         mod = None
       
   209         for thing in self.path:
       
   210             if type(thing) is STRINGTYPE:
       
   211                 owner = self.shadowpath.get(thing, -1)
       
   212                 if owner == -1:
       
   213                     owner = self.shadowpath[thing] = self.makeOwner(thing)
       
   214                 if owner:
       
   215                     mod = owner.getmod(nm)
       
   216             else:
       
   217                 mod = thing.getmod(nm)
       
   218             if mod:
       
   219                 break
       
   220         return mod
       
   221     def makeOwner(self, path):
       
   222         if self.building.get(path):
       
   223             return None
       
   224         self.building[path] = 1
       
   225         owner = None
       
   226         for klass in self.ownertypes:
       
   227             try:
       
   228                 # this may cause an import, which may cause recursion
       
   229                 # hence the protection
       
   230                 owner = klass(path)
       
   231             except:
       
   232                 pass
       
   233             else:
       
   234                 break
       
   235         del self.building[path]
       
   236         return owner
       
   237 
       
   238 def getDescr(fnm):
       
   239     ext = getpathext(fnm)
       
   240     for (suffix, mode, typ) in imp.get_suffixes():
       
   241         if suffix == ext:
       
   242             return (suffix, mode, typ)
       
   243 
       
   244 #=================ImportManager============================#
       
   245 # The one-and-only ImportManager
       
   246 # ie, the builtin import
       
   247 
       
   248 UNTRIED = -1
       
   249 
       
   250 class ImportManager:
       
   251     # really the equivalent of builtin import
       
   252     def __init__(self):
       
   253         self.metapath = [
       
   254             BuiltinImportDirector(),
       
   255             FrozenImportDirector(),
       
   256             RegistryImportDirector(),
       
   257             PathImportDirector()
       
   258         ]
       
   259         self.threaded = 0
       
   260         self.rlock = None
       
   261         self.locker = None
       
   262         self.setThreaded()
       
   263     def setThreaded(self):
       
   264         thread = sys.modules.get('thread', None)
       
   265         if thread and not self.threaded:
       
   266 ##            print "iu setting threaded"
       
   267             self.threaded = 1
       
   268             self.rlock = thread.allocate_lock()
       
   269             self._get_ident = thread.get_ident
       
   270     def install(self):
       
   271         import __builtin__
       
   272         __builtin__.__import__ = self.importHook
       
   273         __builtin__.reload = self.reloadHook
       
   274     def importHook(self, name, globals=None, locals=None, fromlist=None):
       
   275         # first see if we could be importing a relative name
       
   276         #print "importHook(%s, %s, locals, %s)" % (name, globals['__name__'], fromlist)
       
   277         _sys_modules_get = sys.modules.get
       
   278         contexts = [None]
       
   279         if globals:
       
   280             importernm = globals.get('__name__', '')
       
   281             if importernm:
       
   282                 if hasattr(_sys_modules_get(importernm), '__path__'):
       
   283                     # If you use the "from __init__ import" syntax, the package
       
   284                     # name will have a __init__ in it. We want to strip it.
       
   285                     if importernm[-len(".__init__"):] == ".__init__":
       
   286                         importernm = importernm[:-len(".__init__")]
       
   287                     contexts.insert(0,importernm)
       
   288                 else:
       
   289                     pkgnm = packagename(importernm)
       
   290                     if pkgnm:
       
   291                         contexts.insert(0,pkgnm)
       
   292         # so contexts is [pkgnm, None] or just [None]
       
   293         # now break the name being imported up so we get:
       
   294         # a.b.c -> [a, b, c]
       
   295         nmparts = namesplit(name)
       
   296         _self_doimport = self.doimport
       
   297         threaded = self.threaded
       
   298         for context in contexts:
       
   299             ctx = context
       
   300             for i in range(len(nmparts)):
       
   301                 nm = nmparts[i]
       
   302                 #print " importHook trying %s in %s" % (nm, ctx)
       
   303                 if ctx:
       
   304                     fqname = ctx + '.' + nm
       
   305                 else:
       
   306                     fqname = nm
       
   307                 if threaded:
       
   308                     self._acquire()
       
   309                 mod = _sys_modules_get(fqname, UNTRIED)
       
   310                 if mod is UNTRIED:
       
   311                     try:
       
   312                         mod = _self_doimport(nm, ctx, fqname)
       
   313                     except:
       
   314                         if threaded:
       
   315                             self._release()
       
   316                         raise
       
   317                 if threaded:
       
   318                     self._release()
       
   319                 if mod:
       
   320                     ctx = fqname
       
   321                 else:
       
   322                     break
       
   323             else:
       
   324                 # no break, point i beyond end
       
   325                 i = i + 1
       
   326             if i:
       
   327                 break
       
   328 
       
   329         if i<len(nmparts):
       
   330             if ctx and hasattr(sys.modules[ctx], nmparts[i]):
       
   331                 #print "importHook done with %s %s %s (case 1)" % (name, globals['__name__'], fromlist)
       
   332                 return sys.modules[nmparts[0]]
       
   333             del sys.modules[fqname]
       
   334             raise ImportError, "No module named %s" % fqname
       
   335         if fromlist is None:
       
   336             #print "importHook done with %s %s %s (case 2)" % (name, globals['__name__'], fromlist)
       
   337             if context:
       
   338                 return sys.modules[context+'.'+nmparts[0]]
       
   339             return sys.modules[nmparts[0]]
       
   340         bottommod = sys.modules[ctx]
       
   341         if hasattr(bottommod, '__path__'):
       
   342             fromlist = list(fromlist)
       
   343             i = 0
       
   344             while i < len(fromlist):
       
   345                 nm = fromlist[i]
       
   346                 if nm == '*':
       
   347                     fromlist[i:i+1] = list(getattr(bottommod, '__all__', []))
       
   348                     if i >= len(fromlist):
       
   349                         break
       
   350                     nm = fromlist[i]
       
   351                 i = i + 1
       
   352                 if not hasattr(bottommod, nm):
       
   353                     if threaded:
       
   354                         self._acquire()
       
   355                     try:
       
   356                         mod = self.doimport(nm, ctx, ctx+'.'+nm)
       
   357                     except:
       
   358                         pass
       
   359                     if threaded:
       
   360                         self._release()
       
   361         #print "importHook done with %s %s %s (case 3)" % (name, globals['__name__'], fromlist)
       
   362         return bottommod
       
   363     def doimport(self, nm, parentnm, fqname, reload=0):
       
   364         # Not that nm is NEVER a dotted name at this point
       
   365         #print "doimport(%s, %s, %s)" % (nm, parentnm, fqname)
       
   366         if parentnm:
       
   367             parent = sys.modules[parentnm]
       
   368             if hasattr(parent, '__path__'):
       
   369                 importfunc = getattr(parent, '__importsub__', None)
       
   370                 if not importfunc:
       
   371                     subimporter = PathImportDirector(parent.__path__)
       
   372                     importfunc = parent.__importsub__ = subimporter.getmod
       
   373                 mod = importfunc(nm)
       
   374                 if mod and not reload:
       
   375                     setattr(parent, nm, mod)
       
   376             else:
       
   377                 #print "..parent not a package"
       
   378                 return None
       
   379         else:
       
   380             # now we're dealing with an absolute import
       
   381             for director in self.metapath:
       
   382                 mod = director.getmod(nm)
       
   383                 if mod:
       
   384                     break
       
   385         if mod:
       
   386             mod.__name__ = fqname
       
   387             if reload:
       
   388                 sys.modules[fqname].__dict__.update(mod.__dict__)
       
   389             else:
       
   390                 sys.modules[fqname] = mod
       
   391             if hasattr(mod, '__co__'):
       
   392                 co = mod.__co__
       
   393                 del mod.__co__
       
   394                 try:
       
   395                     if reload:
       
   396                         exec co in sys.modules[fqname].__dict__
       
   397                     else:
       
   398                         exec co in mod.__dict__
       
   399                 except:
       
   400                     # In Python 2.4 and above, sys.modules is left clean
       
   401                     # after a broken import. We need to do the same to
       
   402                     # achieve perfect compatibility (see ticket #32).
       
   403                     if py_version >= (2,4,0):
       
   404                         # FIXME: how can we recover from a broken reload()?
       
   405                         # Should we save the mod dict and restore it in case
       
   406                         # of failure?
       
   407                         if not reload:
       
   408                             del sys.modules[fqname]
       
   409                     raise
       
   410             if fqname == 'thread' and not self.threaded:
       
   411 ##                print "thread detected!"
       
   412                 self.setThreaded()
       
   413         else:
       
   414             sys.modules[fqname] = None
       
   415         #print "..found %s" % mod
       
   416         return mod
       
   417     def reloadHook(self, mod):
       
   418         fqnm = mod.__name__
       
   419         nm = namesplit(fqnm)[-1]
       
   420         parentnm = packagename(fqnm)
       
   421         newmod = self.doimport(nm, parentnm, fqnm, reload=1)
       
   422         #mod.__dict__.update(newmod.__dict__)
       
   423         return newmod
       
   424     def _acquire(self):
       
   425         if self.rlock.locked():
       
   426             if self.locker == self._get_ident():
       
   427                 self.lockcount = self.lockcount + 1
       
   428 ##                print "_acquire incrementing lockcount to", self.lockcount
       
   429                 return
       
   430         self.rlock.acquire()
       
   431         self.locker = self._get_ident()
       
   432         self.lockcount = 0
       
   433 ##        print "_acquire first time!"
       
   434     def _release(self):
       
   435         if self.lockcount:
       
   436             self.lockcount = self.lockcount - 1
       
   437 ##            print "_release decrementing lockcount to", self.lockcount
       
   438         else:
       
   439             self.locker = None
       
   440             self.rlock.release()
       
   441 ##            print "_release releasing lock!"
       
   442 
       
   443 #=========some helper functions=============================#
       
   444 
       
   445 def packagename(s):
       
   446     for i in range(len(s)-1, -1, -1):
       
   447         if s[i] == '.':
       
   448             break
       
   449     else:
       
   450         return ''
       
   451     return s[:i]
       
   452 
       
   453 def namesplit(s):
       
   454     rslt = []
       
   455     i = j = 0
       
   456     for j in range(len(s)):
       
   457         if s[j] == '.':
       
   458             rslt.append(s[i:j])
       
   459             i = j+1
       
   460     if i < len(s):
       
   461         rslt.append(s[i:])
       
   462     return rslt
       
   463 
       
   464 def getpathext(fnm):
       
   465     for i in range(len(fnm)-1, -1, -1):
       
   466         if fnm[i] == '.':
       
   467             return fnm[i:]
       
   468     return ''
       
   469 
       
   470 def pathisdir(pathname):
       
   471     "Local replacement for os.path.isdir()."
       
   472     try:
       
   473         s = _os_stat(pathname)
       
   474     except OSError:
       
   475         return None
       
   476     return (s[0] & 0170000) == 0040000
       
   477 
       
   478 _os_stat = _os_path_join = _os_getcwd = _os_path_dirname = None
       
   479 def _os_bootstrap():
       
   480     "Set up 'os' module replacement functions for use during import bootstrap."
       
   481 
       
   482     names = sys.builtin_module_names
       
   483 
       
   484     join = dirname = None
       
   485     mindirlen = 0
       
   486     if 'posix' in names:
       
   487         sep = '/'
       
   488         mindirlen = 1
       
   489         from posix import stat, getcwd
       
   490     elif 'nt' in names:
       
   491         sep = '\\'
       
   492         mindirlen = 3
       
   493         from nt import stat, getcwd
       
   494     elif 'dos' in names:
       
   495         sep = '\\'
       
   496         mindirlen = 3
       
   497         from dos import stat, getcwd
       
   498     elif 'os2' in names:
       
   499         sep = '\\'
       
   500         from os2 import stat, getcwd
       
   501     elif 'mac' in names:
       
   502         from mac import stat, getcwd
       
   503         def join(a, b):
       
   504             if a == '':
       
   505                 return b
       
   506             path = s
       
   507             if ':' not in a:
       
   508                 a = ':' + a
       
   509             if a[-1:] != ':':
       
   510                 a = a + ':'
       
   511             return a + b
       
   512     else:
       
   513         raise ImportError, 'no os specific module found'
       
   514 
       
   515     if join is None:
       
   516         def join(a, b, sep=sep):
       
   517             if a == '':
       
   518                 return b
       
   519             lastchar = a[-1:]
       
   520             if lastchar == '/' or lastchar == sep:
       
   521                 return a + b
       
   522             return a + sep + b
       
   523 
       
   524     if dirname is None:
       
   525         def dirname(a, sep=sep, mindirlen=mindirlen):
       
   526             for i in range(len(a)-1, -1, -1):
       
   527                 c = a[i]
       
   528                 if c == '/' or c == sep:
       
   529                     if i < mindirlen:
       
   530                         return a[:i+1]
       
   531                     return a[:i]
       
   532             return ''
       
   533 
       
   534     global _os_stat
       
   535     _os_stat = stat
       
   536 
       
   537     global _os_path_join
       
   538     _os_path_join = join
       
   539 
       
   540     global _os_path_dirname
       
   541     _os_path_dirname = dirname
       
   542 
       
   543     global _os_getcwd
       
   544     _os_getcwd = getcwd
       
   545 
       
   546 _string_replace = _string_join = _string_split = None
       
   547 def _string_bootstrap():
       
   548     """
       
   549     Set up 'string' module replacement functions for use during import bootstrap.
       
   550 
       
   551     During bootstrap, we can use only builtin modules since import does not work
       
   552     yet. For Python 2.0+, we can use string methods so this is not a problem.
       
   553     For Python 1.5, we would need the string module, so we need replacements.
       
   554     """
       
   555     s = type('')
       
   556 
       
   557     global _string_replace, _string_join, _string_split
       
   558 
       
   559     if hasattr(s, "join"):
       
   560         _string_join = s.join
       
   561     else:
       
   562         def join(sep, words):
       
   563             res = ''
       
   564             for w in words:
       
   565                     res = res + (sep + w)
       
   566             return res[len(sep):]
       
   567         _string_join = join
       
   568 
       
   569     if hasattr(s, "split"):
       
   570         _string_split = s.split
       
   571     else:
       
   572         def split(s, sep, maxsplit=0):
       
   573             res = []
       
   574             nsep = len(sep)
       
   575             if nsep == 0:
       
   576                     return [s]
       
   577             ns = len(s)
       
   578             if maxsplit <= 0: maxsplit = ns
       
   579             i = j = 0
       
   580             count = 0
       
   581             while j+nsep <= ns:
       
   582                     if s[j:j+nsep] == sep:
       
   583                             count = count + 1
       
   584                             res.append(s[i:j])
       
   585                             i = j = j + nsep
       
   586                             if count >= maxsplit: break
       
   587                     else:
       
   588                             j = j + 1
       
   589             res.append(s[i:])
       
   590             return res
       
   591         _string_split = split
       
   592 
       
   593     if hasattr(s, "replace"):
       
   594         _string_replace = s.replace
       
   595     else:
       
   596         def replace(str, old, new):
       
   597             return _string_join(new, _string_split(str, old))
       
   598         _string_replace = replace
       
   599 
       
   600 
       
   601 
       
   602 _os_bootstrap()
       
   603 _string_bootstrap()