symbian-qemu-0.9.1-12/python-2.6.1/Demo/imputil/importers.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 #
       
     2 # importers.py
       
     3 #
       
     4 # Demonstration subclasses of imputil.Importer
       
     5 #
       
     6 
       
     7 # There should be consideration for the imports below if it is desirable
       
     8 # to have "all" modules be imported through the imputil system.
       
     9 
       
    10 # these are C extensions
       
    11 import sys
       
    12 import imp
       
    13 import struct
       
    14 import marshal
       
    15 
       
    16 # these are .py modules
       
    17 import imputil
       
    18 import os
       
    19 
       
    20 ######################################################################
       
    21 
       
    22 _TupleType = type(())
       
    23 _StringType = type('')
       
    24 
       
    25 ######################################################################
       
    26 
       
    27 # byte-compiled file suffic character
       
    28 _suffix_char = __debug__ and 'c' or 'o'
       
    29 
       
    30 # byte-compiled file suffix
       
    31 _suffix = '.py' + _suffix_char
       
    32 
       
    33 # the C_EXTENSION suffixes
       
    34 _c_suffixes = filter(lambda x: x[2] == imp.C_EXTENSION, imp.get_suffixes())
       
    35 
       
    36 def _timestamp(pathname):
       
    37     "Return the file modification time as a Long."
       
    38     try:
       
    39         s = os.stat(pathname)
       
    40     except OSError:
       
    41         return None
       
    42     return long(s[8])
       
    43 
       
    44 def _fs_import(dir, modname, fqname):
       
    45     "Fetch a module from the filesystem."
       
    46 
       
    47     pathname = os.path.join(dir, modname)
       
    48     if os.path.isdir(pathname):
       
    49         values = { '__pkgdir__' : pathname, '__path__' : [ pathname ] }
       
    50         ispkg = 1
       
    51         pathname = os.path.join(pathname, '__init__')
       
    52     else:
       
    53         values = { }
       
    54         ispkg = 0
       
    55 
       
    56         # look for dynload modules
       
    57         for desc in _c_suffixes:
       
    58             file = pathname + desc[0]
       
    59             try:
       
    60                 fp = open(file, desc[1])
       
    61             except IOError:
       
    62                 pass
       
    63             else:
       
    64                 module = imp.load_module(fqname, fp, file, desc)
       
    65                 values['__file__'] = file
       
    66                 return 0, module, values
       
    67 
       
    68     t_py = _timestamp(pathname + '.py')
       
    69     t_pyc = _timestamp(pathname + _suffix)
       
    70     if t_py is None and t_pyc is None:
       
    71         return None
       
    72     code = None
       
    73     if t_py is None or (t_pyc is not None and t_pyc >= t_py):
       
    74         file = pathname + _suffix
       
    75         f = open(file, 'rb')
       
    76         if f.read(4) == imp.get_magic():
       
    77             t = struct.unpack('<I', f.read(4))[0]
       
    78             if t == t_py:
       
    79                 code = marshal.load(f)
       
    80         f.close()
       
    81     if code is None:
       
    82         file = pathname + '.py'
       
    83         code = _compile(file, t_py)
       
    84 
       
    85     values['__file__'] = file
       
    86     return ispkg, code, values
       
    87 
       
    88 ######################################################################
       
    89 #
       
    90 # Simple function-based importer
       
    91 #
       
    92 class FuncImporter(imputil.Importer):
       
    93     "Importer subclass to delegate to a function rather than method overrides."
       
    94     def __init__(self, func):
       
    95         self.func = func
       
    96     def get_code(self, parent, modname, fqname):
       
    97         return self.func(parent, modname, fqname)
       
    98 
       
    99 def install_with(func):
       
   100     FuncImporter(func).install()
       
   101 
       
   102 
       
   103 ######################################################################
       
   104 #
       
   105 # Base class for archive-based importing
       
   106 #
       
   107 class PackageArchiveImporter(imputil.Importer):
       
   108     """Importer subclass to import from (file) archives.
       
   109 
       
   110     This Importer handles imports of the style <archive>.<subfile>, where
       
   111     <archive> can be located using a subclass-specific mechanism and the
       
   112     <subfile> is found in the archive using a subclass-specific mechanism.
       
   113 
       
   114     This class defines two hooks for subclasses: one to locate an archive
       
   115     (and possibly return some context for future subfile lookups), and one
       
   116     to locate subfiles.
       
   117     """
       
   118 
       
   119     def get_code(self, parent, modname, fqname):
       
   120         if parent:
       
   121             # the Importer._finish_import logic ensures that we handle imports
       
   122             # under the top level module (package / archive).
       
   123             assert parent.__importer__ == self
       
   124 
       
   125             # if a parent "package" is provided, then we are importing a
       
   126             # sub-file from the archive.
       
   127             result = self.get_subfile(parent.__archive__, modname)
       
   128             if result is None:
       
   129                 return None
       
   130             if isinstance(result, _TupleType):
       
   131                 assert len(result) == 2
       
   132                 return (0,) + result
       
   133             return 0, result, {}
       
   134 
       
   135         # no parent was provided, so the archive should exist somewhere on the
       
   136         # default "path".
       
   137         archive = self.get_archive(modname)
       
   138         if archive is None:
       
   139             return None
       
   140         return 1, "", {'__archive__':archive}
       
   141 
       
   142     def get_archive(self, modname):
       
   143         """Get an archive of modules.
       
   144 
       
   145         This method should locate an archive and return a value which can be
       
   146         used by get_subfile to load modules from it. The value may be a simple
       
   147         pathname, an open file, or a complex object that caches information
       
   148         for future imports.
       
   149 
       
   150         Return None if the archive was not found.
       
   151         """
       
   152         raise RuntimeError, "get_archive not implemented"
       
   153 
       
   154     def get_subfile(self, archive, modname):
       
   155         """Get code from a subfile in the specified archive.
       
   156 
       
   157         Given the specified archive (as returned by get_archive()), locate
       
   158         and return a code object for the specified module name.
       
   159 
       
   160         A 2-tuple may be returned, consisting of a code object and a dict
       
   161         of name/values to place into the target module.
       
   162 
       
   163         Return None if the subfile was not found.
       
   164         """
       
   165         raise RuntimeError, "get_subfile not implemented"
       
   166 
       
   167 
       
   168 class PackageArchive(PackageArchiveImporter):
       
   169     "PackageArchiveImporter subclass that refers to a specific archive."
       
   170 
       
   171     def __init__(self, modname, archive_pathname):
       
   172         self.__modname = modname
       
   173         self.__path = archive_pathname
       
   174 
       
   175     def get_archive(self, modname):
       
   176         if modname == self.__modname:
       
   177             return self.__path
       
   178         return None
       
   179 
       
   180     # get_subfile is passed the full pathname of the archive
       
   181 
       
   182 
       
   183 ######################################################################
       
   184 #
       
   185 # Emulate the standard directory-based import mechanism
       
   186 #
       
   187 class DirectoryImporter(imputil.Importer):
       
   188     "Importer subclass to emulate the standard importer."
       
   189 
       
   190     def __init__(self, dir):
       
   191         self.dir = dir
       
   192 
       
   193     def get_code(self, parent, modname, fqname):
       
   194         if parent:
       
   195             dir = parent.__pkgdir__
       
   196         else:
       
   197             dir = self.dir
       
   198 
       
   199         # Return the module (and other info) if found in the specified
       
   200         # directory. Otherwise, return None.
       
   201         return _fs_import(dir, modname, fqname)
       
   202 
       
   203     def __repr__(self):
       
   204         return '<%s.%s for "%s" at 0x%x>' % (self.__class__.__module__,
       
   205                                              self.__class__.__name__,
       
   206                                              self.dir,
       
   207                                              id(self))
       
   208 
       
   209 
       
   210 ######################################################################
       
   211 #
       
   212 # Emulate the standard path-style import mechanism
       
   213 #
       
   214 class PathImporter(imputil.Importer):
       
   215     def __init__(self, path=sys.path):
       
   216         self.path = path
       
   217 
       
   218     def get_code(self, parent, modname, fqname):
       
   219         if parent:
       
   220             # we are looking for a module inside of a specific package
       
   221             return _fs_import(parent.__pkgdir__, modname, fqname)
       
   222 
       
   223         # scan sys.path, looking for the requested module
       
   224         for dir in self.path:
       
   225             if isinstance(dir, _StringType):
       
   226                 result = _fs_import(dir, modname, fqname)
       
   227                 if result:
       
   228                     return result
       
   229 
       
   230         # not found
       
   231         return None
       
   232 
       
   233 ######################################################################
       
   234 
       
   235 def _test_dir():
       
   236     "Debug/test function to create DirectoryImporters from sys.path."
       
   237     imputil.ImportManager().install()
       
   238     path = sys.path[:]
       
   239     path.reverse()
       
   240     for d in path:
       
   241         sys.path.insert(0, DirectoryImporter(d))
       
   242     sys.path.insert(0, imputil.BuiltinImporter())
       
   243 
       
   244 def _test_revamp():
       
   245     "Debug/test function for the revamped import system."
       
   246     imputil.ImportManager().install()
       
   247     sys.path.insert(0, PathImporter())
       
   248     sys.path.insert(0, imputil.BuiltinImporter())