Files
pyinstaller/iu.py
T
naufraghi 82ab43bb1e Merged revisions 342-393,401-404,413,424,426-427,429-433,435-437,439-442,445,448 via svnmerge from
https://svn.pyinstaller.python-hosting.com/branches/python2.5

........
  r342 | naufraghi | 2007-12-03 20:02:47 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r238@rosen:  naufraghi | 2007-12-03 19:59:24 +0100
    r200@rosen:  naufraghi | 2007-11-23 15:54:13 +0100
    Cleanup, remove some warning
   
........
  r343 | naufraghi | 2007-12-03 20:02:56 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r239@rosen:  naufraghi | 2007-12-03 19:59:24 +0100
    r201@rosen:  naufraghi | 2007-11-23 17:23:15 +0100
    Allow starting runtests from any path
   
........
  r344 | naufraghi | 2007-12-03 20:03:04 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r240@rosen:  naufraghi | 2007-12-03 20:00:51 +0100
    r202@rosen:  naufraghi | 2007-11-23 17:24:17 +0100
    Add natural sort for tests
   
........
  r345 | naufraghi | 2007-12-03 20:03:12 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r241@rosen:  naufraghi | 2007-12-03 20:00:51 +0100
    r203@rosen:  naufraghi | 2007-11-23 17:32:46 +0100
    Fix some fragile import?
   
........
  r346 | naufraghi | 2007-12-03 20:03:21 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r242@rosen:  naufraghi | 2007-12-03 20:01:01 +0100
    r204@rosen:  naufraghi | 2007-11-23 17:46:41 +0100
    Adds a basic way to choose tests to run
   
........
  r347 | naufraghi | 2007-12-03 20:03:29 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r243@rosen:  naufraghi | 2007-12-03 20:01:04 +0100
    r205@rosen:  naufraghi | 2007-11-23 17:57:31 +0100
    Adds and xml.dom test
   
........
  r348 | naufraghi | 2007-12-03 20:03:38 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r244@rosen:  naufraghi | 2007-12-03 20:01:04 +0100
    r206@rosen:  naufraghi | 2007-11-23 18:05:04 +0100
    Remove cmd line quoting
   
........
  r349 | naufraghi | 2007-12-03 20:03:46 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r245@rosen:  naufraghi | 2007-12-03 20:01:06 +0100
    r207@rosen:  naufraghi | 2007-11-23 19:47:13 +0100
    Adds 'import os' in one specfile
   
........
  r350 | naufraghi | 2007-12-03 20:03:54 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r246@rosen:  naufraghi | 2007-12-03 20:01:08 +0100
    r208@rosen:  naufraghi | 2007-11-23 19:49:21 +0100
    Add an 'encoding' hiddeimport test
   
........
  r351 | naufraghi | 2007-12-03 20:04:05 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r248@rosen:  naufraghi | 2007-12-03 20:01:08 +0100
    r211@rosen:  naufraghi | 2007-11-27 16:13:30 +0100
    Rewrite exec in execfile
   
........
  r352 | naufraghi | 2007-12-03 20:04:15 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r250@rosen:  naufraghi | 2007-12-03 20:01:09 +0100
    r214@rosen:  naufraghi | 2007-11-30 11:49:23 +0100
    Adds support for extended __path__
   
........
  r353 | naufraghi | 2007-12-03 20:04:23 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r251@rosen:  naufraghi | 2007-12-03 20:01:13 +0100
    r215@rosen:  naufraghi | 2007-11-30 11:52:18 +0100
    Simplify execfile
   
........
  r354 | naufraghi | 2007-12-03 20:04:30 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r252@rosen:  naufraghi | 2007-12-03 20:01:15 +0100
    r216@rosen:  naufraghi | 2007-11-30 11:52:56 +0100
    Fix output path
   
........
  r355 | naufraghi | 2007-12-03 20:04:38 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r253@rosen:  naufraghi | 2007-12-03 20:01:16 +0100
    r217@rosen:  naufraghi | 2007-11-30 12:13:17 +0100
    Add optional logging of self.moduleds
   
........
  r356 | naufraghi | 2007-12-03 20:04:46 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r254@rosen:  naufraghi | 2007-12-03 20:01:16 +0100
    r218@rosen:  naufraghi | 2007-11-30 12:19:13 +0100
    Add __str__ at Module class (and adds a default __file__ too)
   
........
  r357 | naufraghi | 2007-12-03 20:04:54 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r255@rosen:  naufraghi | 2007-12-03 20:01:18 +0100
    r219@rosen:  naufraghi | 2007-11-30 12:30:19 +0100
    Add version info to log filename
   
........
  r358 | naufraghi | 2007-12-03 20:05:01 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r256@rosen:  naufraghi | 2007-12-03 20:01:19 +0100
    r220@rosen:  naufraghi | 2007-11-30 16:11:07 +0100
    Asset-ize a comment + cosmetics (align variable name to other scopes)
   
........
  r359 | naufraghi | 2007-12-03 20:05:09 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r257@rosen:  naufraghi | 2007-12-03 20:01:21 +0100
    r221@rosen:  naufraghi | 2007-11-30 16:46:17 +0100
    Add comments and a None-iti assert
   
........
  r360 | naufraghi | 2007-12-03 20:05:16 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r258@rosen:  naufraghi | 2007-12-03 20:01:24 +0100
    r222@rosen:  naufraghi | 2007-12-03 16:23:17 +0100
    Remove user interaction
   
........
  r361 | naufraghi | 2007-12-03 20:05:25 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r259@rosen:  naufraghi | 2007-12-03 20:01:25 +0100
    r223@rosen:  naufraghi | 2007-12-03 16:39:48 +0100
    Activate the option to run selected tests: runtests.py --run 12 13
   
........
  r362 | naufraghi | 2007-12-03 20:05:32 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r260@rosen:  naufraghi | 2007-12-03 20:01:28 +0100
    r224@rosen:  naufraghi | 2007-12-03 16:51:02 +0100
    Adds a test that fails
   
........
  r363 | naufraghi | 2007-12-03 20:05:41 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r261@rosen:  naufraghi | 2007-12-03 20:01:28 +0100
    r225@rosen:  naufraghi | 2007-12-03 17:11:07 +0100
    Expand imports
   
........
  r364 | naufraghi | 2007-12-03 20:05:48 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r262@rosen:  naufraghi | 2007-12-03 20:01:29 +0100
    r226@rosen:  naufraghi | 2007-12-03 17:12:21 +0100
    Reorder imports
   
........
  r365 | naufraghi | 2007-12-03 20:05:55 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r263@rosen:  naufraghi | 2007-12-03 20:01:30 +0100
    r227@rosen:  naufraghi | 2007-12-03 17:16:11 +0100
    Turns 1-0 to True-False
   
........
  r366 | naufraghi | 2007-12-03 20:06:03 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r264@rosen:  naufraghi | 2007-12-03 20:01:30 +0100
    r228@rosen:  naufraghi | 2007-12-03 17:32:17 +0100
    Path cleanup
   
........
  r367 | naufraghi | 2007-12-03 20:06:10 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r265@rosen:  naufraghi | 2007-12-03 20:01:32 +0100
    r229@rosen:  naufraghi | 2007-12-03 17:35:21 +0100
    Followup: Path cleanup
   
........
  r368 | naufraghi | 2007-12-03 20:06:17 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r266@rosen:  naufraghi | 2007-12-03 20:01:33 +0100
    r230@rosen:  naufraghi | 2007-12-03 18:42:00 +0100
    Add some docs to assemble()
   
........
  r369 | naufraghi | 2007-12-03 20:06:23 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r267@rosen:  naufraghi | 2007-12-03 20:01:35 +0100
    r231@rosen:  naufraghi | 2007-12-03 18:55:32 +0100
    Remove criptic outN.toc numbering, use class names + reformat docs
   
........
  r370 | naufraghi | 2007-12-03 20:06:30 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r268@rosen:  naufraghi | 2007-12-03 20:01:36 +0100
    r232@rosen:  naufraghi | 2007-12-03 18:56:26 +0100
    Restore common prefix 'out'
   
........
  r371 | naufraghi | 2007-12-03 20:06:38 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r269@rosen:  naufraghi | 2007-12-03 20:01:37 +0100
    r236@rosen:  naufraghi | 2007-12-03 19:16:19 +0100
    Cosmetic
   
........
  r372 | naufraghi | 2007-12-03 20:06:45 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r270@rosen:  naufraghi | 2007-12-03 20:01:37 +0100
    r237@rosen:  naufraghi | 2007-12-03 19:17:17 +0100
    Factorize py[c|o] extension choice
   
........
  r373 | naufraghi | 2007-12-04 12:01:51 +0100 (Mar, 04 Dic 2007) | 3 lines
  
   r302@rosen:  naufraghi | 2007-12-04 12:00:38 +0100
   Restore invcnum
........
  r374 | naufraghi | 2007-12-04 12:01:58 +0100 (Mar, 04 Dic 2007) | 3 lines
  
   r303@rosen:  naufraghi | 2007-12-04 12:01:41 +0100
   Add warning for mod == None
........
  r375 | naufraghi | 2007-12-04 12:08:04 +0100 (Mar, 04 Dic 2007) | 2 lines
  
  Add final final "done" message
........
  r376 | naufraghi | 2007-12-04 12:09:30 +0100 (Mar, 04 Dic 2007) | 3 lines
  
  Ops, is "config.dat"
........
  r377 | naufraghi | 2007-12-04 12:26:20 +0100 (Mar, 04 Dic 2007) | 2 lines
  
  Restored removed "break"
........
  r378 | naufraghi | 2007-12-04 16:01:18 +0100 (Mar, 04 Dic 2007) | 2 lines
  
  Remove already logged warning
........
  r379 | naufraghi | 2007-12-04 17:46:50 +0100 (Mar, 04 Dic 2007) | 1 line
  
  Minimize test case
........
  r380 | naufraghi | 2007-12-04 17:51:07 +0100 (Mar, 04 Dic 2007) | 1 line
  
  Update PathImportDirector if __path__ changes (for example if modified by _xmlplus hook)
........
  r381 | naufraghi | 2007-12-04 18:06:10 +0100 (Mar, 04 Dic 2007) | 1 line
  
  Localize hiddenimport and add hook
........
  r382 | naufraghi | 2007-12-04 19:37:45 +0100 (Mar, 04 Dic 2007) | 1 line
  
  Add another elementree test
........
  r383 | naufraghi | 2007-12-17 12:58:57 +0100 (Lun, 17 Dic 2007) | 1 line
  
  Fix importHook debug print, add other (commented) print debugs
........
  r384 | naufraghi | 2007-12-17 13:00:32 +0100 (Lun, 17 Dic 2007) | 1 line
  
  Support more then one log per spec
........
  r385 | naufraghi | 2007-12-17 13:01:10 +0100 (Lun, 17 Dic 2007) | 1 line
  
  Add hidden xml.etree.ElementTree import
........
  r386 | naufraghi | 2007-12-17 13:02:35 +0100 (Lun, 17 Dic 2007) | 1 line
  
  Restore PATH before assert + comments
........
  r387 | naufraghi | 2007-12-17 14:42:32 +0100 (Lun, 17 Dic 2007) | 1 line
  
  Print warnings for generic excepts in the code
........
  r388 | naufraghi | 2007-12-17 14:56:12 +0100 (Lun, 17 Dic 2007) | 1 line
  
  Use a specific exception for Owners
........
  r389 | naufraghi | 2007-12-17 16:44:59 +0100 (Lun, 17 Dic 2007) | 1 line
  
  Remove final comma
........
  r390 | naufraghi | 2007-12-18 14:51:06 +0100 (Mar, 18 Dic 2007) | 1 line
  
  Expand debug print
........
  r391 | naufraghi | 2007-12-19 18:21:05 +0100 (Mer, 19 Dic 2007) | 1 line
  
  Avoid 'import os' that causes problems in py25
........
  r392 | naufraghi | 2007-12-19 18:34:46 +0100 (Mer, 19 Dic 2007) | 1 line
  
  Represent with %r the exception
........
  r393 | naufraghi | 2007-12-19 18:37:52 +0100 (Mer, 19 Dic 2007) | 1 line
  
  Add comments and commented prints
........
  r401 | naufraghi | 2008-01-11 16:47:02 +0100 (Ven, 11 Gen 2008) | 1 line
  
  Use sys.executable saved at build time (unknown when frozen)
........
  r402 | naufraghi | 2008-01-11 17:17:37 +0100 (Ven, 11 Gen 2008) | 1 line
  
  Restore linux compatibility
........
  r403 | naufraghi | 2008-01-11 18:37:22 +0100 (Ven, 11 Gen 2008) | 1 line
  
  Add test for sys.getfilesystemencoding()
........
  r404 | naufraghi | 2008-01-11 19:42:42 +0100 (Ven, 11 Gen 2008) | 1 line
  
  Accept different error under windows (FIXME: do a real isfile check)
........
  r413 | naufraghi | 2008-01-25 19:47:50 +0100 (Ven, 25 Gen 2008) | 1 line
  
  Restore compatibility with python 2.4
........
  r424 | naufraghi | 2008-02-18 11:53:12 +0100 (Lun, 18 Feb 2008) | 3 lines
  
   r343@trinity:  naufraghi | 2008-02-18 11:53:00 +0100
   Merge dal trunk
........
  r426 | naufraghi | 2008-02-18 14:49:15 +0100 (Lun, 18 Feb 2008) | 1 line
  
  Catch SyntaxError too
........
  r427 | naufraghi | 2008-02-18 15:02:45 +0100 (Lun, 18 Feb 2008) | 1 line
  
  Revert: DummyZlib is a zero commpression zlib
........
  r429 | naufraghi | 2008-02-23 17:05:35 +0100 (Sab, 23 Feb 2008) | 1 line
  
  Add a (failing) test on module imp
........
  r430 | naufraghi | 2008-02-23 18:12:59 +0100 (Sab, 23 Feb 2008) | 1 line
  
  Modified runtest, now all tests are executed (default) but the interactive one(s), thet are executed if -i option is provided
........
  r431 | naufraghi | 2008-02-23 18:18:02 +0100 (Sab, 23 Feb 2008) | 1 line
  
  Merge dal branch dl
........
  r432 | danielevarrazzo | 2008-02-24 14:38:15 +0100 (Dom, 24 Feb 2008) | 2 lines
  
  Added missing file from the 'dl' branch.
........
  r433 | naufraghi | 2008-02-25 13:07:44 +0100 (Lun, 25 Feb 2008) | 1 line
  
  Continue on test failure and report (...) at the end
........
  r435 | naufraghi | 2008-02-25 13:28:08 +0100 (Lun, 25 Feb 2008) | 1 line
  
  Stub of a launcher rebuilder
........
  r436 | danielevarrazzo | 2008-02-25 13:30:56 +0100 (Lun, 25 Feb 2008) | 2 lines
  
  The Python library is found both in onedir and onefile mode.
........
  r437 | naufraghi | 2008-02-25 18:42:16 +0100 (Lun, 25 Feb 2008) | 1 line
  
  Add comments and (commented) debug prints
........
  r439 | naufraghi | 2008-02-28 00:16:38 +0100 (Gio, 28 Feb 2008) | 1 line
  
  Cosmetics
........
  r440 | danielevarrazzo | 2008-02-28 20:21:15 +0100 (Gio, 28 Feb 2008) | 4 lines
  
  The Python library is added to the package even if bindepend couldn't find it.
  
  This may happen when Python is statically linked, e.g. on debian-based systems.
........
  r441 | naufraghi | 2008-03-01 00:46:00 +0100 (Sab, 01 Mar 2008) | 1 line
  
  Remove too restrictive assert
........
  r442 | naufraghi | 2008-03-01 00:47:07 +0100 (Sab, 01 Mar 2008) | 1 line
  
  Run Configure.py after make
........
  r445 | naufraghi | 2008-04-28 19:42:13 +0200 (Lun, 28 Apr 2008) | 1 line
  
  Merge follow up
........
  r448 | naufraghi | 2008-04-30 15:41:51 +0200 (Mer, 30 Apr 2008) | 2 lines
  
  ops, svnmerge was not complete...
........


git-svn-id: http://svn.pyinstaller.org/trunk@449 8dd32b29-ccff-0310-8a9a-9233e24343b1
2008-04-30 14:30:09 +00:00

623 lines
22 KiB
Python

# Copyright (C) 2005, Giovanni Bajo
# Based on previous work under copyright (c) 2002 McMillan Enterprises, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# In addition to the permissions in the GNU General Public License, the
# authors give you unlimited permission to link or embed the compiled
# version of this file into combinations with other programs, and to
# distribute those combinations without any restriction coming from the
# use of this file. (The General Public License restrictions do apply in
# other respects; for example, they cover modification of the file, and
# distribution when not linked into a combine executable.)
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
# **NOTE** This module is used during bootstrap. Import *ONLY* builtin modules.
import sys
import imp
import marshal
try:
py_version = sys.version_info
except AttributeError:
py_version = (1,5)
#=======================Owners==========================#
# An Owner does imports from a particular piece of turf
# That is, there's an Owner for each thing on sys.path
# There are owners for directories and .pyz files.
# There could be owners for zip files, or even URLs.
# A shadowpath (a dictionary mapping the names in
# sys.path to their owners) is used so that sys.path
# (or a package's __path__) is still a bunch of strings,
STRINGTYPE = type('')
class OwnerError(IOError):
def __init__(self, msg):
self.msg = msg
def __str__(self):
return "<OwnerError %s>" % self.msg
class Owner:
def __init__(self, path):
self.path = path
def __str__(self):
return self.path
def getmod(self, nm):
return None
class DirOwner(Owner):
def __init__(self, path):
if path == '':
path = _os_getcwd()
if not pathisdir(path):
raise OwnerError("%s is not a directory" % path)
Owner.__init__(self, path)
def getmod(self, nm, getsuffixes=imp.get_suffixes, loadco=marshal.loads, newmod=imp.new_module):
pth = _os_path_join(self.path, nm)
possibles = [(pth, 0, None)]
if pathisdir(pth):
possibles.insert(0, (_os_path_join(pth, '__init__'), 1, pth))
py = pyc = None
for pth, ispkg, pkgpth in possibles:
for ext, mode, typ in getsuffixes():
attempt = pth+ext
try:
st = _os_stat(attempt)
except OSError, e:
assert e.errno == 2 #[Errno 2] No such file or directory
else:
if typ == imp.C_EXTENSION:
fp = open(attempt, 'rb')
mod = imp.load_module(nm, fp, attempt, (ext, mode, typ))
mod.__file__ = attempt
return mod
elif typ == imp.PY_SOURCE:
py = (attempt, st)
else:
pyc = (attempt, st)
if py or pyc:
break
if py is None and pyc is None:
return None
while 1:
if pyc is None or py and pyc[1][8] < py[1][8]:
try:
co = compile(open(py[0], 'r').read()+'\n', py[0], 'exec')
break
except SyntaxError, e:
print "Invalid syntax in %s" % py[0]
print e.args
raise
elif pyc:
stuff = open(pyc[0], 'rb').read()
try:
co = loadco(stuff[8:])
break
except (ValueError, EOFError):
pyc = None
else:
return None
mod = newmod(nm)
mod.__file__ = co.co_filename
if ispkg:
mod.__path__ = [pkgpth]
subimporter = PathImportDirector(mod.__path__)
mod.__importsub__ = subimporter.getmod
mod.__co__ = co
return mod
_globalownertypes = [
DirOwner,
Owner,
]
#===================Import Directors====================================#
# ImportDirectors live on the metapath
# There's one for builtins, one for frozen modules, and one for sys.path
# Windows gets one for modules gotten from the Registry
# Mac would have them for PY_RESOURCE modules etc.
# A generalization of Owner - their concept of "turf" is broader
class ImportDirector(Owner):
pass
class BuiltinImportDirector(ImportDirector):
def __init__(self):
self.path = 'Builtins'
def getmod(self, nm, isbuiltin=imp.is_builtin):
if isbuiltin(nm):
mod = imp.load_module(nm, None, nm, ('','',imp.C_BUILTIN))
return mod
return None
class FrozenImportDirector(ImportDirector):
def __init__(self):
self.path = 'FrozenModules'
def getmod(self, nm, isfrozen=imp.is_frozen):
if isfrozen(nm):
mod = imp.load_module(nm, None, nm, ('','',imp.PY_FROZEN))
if hasattr(mod, '__path__'):
mod.__importsub__ = lambda name, pname=nm, owner=self: owner.getmod(pname+'.'+name)
return mod
return None
class RegistryImportDirector(ImportDirector):
# for Windows only
def __init__(self):
self.path = "WindowsRegistry"
self.map = {}
try:
import win32api
## import win32con
except ImportError:
pass
else:
HKEY_CURRENT_USER = -2147483647
HKEY_LOCAL_MACHINE = -2147483646
KEY_ALL_ACCESS = 983103
KEY_READ = 131097
subkey = r"Software\Python\PythonCore\%s\Modules" % sys.winver
for root in (HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE):
try:
#hkey = win32api.RegOpenKeyEx(root, subkey, 0, KEY_ALL_ACCESS)
hkey = win32api.RegOpenKeyEx(root, subkey, 0, KEY_READ)
except Exception, e:
print "FIXME: RegOpenKeyEx Exception", e
else:
numsubkeys, numvalues, lastmodified = win32api.RegQueryInfoKey(hkey)
for i in range(numsubkeys):
subkeyname = win32api.RegEnumKey(hkey, i)
#hskey = win32api.RegOpenKeyEx(hkey, subkeyname, 0, KEY_ALL_ACCESS)
hskey = win32api.RegOpenKeyEx(hkey, subkeyname, 0, KEY_READ)
val = win32api.RegQueryValueEx(hskey, '')
desc = getDescr(val[0])
self.map[subkeyname] = (val[0], desc)
hskey.Close()
hkey.Close()
break
def getmod(self, nm):
stuff = self.map.get(nm)
if stuff:
fnm, desc = stuff
fp = open(fnm, 'rb')
mod = imp.load_module(nm, fp, fnm, desc)
mod.__file__ = fnm
return mod
return None
class PathImportDirector(ImportDirector):
def __init__(self, pathlist=None, importers=None, ownertypes=None):
if pathlist is None:
self.path = sys.path
else:
self.path = pathlist
if ownertypes == None:
self.ownertypes = _globalownertypes
else:
self.ownertypes = ownertypes
if importers:
self.shadowpath = importers
else:
self.shadowpath = {}
self.inMakeOwner = 0
self.building = {}
def getmod(self, nm):
mod = None
for thing in self.path:
if type(thing) is STRINGTYPE:
owner = self.shadowpath.get(thing, -1)
if owner == -1:
owner = self.shadowpath[thing] = self.makeOwner(thing)
if owner:
mod = owner.getmod(nm)
else:
mod = thing.getmod(nm)
if mod:
break
return mod
def makeOwner(self, path):
if self.building.get(path):
return None
self.building[path] = 1
owner = None
for klass in self.ownertypes:
try:
# this may cause an import, which may cause recursion
# hence the protection
owner = klass(path)
except OwnerError, e:
pass
else:
break
del self.building[path]
return owner
def getDescr(fnm):
ext = getpathext(fnm)
for (suffix, mode, typ) in imp.get_suffixes():
if suffix == ext:
return (suffix, mode, typ)
#=================ImportManager============================#
# The one-and-only ImportManager
# ie, the builtin import
UNTRIED = -1
class ImportManagerException(Exception):
def __init__(self, args):
self.args = args
def __repr__(self):
return "<%s: %s>" % (self.__name__, self.args)
class ImportManager:
# really the equivalent of builtin import
def __init__(self):
self.metapath = [
BuiltinImportDirector(),
FrozenImportDirector(),
RegistryImportDirector(),
PathImportDirector()
]
self.threaded = 0
self.rlock = None
self.locker = None
self.setThreaded()
def setThreaded(self):
thread = sys.modules.get('thread', None)
if thread and not self.threaded:
## print "iu setting threaded"
self.threaded = 1
self.rlock = thread.allocate_lock()
self._get_ident = thread.get_ident
def install(self):
import __builtin__
__builtin__.__import__ = self.importHook
__builtin__.reload = self.reloadHook
def importHook(self, name, globals=None, locals=None, fromlist=None, level=-1):
# first see if we could be importing a relative name
#print "importHook(%s, %s, locals, %s)" % (name, getattr(globals, '__name__', None), fromlist)
_sys_modules_get = sys.modules.get
contexts = [None]
if globals and level == -1:
# The level indicates we should attempt relative imports, add the
# package to searched contexts
importernm = globals.get('__name__', '')
if importernm:
if hasattr(_sys_modules_get(importernm), '__path__'):
# If you use the "from __init__ import" syntax, the package
# name will have a __init__ in it. We want to strip it.
if importernm[-len(".__init__"):] == ".__init__":
importernm = importernm[:-len(".__init__")]
contexts.insert(0,importernm)
else:
pkgnm = packagename(importernm)
if pkgnm:
contexts.insert(0,pkgnm)
# so contexts is [pkgnm, None] or just [None]
# now break the name being imported up so we get:
# a.b.c -> [a, b, c]
nmparts = namesplit(name)
_self_doimport = self.doimport
threaded = self.threaded
for context in contexts:
ctx = context
for i in range(len(nmparts)):
nm = nmparts[i]
#print " importHook trying %s in %s" % (nm, ctx)
if ctx:
fqname = ctx + '.' + nm
else:
fqname = nm
if threaded:
self._acquire()
mod = _sys_modules_get(fqname, UNTRIED)
if mod is UNTRIED:
try:
mod = _self_doimport(nm, ctx, fqname)
except Exception, e:
print "FIXME: _self_doimport %r" % e,
print " nm='%s' ctx='%s' fqname='%s'" % (nm, ctx, fqname)
if threaded:
self._release()
raise
if threaded:
self._release()
if mod:
ctx = fqname
else:
break
else:
# no break, point i beyond end
i = i + 1
if i:
break
if i<len(nmparts):
if ctx and hasattr(sys.modules[ctx], nmparts[i]):
#print "importHook done with %s %s %s (case 1)" % (name, globals['__name__'], fromlist)
return sys.modules[nmparts[0]]
del sys.modules[fqname]
raise ImportError, "No module named %s" % fqname
if fromlist is None:
#print "importHook done with %s %s %s (case 2)" % (name, globals['__name__'], fromlist)
if context:
return sys.modules[context+'.'+nmparts[0]]
return sys.modules[nmparts[0]]
bottommod = sys.modules[ctx]
if hasattr(bottommod, '__path__'):
fromlist = list(fromlist)
i = 0
while i < len(fromlist):
nm = fromlist[i]
if nm == '*':
fromlist[i:i+1] = list(getattr(bottommod, '__all__', []))
if i >= len(fromlist):
break
nm = fromlist[i]
i = i + 1
if not hasattr(bottommod, nm):
if threaded:
self._acquire()
try:
mod = self.doimport(nm, ctx, ctx+'.'+nm)
except Exception, e:
print "FIXME: self.doimport Exception", e
if threaded:
self._release()
#print "importHook done with %s %s %s (case 3)" % (name, globals['__name__'], fromlist)
return bottommod
def doimport(self, nm, parentnm, fqname, reload=0):
# Not that nm is NEVER a dotted name at this point
#print "doimport(%s, %s, %s)" % (nm, parentnm, fqname)
if parentnm:
parent = sys.modules[parentnm]
if hasattr(parent, '__path__'):
importfunc = getattr(parent, '__importsub__', None)
if not importfunc:
subimporter = PathImportDirector(parent.__path__)
importfunc = parent.__importsub__ = subimporter.getmod
mod = importfunc(nm)
if mod and not reload:
setattr(parent, nm, mod)
else:
#print "..parent not a package"
return None
else:
parent = None
# now we're dealing with an absolute import
for director in self.metapath:
mod = director.getmod(nm)
if mod:
break
if mod:
mod.__name__ = fqname
if reload:
sys.modules[fqname].__dict__.update(mod.__dict__)
else:
sys.modules[fqname] = mod
if hasattr(mod, '__co__'):
co = mod.__co__
del mod.__co__
try:
if reload:
exec co in sys.modules[fqname].__dict__
else:
exec co in mod.__dict__
except:
# In Python 2.4 and above, sys.modules is left clean
# after a broken import. We need to do the same to
# achieve perfect compatibility (see ticket #32).
if py_version >= (2,4,0):
# FIXME: how can we recover from a broken reload()?
# Should we save the mod dict and restore it in case
# of failure?
if not reload:
del sys.modules[fqname]
if hasattr(parent, nm):
delattr(parent, nm)
raise
if fqname == 'thread' and not self.threaded:
## print "thread detected!"
self.setThreaded()
else:
sys.modules[fqname] = None
#print "..found %s" % mod
return mod
def reloadHook(self, mod):
fqnm = mod.__name__
nm = namesplit(fqnm)[-1]
parentnm = packagename(fqnm)
newmod = self.doimport(nm, parentnm, fqnm, reload=1)
#mod.__dict__.update(newmod.__dict__)
return newmod
def _acquire(self):
if self.rlock.locked():
if self.locker == self._get_ident():
self.lockcount = self.lockcount + 1
## print "_acquire incrementing lockcount to", self.lockcount
return
self.rlock.acquire()
self.locker = self._get_ident()
self.lockcount = 0
## print "_acquire first time!"
def _release(self):
if self.lockcount:
self.lockcount = self.lockcount - 1
## print "_release decrementing lockcount to", self.lockcount
else:
self.locker = None
self.rlock.release()
## print "_release releasing lock!"
#=========some helper functions=============================#
def packagename(s):
for i in range(len(s)-1, -1, -1):
if s[i] == '.':
break
else:
return ''
return s[:i]
def namesplit(s):
rslt = []
i = j = 0
for j in range(len(s)):
if s[j] == '.':
rslt.append(s[i:j])
i = j+1
if i < len(s):
rslt.append(s[i:])
return rslt
def getpathext(fnm):
for i in range(len(fnm)-1, -1, -1):
if fnm[i] == '.':
return fnm[i:]
return ''
def pathisdir(pathname):
"Local replacement for os.path.isdir()."
try:
s = _os_stat(pathname)
except OSError:
return None
return (s[0] & 0170000) == 0040000
_os_stat = _os_path_join = _os_getcwd = _os_path_dirname = None
def _os_bootstrap():
"Set up 'os' module replacement functions for use during import bootstrap."
names = sys.builtin_module_names
join = dirname = None
mindirlen = 0
if 'posix' in names:
sep = '/'
mindirlen = 1
from posix import stat, getcwd
elif 'nt' in names:
sep = '\\'
mindirlen = 3
from nt import stat, getcwd
elif 'dos' in names:
sep = '\\'
mindirlen = 3
from dos import stat, getcwd
elif 'os2' in names:
sep = '\\'
from os2 import stat, getcwd
elif 'mac' in names:
from mac import stat, getcwd
def join(a, b):
if a == '':
return b
path = s
if ':' not in a:
a = ':' + a
if a[-1:] != ':':
a = a + ':'
return a + b
else:
raise ImportError, 'no os specific module found'
if join is None:
def join(a, b, sep=sep):
if a == '':
return b
lastchar = a[-1:]
if lastchar == '/' or lastchar == sep:
return a + b
return a + sep + b
if dirname is None:
def dirname(a, sep=sep, mindirlen=mindirlen):
for i in range(len(a)-1, -1, -1):
c = a[i]
if c == '/' or c == sep:
if i < mindirlen:
return a[:i+1]
return a[:i]
return ''
global _os_stat
_os_stat = stat
global _os_path_join
_os_path_join = join
global _os_path_dirname
_os_path_dirname = dirname
global _os_getcwd
_os_getcwd = getcwd
_string_replace = _string_join = _string_split = None
def _string_bootstrap():
"""
Set up 'string' module replacement functions for use during import bootstrap.
During bootstrap, we can use only builtin modules since import does not work
yet. For Python 2.0+, we can use string methods so this is not a problem.
For Python 1.5, we would need the string module, so we need replacements.
"""
s = type('')
global _string_replace, _string_join, _string_split
if hasattr(s, "join"):
_string_join = s.join
else:
def join(sep, words):
res = ''
for w in words:
res = res + (sep + w)
return res[len(sep):]
_string_join = join
if hasattr(s, "split"):
_string_split = s.split
else:
def split(s, sep, maxsplit=0):
res = []
nsep = len(sep)
if nsep == 0:
return [s]
ns = len(s)
if maxsplit <= 0: maxsplit = ns
i = j = 0
count = 0
while j+nsep <= ns:
if s[j:j+nsep] == sep:
count = count + 1
res.append(s[i:j])
i = j = j + nsep
if count >= maxsplit: break
else:
j = j + 1
res.append(s[i:])
return res
_string_split = split
if hasattr(s, "replace"):
_string_replace = s.replace
else:
def replace(str, old, new):
return _string_join(new, _string_split(str, old))
_string_replace = replace
_os_bootstrap()
_string_bootstrap()