| Fred Drake | 05857df | 2001-09-04 18:39:45 +0000 | [diff] [blame] | 1 | """ | 
 | 2 | Import utilities | 
| Greg Stein | 99a5621 | 2000-06-26 17:31:49 +0000 | [diff] [blame] | 3 |  | 
| Fred Drake | 05857df | 2001-09-04 18:39:45 +0000 | [diff] [blame] | 4 | Exported classes: | 
 | 5 |     ImportManager   Manage the import process | 
 | 6 |  | 
 | 7 |     Importer        Base class for replacing standard import functions | 
 | 8 |     BuiltinImporter Emulate the import mechanism for builtin and frozen modules | 
 | 9 |  | 
 | 10 |     DynLoadSuffixImporter | 
 | 11 | """ | 
| Greg Stein | 281b8d8 | 1999-11-07 12:54:45 +0000 | [diff] [blame] | 12 |  | 
| Greg Stein | 281b8d8 | 1999-11-07 12:54:45 +0000 | [diff] [blame] | 13 | # note: avoid importing non-builtin modules | 
| Tim Peters | 07e99cb | 2001-01-14 23:47:14 +0000 | [diff] [blame] | 14 | import imp                      ### not available in JPython? | 
| Greg Stein | 281b8d8 | 1999-11-07 12:54:45 +0000 | [diff] [blame] | 15 | import sys | 
| Greg Stein | 7ec28d2 | 1999-11-20 12:31:07 +0000 | [diff] [blame] | 16 | import __builtin__ | 
| Greg Stein | 281b8d8 | 1999-11-07 12:54:45 +0000 | [diff] [blame] | 17 |  | 
 | 18 | # for the DirectoryImporter | 
 | 19 | import struct | 
 | 20 | import marshal | 
 | 21 |  | 
| Skip Montanaro | 17ab123 | 2001-01-24 06:27:27 +0000 | [diff] [blame] | 22 | __all__ = ["ImportManager","Importer","BuiltinImporter"] | 
 | 23 |  | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 24 | _StringType = type('') | 
| Tim Peters | 07e99cb | 2001-01-14 23:47:14 +0000 | [diff] [blame] | 25 | _ModuleType = type(sys)         ### doesn't work in JPython... | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 26 |  | 
 | 27 | class ImportManager: | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 28 |     "Manage the import process." | 
| Greg Stein | 281b8d8 | 1999-11-07 12:54:45 +0000 | [diff] [blame] | 29 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 30 |     def install(self, namespace=vars(__builtin__)): | 
 | 31 |         "Install this ImportManager into the specified namespace." | 
| Greg Stein | d4f1d20 | 2000-02-18 12:03:40 +0000 | [diff] [blame] | 32 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 33 |         if isinstance(namespace, _ModuleType): | 
 | 34 |             namespace = vars(namespace) | 
| Greg Stein | d4f1d20 | 2000-02-18 12:03:40 +0000 | [diff] [blame] | 35 |  | 
| Greg Stein | 76977bb | 2001-04-07 16:05:24 +0000 | [diff] [blame] | 36 |         # Note: we have no notion of "chaining" | 
| Greg Stein | 3bb578c | 2000-02-18 13:04:10 +0000 | [diff] [blame] | 37 |  | 
| Greg Stein | 76977bb | 2001-04-07 16:05:24 +0000 | [diff] [blame] | 38 |         # Record the previous import hook, then install our own. | 
 | 39 |         self.previous_importer = namespace['__import__'] | 
 | 40 |         self.namespace = namespace | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 41 |         namespace['__import__'] = self._import_hook | 
| Greg Stein | 76977bb | 2001-04-07 16:05:24 +0000 | [diff] [blame] | 42 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 43 |         ### fix this | 
 | 44 |         #namespace['reload'] = self._reload_hook | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 45 |  | 
| Greg Stein | 76977bb | 2001-04-07 16:05:24 +0000 | [diff] [blame] | 46 |     def uninstall(self): | 
 | 47 |         "Restore the previous import mechanism." | 
 | 48 |         self.namespace['__import__'] = self.previous_importer | 
 | 49 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 50 |     def add_suffix(self, suffix, importFunc): | 
 | 51 |         assert callable(importFunc) | 
 | 52 |         self.fs_imp.add_suffix(suffix, importFunc) | 
| Greg Stein | 281b8d8 | 1999-11-07 12:54:45 +0000 | [diff] [blame] | 53 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 54 |     ###################################################################### | 
 | 55 |     # | 
 | 56 |     # PRIVATE METHODS | 
 | 57 |     # | 
| Greg Stein | 3bb578c | 2000-02-18 13:04:10 +0000 | [diff] [blame] | 58 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 59 |     clsFilesystemImporter = None | 
| Greg Stein | 281b8d8 | 1999-11-07 12:54:45 +0000 | [diff] [blame] | 60 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 61 |     def __init__(self, fs_imp=None): | 
 | 62 |         # we're definitely going to be importing something in the future, | 
 | 63 |         # so let's just load the OS-related facilities. | 
 | 64 |         if not _os_stat: | 
 | 65 |             _os_bootstrap() | 
| Greg Stein | 3bb578c | 2000-02-18 13:04:10 +0000 | [diff] [blame] | 66 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 67 |         # This is the Importer that we use for grabbing stuff from the | 
 | 68 |         # filesystem. It defines one more method (import_from_dir) for our use. | 
| Raymond Hettinger | 936654b | 2002-06-01 03:06:31 +0000 | [diff] [blame] | 69 |         if fs_imp is None: | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 70 |             cls = self.clsFilesystemImporter or _FilesystemImporter | 
 | 71 |             fs_imp = cls() | 
 | 72 |         self.fs_imp = fs_imp | 
| Greg Stein | 281b8d8 | 1999-11-07 12:54:45 +0000 | [diff] [blame] | 73 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 74 |         # Initialize the set of suffixes that we recognize and import. | 
 | 75 |         # The default will import dynamic-load modules first, followed by | 
 | 76 |         # .py files (or a .py file's cached bytecode) | 
 | 77 |         for desc in imp.get_suffixes(): | 
 | 78 |             if desc[2] == imp.C_EXTENSION: | 
 | 79 |                 self.add_suffix(desc[0], | 
 | 80 |                                 DynLoadSuffixImporter(desc).import_file) | 
 | 81 |         self.add_suffix('.py', py_suffix_importer) | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 82 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 83 |     def _import_hook(self, fqname, globals=None, locals=None, fromlist=None): | 
 | 84 |         """Python calls this hook to locate and import a module.""" | 
| Greg Stein | 63faa01 | 1999-11-20 11:22:37 +0000 | [diff] [blame] | 85 |  | 
| Martin v. Löwis | d3011cd | 2001-07-28 17:59:34 +0000 | [diff] [blame] | 86 |         parts = fqname.split('.') | 
| Greg Stein | 281b8d8 | 1999-11-07 12:54:45 +0000 | [diff] [blame] | 87 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 88 |         # determine the context of this import | 
 | 89 |         parent = self._determine_import_context(globals) | 
| Greg Stein | 281b8d8 | 1999-11-07 12:54:45 +0000 | [diff] [blame] | 90 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 91 |         # if there is a parent, then its importer should manage this import | 
 | 92 |         if parent: | 
 | 93 |             module = parent.__importer__._do_import(parent, parts, fromlist) | 
 | 94 |             if module: | 
 | 95 |                 return module | 
| Greg Stein | 281b8d8 | 1999-11-07 12:54:45 +0000 | [diff] [blame] | 96 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 97 |         # has the top module already been imported? | 
 | 98 |         try: | 
 | 99 |             top_module = sys.modules[parts[0]] | 
 | 100 |         except KeyError: | 
 | 101 |  | 
 | 102 |             # look for the topmost module | 
 | 103 |             top_module = self._import_top_module(parts[0]) | 
 | 104 |             if not top_module: | 
 | 105 |                 # the topmost module wasn't found at all. | 
 | 106 |                 raise ImportError, 'No module named ' + fqname | 
 | 107 |  | 
 | 108 |         # fast-path simple imports | 
 | 109 |         if len(parts) == 1: | 
 | 110 |             if not fromlist: | 
 | 111 |                 return top_module | 
 | 112 |  | 
 | 113 |             if not top_module.__dict__.get('__ispkg__'): | 
 | 114 |                 # __ispkg__ isn't defined (the module was not imported by us), | 
 | 115 |                 # or it is zero. | 
 | 116 |                 # | 
 | 117 |                 # In the former case, there is no way that we could import | 
 | 118 |                 # sub-modules that occur in the fromlist (but we can't raise an | 
 | 119 |                 # error because it may just be names) because we don't know how | 
 | 120 |                 # to deal with packages that were imported by other systems. | 
 | 121 |                 # | 
 | 122 |                 # In the latter case (__ispkg__ == 0), there can't be any sub- | 
 | 123 |                 # modules present, so we can just return. | 
 | 124 |                 # | 
 | 125 |                 # In both cases, since len(parts) == 1, the top_module is also | 
 | 126 |                 # the "bottom" which is the defined return when a fromlist | 
 | 127 |                 # exists. | 
 | 128 |                 return top_module | 
 | 129 |  | 
 | 130 |         importer = top_module.__dict__.get('__importer__') | 
 | 131 |         if importer: | 
 | 132 |             return importer._finish_import(top_module, parts[1:], fromlist) | 
 | 133 |  | 
| Martin v. Löwis | 70195da | 2001-07-28 20:33:41 +0000 | [diff] [blame] | 134 |         # Grrr, some people "import os.path" | 
 | 135 |         if len(parts) == 2 and hasattr(top_module, parts[1]): | 
 | 136 |             return top_module | 
 | 137 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 138 |         # If the importer does not exist, then we have to bail. A missing | 
 | 139 |         # importer means that something else imported the module, and we have | 
 | 140 |         # no knowledge of how to get sub-modules out of the thing. | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 141 |         raise ImportError, 'No module named ' + fqname | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 142 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 143 |     def _determine_import_context(self, globals): | 
 | 144 |         """Returns the context in which a module should be imported. | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 145 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 146 |         The context could be a loaded (package) module and the imported module | 
 | 147 |         will be looked for within that package. The context could also be None, | 
 | 148 |         meaning there is no context -- the module should be looked for as a | 
 | 149 |         "top-level" module. | 
 | 150 |         """ | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 151 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 152 |         if not globals or not globals.get('__importer__'): | 
 | 153 |             # globals does not refer to one of our modules or packages. That | 
 | 154 |             # implies there is no relative import context (as far as we are | 
 | 155 |             # concerned), and it should just pick it off the standard path. | 
 | 156 |             return None | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 157 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 158 |         # The globals refer to a module or package of ours. It will define | 
 | 159 |         # the context of the new import. Get the module/package fqname. | 
 | 160 |         parent_fqname = globals['__name__'] | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 161 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 162 |         # if a package is performing the import, then return itself (imports | 
 | 163 |         # refer to pkg contents) | 
 | 164 |         if globals['__ispkg__']: | 
 | 165 |             parent = sys.modules[parent_fqname] | 
 | 166 |             assert globals is parent.__dict__ | 
 | 167 |             return parent | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 168 |  | 
| Martin v. Löwis | d3011cd | 2001-07-28 17:59:34 +0000 | [diff] [blame] | 169 |         i = parent_fqname.rfind('.') | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 170 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 171 |         # a module outside of a package has no particular import context | 
 | 172 |         if i == -1: | 
 | 173 |             return None | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 174 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 175 |         # if a module in a package is performing the import, then return the | 
 | 176 |         # package (imports refer to siblings) | 
 | 177 |         parent_fqname = parent_fqname[:i] | 
 | 178 |         parent = sys.modules[parent_fqname] | 
 | 179 |         assert parent.__name__ == parent_fqname | 
 | 180 |         return parent | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 181 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 182 |     def _import_top_module(self, name): | 
 | 183 |         # scan sys.path looking for a location in the filesystem that contains | 
 | 184 |         # the module, or an Importer object that can import the module. | 
 | 185 |         for item in sys.path: | 
 | 186 |             if isinstance(item, _StringType): | 
 | 187 |                 module = self.fs_imp.import_from_dir(item, name) | 
 | 188 |             else: | 
 | 189 |                 module = item.import_top(name) | 
 | 190 |             if module: | 
 | 191 |                 return module | 
 | 192 |         return None | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 193 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 194 |     def _reload_hook(self, module): | 
 | 195 |         "Python calls this hook to reload a module." | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 196 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 197 |         # reloading of a module may or may not be possible (depending on the | 
 | 198 |         # importer), but at least we can validate that it's ours to reload | 
 | 199 |         importer = module.__dict__.get('__importer__') | 
 | 200 |         if not importer: | 
 | 201 |             ### oops. now what... | 
 | 202 |             pass | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 203 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 204 |         # okay. it is using the imputil system, and we must delegate it, but | 
 | 205 |         # we don't know what to do (yet) | 
 | 206 |         ### we should blast the module dict and do another get_code(). need to | 
 | 207 |         ### flesh this out and add proper docco... | 
 | 208 |         raise SystemError, "reload not yet implemented" | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 209 |  | 
 | 210 |  | 
 | 211 | class Importer: | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 212 |     "Base class for replacing standard import functions." | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 213 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 214 |     def import_top(self, name): | 
 | 215 |         "Import a top-level module." | 
 | 216 |         return self._import_one(None, name, name) | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 217 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 218 |     ###################################################################### | 
| Greg Stein | 281b8d8 | 1999-11-07 12:54:45 +0000 | [diff] [blame] | 219 |     # | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 220 |     # PRIVATE METHODS | 
| Greg Stein | 281b8d8 | 1999-11-07 12:54:45 +0000 | [diff] [blame] | 221 |     # | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 222 |     def _finish_import(self, top, parts, fromlist): | 
 | 223 |         # if "a.b.c" was provided, then load the ".b.c" portion down from | 
 | 224 |         # below the top-level module. | 
 | 225 |         bottom = self._load_tail(top, parts) | 
| Greg Stein | 281b8d8 | 1999-11-07 12:54:45 +0000 | [diff] [blame] | 226 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 227 |         # if the form is "import a.b.c", then return "a" | 
 | 228 |         if not fromlist: | 
 | 229 |             # no fromlist: return the top of the import tree | 
 | 230 |             return top | 
 | 231 |  | 
 | 232 |         # the top module was imported by self. | 
 | 233 |         # | 
 | 234 |         # this means that the bottom module was also imported by self (just | 
 | 235 |         # now, or in the past and we fetched it from sys.modules). | 
 | 236 |         # | 
 | 237 |         # since we imported/handled the bottom module, this means that we can | 
 | 238 |         # also handle its fromlist (and reliably use __ispkg__). | 
 | 239 |  | 
 | 240 |         # if the bottom node is a package, then (potentially) import some | 
 | 241 |         # modules. | 
 | 242 |         # | 
 | 243 |         # note: if it is not a package, then "fromlist" refers to names in | 
 | 244 |         #       the bottom module rather than modules. | 
 | 245 |         # note: for a mix of names and modules in the fromlist, we will | 
 | 246 |         #       import all modules and insert those into the namespace of | 
 | 247 |         #       the package module. Python will pick up all fromlist names | 
 | 248 |         #       from the bottom (package) module; some will be modules that | 
 | 249 |         #       we imported and stored in the namespace, others are expected | 
 | 250 |         #       to be present already. | 
 | 251 |         if bottom.__ispkg__: | 
 | 252 |             self._import_fromlist(bottom, fromlist) | 
 | 253 |  | 
 | 254 |         # if the form is "from a.b import c, d" then return "b" | 
 | 255 |         return bottom | 
 | 256 |  | 
 | 257 |     def _import_one(self, parent, modname, fqname): | 
 | 258 |         "Import a single module." | 
 | 259 |  | 
 | 260 |         # has the module already been imported? | 
 | 261 |         try: | 
 | 262 |             return sys.modules[fqname] | 
 | 263 |         except KeyError: | 
 | 264 |             pass | 
 | 265 |  | 
 | 266 |         # load the module's code, or fetch the module itself | 
 | 267 |         result = self.get_code(parent, modname, fqname) | 
 | 268 |         if result is None: | 
 | 269 |             return None | 
 | 270 |  | 
 | 271 |         module = self._process_result(result, fqname) | 
 | 272 |  | 
 | 273 |         # insert the module into its parent | 
 | 274 |         if parent: | 
 | 275 |             setattr(parent, modname, module) | 
 | 276 |         return module | 
 | 277 |  | 
 | 278 |     def _process_result(self, (ispkg, code, values), fqname): | 
 | 279 |         # did get_code() return an actual module? (rather than a code object) | 
 | 280 |         is_module = isinstance(code, _ModuleType) | 
 | 281 |  | 
 | 282 |         # use the returned module, or create a new one to exec code into | 
 | 283 |         if is_module: | 
 | 284 |             module = code | 
 | 285 |         else: | 
 | 286 |             module = imp.new_module(fqname) | 
 | 287 |  | 
 | 288 |         ### record packages a bit differently?? | 
 | 289 |         module.__importer__ = self | 
 | 290 |         module.__ispkg__ = ispkg | 
 | 291 |  | 
 | 292 |         # insert additional values into the module (before executing the code) | 
 | 293 |         module.__dict__.update(values) | 
 | 294 |  | 
 | 295 |         # the module is almost ready... make it visible | 
 | 296 |         sys.modules[fqname] = module | 
 | 297 |  | 
 | 298 |         # execute the code within the module's namespace | 
 | 299 |         if not is_module: | 
 | 300 |             exec code in module.__dict__ | 
 | 301 |  | 
| Thomas Heller | bfae196 | 2001-02-12 09:17:06 +0000 | [diff] [blame] | 302 |         # fetch from sys.modules instead of returning module directly. | 
| Martin v. Löwis | 70195da | 2001-07-28 20:33:41 +0000 | [diff] [blame] | 303 |         # also make module's __name__ agree with fqname, in case | 
 | 304 |         # the "exec code in module.__dict__" played games on us. | 
 | 305 |         module = sys.modules[fqname] | 
 | 306 |         module.__name__ = fqname | 
 | 307 |         return module | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 308 |  | 
 | 309 |     def _load_tail(self, m, parts): | 
 | 310 |         """Import the rest of the modules, down from the top-level module. | 
 | 311 |  | 
 | 312 |         Returns the last module in the dotted list of modules. | 
 | 313 |         """ | 
 | 314 |         for part in parts: | 
 | 315 |             fqname = "%s.%s" % (m.__name__, part) | 
 | 316 |             m = self._import_one(m, part, fqname) | 
 | 317 |             if not m: | 
 | 318 |                 raise ImportError, "No module named " + fqname | 
 | 319 |         return m | 
 | 320 |  | 
 | 321 |     def _import_fromlist(self, package, fromlist): | 
 | 322 |         'Import any sub-modules in the "from" list.' | 
 | 323 |  | 
 | 324 |         # if '*' is present in the fromlist, then look for the '__all__' | 
 | 325 |         # variable to find additional items (modules) to import. | 
 | 326 |         if '*' in fromlist: | 
 | 327 |             fromlist = list(fromlist) + \ | 
 | 328 |                        list(package.__dict__.get('__all__', [])) | 
 | 329 |  | 
 | 330 |         for sub in fromlist: | 
 | 331 |             # if the name is already present, then don't try to import it (it | 
 | 332 |             # might not be a module!). | 
 | 333 |             if sub != '*' and not hasattr(package, sub): | 
 | 334 |                 subname = "%s.%s" % (package.__name__, sub) | 
 | 335 |                 submod = self._import_one(package, sub, subname) | 
 | 336 |                 if not submod: | 
 | 337 |                     raise ImportError, "cannot import name " + subname | 
 | 338 |  | 
 | 339 |     def _do_import(self, parent, parts, fromlist): | 
 | 340 |         """Attempt to import the module relative to parent. | 
 | 341 |  | 
 | 342 |         This method is used when the import context specifies that <self> | 
 | 343 |         imported the parent module. | 
 | 344 |         """ | 
 | 345 |         top_name = parts[0] | 
 | 346 |         top_fqname = parent.__name__ + '.' + top_name | 
 | 347 |         top_module = self._import_one(parent, top_name, top_fqname) | 
 | 348 |         if not top_module: | 
 | 349 |             # this importer and parent could not find the module (relatively) | 
 | 350 |             return None | 
 | 351 |  | 
 | 352 |         return self._finish_import(top_module, parts[1:], fromlist) | 
 | 353 |  | 
 | 354 |     ###################################################################### | 
| Greg Stein | 281b8d8 | 1999-11-07 12:54:45 +0000 | [diff] [blame] | 355 |     # | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 356 |     # METHODS TO OVERRIDE | 
 | 357 |     # | 
 | 358 |     def get_code(self, parent, modname, fqname): | 
 | 359 |         """Find and retrieve the code for the given module. | 
| Greg Stein | 281b8d8 | 1999-11-07 12:54:45 +0000 | [diff] [blame] | 360 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 361 |         parent specifies a parent module to define a context for importing. It | 
 | 362 |         may be None, indicating no particular context for the search. | 
| Greg Stein | 281b8d8 | 1999-11-07 12:54:45 +0000 | [diff] [blame] | 363 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 364 |         modname specifies a single module (not dotted) within the parent. | 
| Greg Stein | 281b8d8 | 1999-11-07 12:54:45 +0000 | [diff] [blame] | 365 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 366 |         fqname specifies the fully-qualified module name. This is a | 
 | 367 |         (potentially) dotted name from the "root" of the module namespace | 
 | 368 |         down to the modname. | 
 | 369 |         If there is no parent, then modname==fqname. | 
| Greg Stein | 281b8d8 | 1999-11-07 12:54:45 +0000 | [diff] [blame] | 370 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 371 |         This method should return None, or a 3-tuple. | 
| Greg Stein | 281b8d8 | 1999-11-07 12:54:45 +0000 | [diff] [blame] | 372 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 373 |         * If the module was not found, then None should be returned. | 
| Greg Stein | 281b8d8 | 1999-11-07 12:54:45 +0000 | [diff] [blame] | 374 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 375 |         * The first item of the 2- or 3-tuple should be the integer 0 or 1, | 
 | 376 |             specifying whether the module that was found is a package or not. | 
| Greg Stein | 281b8d8 | 1999-11-07 12:54:45 +0000 | [diff] [blame] | 377 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 378 |         * The second item is the code object for the module (it will be | 
 | 379 |             executed within the new module's namespace). This item can also | 
 | 380 |             be a fully-loaded module object (e.g. loaded from a shared lib). | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 381 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 382 |         * The third item is a dictionary of name/value pairs that will be | 
 | 383 |             inserted into new module before the code object is executed. This | 
 | 384 |             is provided in case the module's code expects certain values (such | 
 | 385 |             as where the module was found). When the second item is a module | 
 | 386 |             object, then these names/values will be inserted *after* the module | 
 | 387 |             has been loaded/initialized. | 
 | 388 |         """ | 
 | 389 |         raise RuntimeError, "get_code not implemented" | 
| Greg Stein | 281b8d8 | 1999-11-07 12:54:45 +0000 | [diff] [blame] | 390 |  | 
 | 391 |  | 
 | 392 | ###################################################################### | 
 | 393 | # | 
| Greg Stein | 63faa01 | 1999-11-20 11:22:37 +0000 | [diff] [blame] | 394 | # Some handy stuff for the Importers | 
 | 395 | # | 
 | 396 |  | 
| Greg Stein | d4f1d20 | 2000-02-18 12:03:40 +0000 | [diff] [blame] | 397 | # byte-compiled file suffix character | 
| Greg Stein | 63faa01 | 1999-11-20 11:22:37 +0000 | [diff] [blame] | 398 | _suffix_char = __debug__ and 'c' or 'o' | 
 | 399 |  | 
 | 400 | # byte-compiled file suffix | 
 | 401 | _suffix = '.py' + _suffix_char | 
 | 402 |  | 
| Greg Stein | 63faa01 | 1999-11-20 11:22:37 +0000 | [diff] [blame] | 403 | def _compile(pathname, timestamp): | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 404 |     """Compile (and cache) a Python source file. | 
| Greg Stein | 63faa01 | 1999-11-20 11:22:37 +0000 | [diff] [blame] | 405 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 406 |     The file specified by <pathname> is compiled to a code object and | 
 | 407 |     returned. | 
| Greg Stein | 63faa01 | 1999-11-20 11:22:37 +0000 | [diff] [blame] | 408 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 409 |     Presuming the appropriate privileges exist, the bytecodes will be | 
 | 410 |     saved back to the filesystem for future imports. The source file's | 
 | 411 |     modification timestamp must be provided as a Long value. | 
 | 412 |     """ | 
| Jeremy Hylton | 13f99d7 | 2002-06-28 23:32:51 +0000 | [diff] [blame] | 413 |     codestring = open(pathname, 'rU').read() | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 414 |     if codestring and codestring[-1] != '\n': | 
 | 415 |         codestring = codestring + '\n' | 
 | 416 |     code = __builtin__.compile(codestring, pathname, 'exec') | 
| Greg Stein | 63faa01 | 1999-11-20 11:22:37 +0000 | [diff] [blame] | 417 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 418 |     # try to cache the compiled code | 
 | 419 |     try: | 
 | 420 |         f = open(pathname + _suffix_char, 'wb') | 
 | 421 |     except IOError: | 
 | 422 |         pass | 
 | 423 |     else: | 
 | 424 |         f.write('\0\0\0\0') | 
 | 425 |         f.write(struct.pack('<I', timestamp)) | 
 | 426 |         marshal.dump(code, f) | 
 | 427 |         f.flush() | 
 | 428 |         f.seek(0, 0) | 
 | 429 |         f.write(imp.get_magic()) | 
 | 430 |         f.close() | 
| Greg Stein | 63faa01 | 1999-11-20 11:22:37 +0000 | [diff] [blame] | 431 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 432 |     return code | 
| Greg Stein | 63faa01 | 1999-11-20 11:22:37 +0000 | [diff] [blame] | 433 |  | 
 | 434 | _os_stat = _os_path_join = None | 
 | 435 | def _os_bootstrap(): | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 436 |     "Set up 'os' module replacement functions for use during import bootstrap." | 
| Greg Stein | 63faa01 | 1999-11-20 11:22:37 +0000 | [diff] [blame] | 437 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 438 |     names = sys.builtin_module_names | 
| Greg Stein | 63faa01 | 1999-11-20 11:22:37 +0000 | [diff] [blame] | 439 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 440 |     join = None | 
 | 441 |     if 'posix' in names: | 
 | 442 |         sep = '/' | 
 | 443 |         from posix import stat | 
 | 444 |     elif 'nt' in names: | 
 | 445 |         sep = '\\' | 
 | 446 |         from nt import stat | 
 | 447 |     elif 'dos' in names: | 
 | 448 |         sep = '\\' | 
 | 449 |         from dos import stat | 
 | 450 |     elif 'os2' in names: | 
 | 451 |         sep = '\\' | 
 | 452 |         from os2 import stat | 
 | 453 |     elif 'mac' in names: | 
 | 454 |         from mac import stat | 
 | 455 |         def join(a, b): | 
 | 456 |             if a == '': | 
 | 457 |                 return b | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 458 |             if ':' not in a: | 
 | 459 |                 a = ':' + a | 
| Fred Drake | 8152d32 | 2000-12-12 23:20:45 +0000 | [diff] [blame] | 460 |             if a[-1:] != ':': | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 461 |                 a = a + ':' | 
 | 462 |             return a + b | 
 | 463 |     else: | 
 | 464 |         raise ImportError, 'no os specific module found' | 
| Greg Stein | 63faa01 | 1999-11-20 11:22:37 +0000 | [diff] [blame] | 465 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 466 |     if join is None: | 
 | 467 |         def join(a, b, sep=sep): | 
 | 468 |             if a == '': | 
 | 469 |                 return b | 
 | 470 |             lastchar = a[-1:] | 
 | 471 |             if lastchar == '/' or lastchar == sep: | 
 | 472 |                 return a + b | 
 | 473 |             return a + sep + b | 
| Greg Stein | 63faa01 | 1999-11-20 11:22:37 +0000 | [diff] [blame] | 474 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 475 |     global _os_stat | 
 | 476 |     _os_stat = stat | 
 | 477 |  | 
 | 478 |     global _os_path_join | 
 | 479 |     _os_path_join = join | 
| Greg Stein | 63faa01 | 1999-11-20 11:22:37 +0000 | [diff] [blame] | 480 |  | 
 | 481 | def _os_path_isdir(pathname): | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 482 |     "Local replacement for os.path.isdir()." | 
 | 483 |     try: | 
 | 484 |         s = _os_stat(pathname) | 
 | 485 |     except OSError: | 
 | 486 |         return None | 
| Raymond Hettinger | 32200ae | 2002-06-01 19:51:15 +0000 | [diff] [blame] | 487 |     return (s.st_mode & 0170000) == 0040000 | 
| Greg Stein | 63faa01 | 1999-11-20 11:22:37 +0000 | [diff] [blame] | 488 |  | 
 | 489 | def _timestamp(pathname): | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 490 |     "Return the file modification time as a Long." | 
 | 491 |     try: | 
 | 492 |         s = _os_stat(pathname) | 
 | 493 |     except OSError: | 
 | 494 |         return None | 
| Raymond Hettinger | 32200ae | 2002-06-01 19:51:15 +0000 | [diff] [blame] | 495 |     return long(s.st_mtime) | 
| Greg Stein | 63faa01 | 1999-11-20 11:22:37 +0000 | [diff] [blame] | 496 |  | 
| Greg Stein | 63faa01 | 1999-11-20 11:22:37 +0000 | [diff] [blame] | 497 |  | 
 | 498 | ###################################################################### | 
 | 499 | # | 
 | 500 | # Emulate the import mechanism for builtin and frozen modules | 
 | 501 | # | 
 | 502 | class BuiltinImporter(Importer): | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 503 |     def get_code(self, parent, modname, fqname): | 
 | 504 |         if parent: | 
 | 505 |             # these modules definitely do not occur within a package context | 
 | 506 |             return None | 
| Greg Stein | 63faa01 | 1999-11-20 11:22:37 +0000 | [diff] [blame] | 507 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 508 |         # look for the module | 
 | 509 |         if imp.is_builtin(modname): | 
 | 510 |             type = imp.C_BUILTIN | 
 | 511 |         elif imp.is_frozen(modname): | 
 | 512 |             type = imp.PY_FROZEN | 
 | 513 |         else: | 
 | 514 |             # not found | 
 | 515 |             return None | 
| Greg Stein | 63faa01 | 1999-11-20 11:22:37 +0000 | [diff] [blame] | 516 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 517 |         # got it. now load and return it. | 
 | 518 |         module = imp.load_module(modname, None, modname, ('', '', type)) | 
 | 519 |         return 0, module, { } | 
| Greg Stein | 63faa01 | 1999-11-20 11:22:37 +0000 | [diff] [blame] | 520 |  | 
 | 521 |  | 
 | 522 | ###################################################################### | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 523 | # | 
 | 524 | # Internal importer used for importing from the filesystem | 
 | 525 | # | 
 | 526 | class _FilesystemImporter(Importer): | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 527 |     def __init__(self): | 
 | 528 |         self.suffixes = [ ] | 
| Greg Stein | 3bb578c | 2000-02-18 13:04:10 +0000 | [diff] [blame] | 529 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 530 |     def add_suffix(self, suffix, importFunc): | 
 | 531 |         assert callable(importFunc) | 
 | 532 |         self.suffixes.append((suffix, importFunc)) | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 533 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 534 |     def import_from_dir(self, dir, fqname): | 
 | 535 |         result = self._import_pathname(_os_path_join(dir, fqname), fqname) | 
 | 536 |         if result: | 
 | 537 |             return self._process_result(result, fqname) | 
 | 538 |         return None | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 539 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 540 |     def get_code(self, parent, modname, fqname): | 
 | 541 |         # This importer is never used with an empty parent. Its existence is | 
 | 542 |         # private to the ImportManager. The ImportManager uses the | 
 | 543 |         # import_from_dir() method to import top-level modules/packages. | 
 | 544 |         # This method is only used when we look for a module within a package. | 
 | 545 |         assert parent | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 546 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 547 |         return self._import_pathname(_os_path_join(parent.__pkgdir__, modname), | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 548 |                                      fqname) | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 549 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 550 |     def _import_pathname(self, pathname, fqname): | 
 | 551 |         if _os_path_isdir(pathname): | 
 | 552 |             result = self._import_pathname(_os_path_join(pathname, '__init__'), | 
 | 553 |                                            fqname) | 
 | 554 |             if result: | 
 | 555 |                 values = result[2] | 
 | 556 |                 values['__pkgdir__'] = pathname | 
 | 557 |                 values['__path__'] = [ pathname ] | 
 | 558 |                 return 1, result[1], values | 
 | 559 |             return None | 
 | 560 |  | 
 | 561 |         for suffix, importFunc in self.suffixes: | 
 | 562 |             filename = pathname + suffix | 
 | 563 |             try: | 
 | 564 |                 finfo = _os_stat(filename) | 
 | 565 |             except OSError: | 
 | 566 |                 pass | 
 | 567 |             else: | 
 | 568 |                 return importFunc(filename, finfo, fqname) | 
 | 569 |         return None | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 570 |  | 
 | 571 | ###################################################################### | 
 | 572 | # | 
 | 573 | # SUFFIX-BASED IMPORTERS | 
 | 574 | # | 
 | 575 |  | 
| Greg Stein | 3bb578c | 2000-02-18 13:04:10 +0000 | [diff] [blame] | 576 | def py_suffix_importer(filename, finfo, fqname): | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 577 |     file = filename[:-3] + _suffix | 
 | 578 |     t_py = long(finfo[8]) | 
 | 579 |     t_pyc = _timestamp(file) | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 580 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 581 |     code = None | 
 | 582 |     if t_pyc is not None and t_pyc >= t_py: | 
 | 583 |         f = open(file, 'rb') | 
 | 584 |         if f.read(4) == imp.get_magic(): | 
 | 585 |             t = struct.unpack('<I', f.read(4))[0] | 
 | 586 |             if t == t_py: | 
 | 587 |                 code = marshal.load(f) | 
 | 588 |         f.close() | 
 | 589 |     if code is None: | 
 | 590 |         file = filename | 
 | 591 |         code = _compile(file, t_py) | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 592 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 593 |     return 0, code, { '__file__' : file } | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 594 |  | 
| Greg Stein | 3bb578c | 2000-02-18 13:04:10 +0000 | [diff] [blame] | 595 | class DynLoadSuffixImporter: | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 596 |     def __init__(self, desc): | 
 | 597 |         self.desc = desc | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 598 |  | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 599 |     def import_file(self, filename, finfo, fqname): | 
 | 600 |         fp = open(filename, self.desc[1]) | 
 | 601 |         module = imp.load_module(fqname, fp, filename, self.desc) | 
 | 602 |         module.__file__ = filename | 
 | 603 |         return 0, module, { } | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 604 |  | 
 | 605 |  | 
 | 606 | ###################################################################### | 
| Greg Stein | 63faa01 | 1999-11-20 11:22:37 +0000 | [diff] [blame] | 607 |  | 
| Greg Stein | 63faa01 | 1999-11-20 11:22:37 +0000 | [diff] [blame] | 608 | def _print_importers(): | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 609 |     items = sys.modules.items() | 
 | 610 |     items.sort() | 
 | 611 |     for name, module in items: | 
 | 612 |         if module: | 
 | 613 |             print name, module.__dict__.get('__importer__', '-- no importer') | 
 | 614 |         else: | 
 | 615 |             print name, '-- non-existent module' | 
| Greg Stein | 63faa01 | 1999-11-20 11:22:37 +0000 | [diff] [blame] | 616 |  | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 617 | def _test_revamp(): | 
| Greg Stein | dd6eefb | 2000-07-18 09:09:48 +0000 | [diff] [blame] | 618 |     ImportManager().install() | 
 | 619 |     sys.path.insert(0, BuiltinImporter()) | 
| Greg Stein | f23aa1e | 2000-01-03 02:38:29 +0000 | [diff] [blame] | 620 |  | 
| Greg Stein | 281b8d8 | 1999-11-07 12:54:45 +0000 | [diff] [blame] | 621 | ###################################################################### | 
| Greg Stein | 42b9bc7 | 2000-02-19 13:36:23 +0000 | [diff] [blame] | 622 |  | 
 | 623 | # | 
 | 624 | # TODO | 
 | 625 | # | 
 | 626 | # from Finn Bock: | 
| Greg Stein | 42b9bc7 | 2000-02-19 13:36:23 +0000 | [diff] [blame] | 627 | #   type(sys) is not a module in JPython. what to use instead? | 
 | 628 | #   imp.C_EXTENSION is not in JPython. same for get_suffixes and new_module | 
 | 629 | # | 
 | 630 | #   given foo.py of: | 
 | 631 | #      import sys | 
 | 632 | #      sys.modules['foo'] = sys | 
 | 633 | # | 
 | 634 | #   ---- standard import mechanism | 
 | 635 | #   >>> import foo | 
 | 636 | #   >>> foo | 
 | 637 | #   <module 'sys' (built-in)> | 
 | 638 | # | 
 | 639 | #   ---- revamped import mechanism | 
 | 640 | #   >>> import imputil | 
 | 641 | #   >>> imputil._test_revamp() | 
 | 642 | #   >>> import foo | 
 | 643 | #   >>> foo | 
 | 644 | #   <module 'foo' from 'foo.py'> | 
 | 645 | # | 
 | 646 | # | 
 | 647 | # from MAL: | 
 | 648 | #   should BuiltinImporter exist in sys.path or hard-wired in ImportManager? | 
 | 649 | #   need __path__ processing | 
 | 650 | #   performance | 
 | 651 | #   move chaining to a subclass [gjs: it's been nuked] | 
| Greg Stein | 42b9bc7 | 2000-02-19 13:36:23 +0000 | [diff] [blame] | 652 | #   deinstall should be possible | 
 | 653 | #   query mechanism needed: is a specific Importer installed? | 
 | 654 | #   py/pyc/pyo piping hooks to filter/process these files | 
 | 655 | #   wish list: | 
 | 656 | #     distutils importer hooked to list of standard Internet repositories | 
 | 657 | #     module->file location mapper to speed FS-based imports | 
 | 658 | #     relative imports | 
 | 659 | #     keep chaining so that it can play nice with other import hooks | 
 | 660 | # | 
 | 661 | # from Gordon: | 
 | 662 | #   push MAL's mapper into sys.path[0] as a cache (hard-coded for apps) | 
 | 663 | # | 
 | 664 | # from Guido: | 
 | 665 | #   need to change sys.* references for rexec environs | 
 | 666 | #   need hook for MAL's walk-me-up import strategy, or Tim's absolute strategy | 
| Fred Drake | 8152d32 | 2000-12-12 23:20:45 +0000 | [diff] [blame] | 667 | #   watch out for sys.modules[...] is None | 
| Greg Stein | 42b9bc7 | 2000-02-19 13:36:23 +0000 | [diff] [blame] | 668 | #   flag to force absolute imports? (speeds _determine_import_context and | 
 | 669 | #       checking for a relative module) | 
 | 670 | #   insert names of archives into sys.path  (see quote below) | 
 | 671 | #   note: reload does NOT blast module dict | 
 | 672 | #   shift import mechanisms and policies around; provide for hooks, overrides | 
 | 673 | #       (see quote below) | 
 | 674 | #   add get_source stuff | 
 | 675 | #   get_topcode and get_subcode | 
 | 676 | #   CRLF handling in _compile | 
 | 677 | #   race condition in _compile | 
 | 678 | #   refactoring of os.py to deal with _os_bootstrap problem | 
 | 679 | #   any special handling to do for importing a module with a SyntaxError? | 
 | 680 | #       (e.g. clean up the traceback) | 
 | 681 | #   implement "domain" for path-type functionality using pkg namespace | 
 | 682 | #       (rather than FS-names like __path__) | 
 | 683 | #   don't use the word "private"... maybe "internal" | 
 | 684 | # | 
 | 685 | # | 
 | 686 | # Guido's comments on sys.path caching: | 
| Tim Peters | 07e99cb | 2001-01-14 23:47:14 +0000 | [diff] [blame] | 687 | # | 
| Greg Stein | 42b9bc7 | 2000-02-19 13:36:23 +0000 | [diff] [blame] | 688 | # We could cache this in a dictionary: the ImportManager can have a | 
 | 689 | # cache dict mapping pathnames to importer objects, and a separate | 
 | 690 | # method for coming up with an importer given a pathname that's not yet | 
 | 691 | # in the cache.  The method should do a stat and/or look at the | 
 | 692 | # extension to decide which importer class to use; you can register new | 
 | 693 | # importer classes by registering a suffix or a Boolean function, plus a | 
 | 694 | # class.  If you register a new importer class, the cache is zapped. | 
 | 695 | # The cache is independent from sys.path (but maintained per | 
 | 696 | # ImportManager instance) so that rearrangements of sys.path do the | 
 | 697 | # right thing.  If a path is dropped from sys.path the corresponding | 
 | 698 | # cache entry is simply no longer used. | 
 | 699 | # | 
 | 700 | # My/Guido's comments on factoring ImportManager and Importer: | 
 | 701 | # | 
 | 702 | # > However, we still have a tension occurring here: | 
| Tim Peters | 07e99cb | 2001-01-14 23:47:14 +0000 | [diff] [blame] | 703 | # > | 
| Greg Stein | 42b9bc7 | 2000-02-19 13:36:23 +0000 | [diff] [blame] | 704 | # > 1) implementing policy in ImportManager assists in single-point policy | 
 | 705 | # >    changes for app/rexec situations | 
 | 706 | # > 2) implementing policy in Importer assists in package-private policy | 
 | 707 | # >    changes for normal, operating conditions | 
| Tim Peters | 07e99cb | 2001-01-14 23:47:14 +0000 | [diff] [blame] | 708 | # > | 
| Greg Stein | 42b9bc7 | 2000-02-19 13:36:23 +0000 | [diff] [blame] | 709 | # > I'll see if I can sort out a way to do this. Maybe the Importer class will | 
 | 710 | # > implement the methods (which can be overridden to change policy) by | 
 | 711 | # > delegating to ImportManager. | 
| Tim Peters | 07e99cb | 2001-01-14 23:47:14 +0000 | [diff] [blame] | 712 | # | 
| Greg Stein | 42b9bc7 | 2000-02-19 13:36:23 +0000 | [diff] [blame] | 713 | # Maybe also think about what kind of policies an Importer would be | 
 | 714 | # likely to want to change.  I have a feeling that a lot of the code | 
 | 715 | # there is actually not so much policy but a *necessity* to get things | 
 | 716 | # working given the calling conventions for the __import__ hook: whether | 
 | 717 | # to return the head or tail of a dotted name, or when to do the "finish | 
 | 718 | # fromlist" stuff. | 
 | 719 | # |