blob: eb53e070e5eb1456f345ed4ce2f2d04d381b1120 [file] [log] [blame]
Greg Stein281b8d81999-11-07 12:54:45 +00001#
Greg Stein99a56212000-06-26 17:31:49 +00002# imputil.py: import utilities
Greg Stein281b8d81999-11-07 12:54:45 +00003#
Greg Stein99a56212000-06-26 17:31:49 +00004
5### docco needed here and in Docs/ ...
Greg Stein281b8d81999-11-07 12:54:45 +00006
Greg Stein281b8d81999-11-07 12:54:45 +00007# note: avoid importing non-builtin modules
Tim Peters07e99cb2001-01-14 23:47:14 +00008import imp ### not available in JPython?
Greg Stein281b8d81999-11-07 12:54:45 +00009import sys
Greg Stein7ec28d21999-11-20 12:31:07 +000010import __builtin__
Greg Stein281b8d81999-11-07 12:54:45 +000011
12# for the DirectoryImporter
13import struct
14import marshal
15
Skip Montanaro17ab1232001-01-24 06:27:27 +000016__all__ = ["ImportManager","Importer","BuiltinImporter"]
17
Greg Steinf23aa1e2000-01-03 02:38:29 +000018_StringType = type('')
Tim Peters07e99cb2001-01-14 23:47:14 +000019_ModuleType = type(sys) ### doesn't work in JPython...
Greg Steinf23aa1e2000-01-03 02:38:29 +000020
21class ImportManager:
Greg Steindd6eefb2000-07-18 09:09:48 +000022 "Manage the import process."
Greg Stein281b8d81999-11-07 12:54:45 +000023
Greg Steindd6eefb2000-07-18 09:09:48 +000024 def install(self, namespace=vars(__builtin__)):
25 "Install this ImportManager into the specified namespace."
Greg Steind4f1d202000-02-18 12:03:40 +000026
Greg Steindd6eefb2000-07-18 09:09:48 +000027 if isinstance(namespace, _ModuleType):
28 namespace = vars(namespace)
Greg Steind4f1d202000-02-18 12:03:40 +000029
Greg Stein76977bb2001-04-07 16:05:24 +000030 # Note: we have no notion of "chaining"
Greg Stein3bb578c2000-02-18 13:04:10 +000031
Greg Stein76977bb2001-04-07 16:05:24 +000032 # Record the previous import hook, then install our own.
33 self.previous_importer = namespace['__import__']
34 self.namespace = namespace
Greg Steindd6eefb2000-07-18 09:09:48 +000035 namespace['__import__'] = self._import_hook
Greg Stein76977bb2001-04-07 16:05:24 +000036
Greg Steindd6eefb2000-07-18 09:09:48 +000037 ### fix this
38 #namespace['reload'] = self._reload_hook
Greg Steinf23aa1e2000-01-03 02:38:29 +000039
Greg Stein76977bb2001-04-07 16:05:24 +000040 def uninstall(self):
41 "Restore the previous import mechanism."
42 self.namespace['__import__'] = self.previous_importer
43
Greg Steindd6eefb2000-07-18 09:09:48 +000044 def add_suffix(self, suffix, importFunc):
45 assert callable(importFunc)
46 self.fs_imp.add_suffix(suffix, importFunc)
Greg Stein281b8d81999-11-07 12:54:45 +000047
Greg Steindd6eefb2000-07-18 09:09:48 +000048 ######################################################################
49 #
50 # PRIVATE METHODS
51 #
Greg Stein3bb578c2000-02-18 13:04:10 +000052
Greg Steindd6eefb2000-07-18 09:09:48 +000053 clsFilesystemImporter = None
Greg Stein281b8d81999-11-07 12:54:45 +000054
Greg Steindd6eefb2000-07-18 09:09:48 +000055 def __init__(self, fs_imp=None):
56 # we're definitely going to be importing something in the future,
57 # so let's just load the OS-related facilities.
58 if not _os_stat:
59 _os_bootstrap()
Greg Stein3bb578c2000-02-18 13:04:10 +000060
Greg Steindd6eefb2000-07-18 09:09:48 +000061 # This is the Importer that we use for grabbing stuff from the
62 # filesystem. It defines one more method (import_from_dir) for our use.
63 if not fs_imp:
64 cls = self.clsFilesystemImporter or _FilesystemImporter
65 fs_imp = cls()
66 self.fs_imp = fs_imp
Greg Stein281b8d81999-11-07 12:54:45 +000067
Greg Steindd6eefb2000-07-18 09:09:48 +000068 # Initialize the set of suffixes that we recognize and import.
69 # The default will import dynamic-load modules first, followed by
70 # .py files (or a .py file's cached bytecode)
71 for desc in imp.get_suffixes():
72 if desc[2] == imp.C_EXTENSION:
73 self.add_suffix(desc[0],
74 DynLoadSuffixImporter(desc).import_file)
75 self.add_suffix('.py', py_suffix_importer)
Greg Steinf23aa1e2000-01-03 02:38:29 +000076
Greg Steindd6eefb2000-07-18 09:09:48 +000077 def _import_hook(self, fqname, globals=None, locals=None, fromlist=None):
78 """Python calls this hook to locate and import a module."""
Greg Stein63faa011999-11-20 11:22:37 +000079
Martin v. Löwisd3011cd2001-07-28 17:59:34 +000080 parts = fqname.split('.')
Greg Stein281b8d81999-11-07 12:54:45 +000081
Greg Steindd6eefb2000-07-18 09:09:48 +000082 # determine the context of this import
83 parent = self._determine_import_context(globals)
Greg Stein281b8d81999-11-07 12:54:45 +000084
Greg Steindd6eefb2000-07-18 09:09:48 +000085 # if there is a parent, then its importer should manage this import
86 if parent:
87 module = parent.__importer__._do_import(parent, parts, fromlist)
88 if module:
89 return module
Greg Stein281b8d81999-11-07 12:54:45 +000090
Greg Steindd6eefb2000-07-18 09:09:48 +000091 # has the top module already been imported?
92 try:
93 top_module = sys.modules[parts[0]]
94 except KeyError:
95
96 # look for the topmost module
97 top_module = self._import_top_module(parts[0])
98 if not top_module:
99 # the topmost module wasn't found at all.
100 raise ImportError, 'No module named ' + fqname
101
102 # fast-path simple imports
103 if len(parts) == 1:
104 if not fromlist:
105 return top_module
106
107 if not top_module.__dict__.get('__ispkg__'):
108 # __ispkg__ isn't defined (the module was not imported by us),
109 # or it is zero.
110 #
111 # In the former case, there is no way that we could import
112 # sub-modules that occur in the fromlist (but we can't raise an
113 # error because it may just be names) because we don't know how
114 # to deal with packages that were imported by other systems.
115 #
116 # In the latter case (__ispkg__ == 0), there can't be any sub-
117 # modules present, so we can just return.
118 #
119 # In both cases, since len(parts) == 1, the top_module is also
120 # the "bottom" which is the defined return when a fromlist
121 # exists.
122 return top_module
123
124 importer = top_module.__dict__.get('__importer__')
125 if importer:
126 return importer._finish_import(top_module, parts[1:], fromlist)
127
Martin v. Löwis70195da2001-07-28 20:33:41 +0000128 # Grrr, some people "import os.path"
129 if len(parts) == 2 and hasattr(top_module, parts[1]):
130 return top_module
131
Greg Steindd6eefb2000-07-18 09:09:48 +0000132 # If the importer does not exist, then we have to bail. A missing
133 # importer means that something else imported the module, and we have
134 # no knowledge of how to get sub-modules out of the thing.
Greg Steinf23aa1e2000-01-03 02:38:29 +0000135 raise ImportError, 'No module named ' + fqname
Greg Steinf23aa1e2000-01-03 02:38:29 +0000136
Greg Steindd6eefb2000-07-18 09:09:48 +0000137 def _determine_import_context(self, globals):
138 """Returns the context in which a module should be imported.
Greg Steinf23aa1e2000-01-03 02:38:29 +0000139
Greg Steindd6eefb2000-07-18 09:09:48 +0000140 The context could be a loaded (package) module and the imported module
141 will be looked for within that package. The context could also be None,
142 meaning there is no context -- the module should be looked for as a
143 "top-level" module.
144 """
Greg Steinf23aa1e2000-01-03 02:38:29 +0000145
Greg Steindd6eefb2000-07-18 09:09:48 +0000146 if not globals or not globals.get('__importer__'):
147 # globals does not refer to one of our modules or packages. That
148 # implies there is no relative import context (as far as we are
149 # concerned), and it should just pick it off the standard path.
150 return None
Greg Steinf23aa1e2000-01-03 02:38:29 +0000151
Greg Steindd6eefb2000-07-18 09:09:48 +0000152 # The globals refer to a module or package of ours. It will define
153 # the context of the new import. Get the module/package fqname.
154 parent_fqname = globals['__name__']
Greg Steinf23aa1e2000-01-03 02:38:29 +0000155
Greg Steindd6eefb2000-07-18 09:09:48 +0000156 # if a package is performing the import, then return itself (imports
157 # refer to pkg contents)
158 if globals['__ispkg__']:
159 parent = sys.modules[parent_fqname]
160 assert globals is parent.__dict__
161 return parent
Greg Steinf23aa1e2000-01-03 02:38:29 +0000162
Martin v. Löwisd3011cd2001-07-28 17:59:34 +0000163 i = parent_fqname.rfind('.')
Greg Steinf23aa1e2000-01-03 02:38:29 +0000164
Greg Steindd6eefb2000-07-18 09:09:48 +0000165 # a module outside of a package has no particular import context
166 if i == -1:
167 return None
Greg Steinf23aa1e2000-01-03 02:38:29 +0000168
Greg Steindd6eefb2000-07-18 09:09:48 +0000169 # if a module in a package is performing the import, then return the
170 # package (imports refer to siblings)
171 parent_fqname = parent_fqname[:i]
172 parent = sys.modules[parent_fqname]
173 assert parent.__name__ == parent_fqname
174 return parent
Greg Steinf23aa1e2000-01-03 02:38:29 +0000175
Greg Steindd6eefb2000-07-18 09:09:48 +0000176 def _import_top_module(self, name):
177 # scan sys.path looking for a location in the filesystem that contains
178 # the module, or an Importer object that can import the module.
179 for item in sys.path:
180 if isinstance(item, _StringType):
181 module = self.fs_imp.import_from_dir(item, name)
182 else:
183 module = item.import_top(name)
184 if module:
185 return module
186 return None
Greg Steinf23aa1e2000-01-03 02:38:29 +0000187
Greg Steindd6eefb2000-07-18 09:09:48 +0000188 def _reload_hook(self, module):
189 "Python calls this hook to reload a module."
Greg Steinf23aa1e2000-01-03 02:38:29 +0000190
Greg Steindd6eefb2000-07-18 09:09:48 +0000191 # reloading of a module may or may not be possible (depending on the
192 # importer), but at least we can validate that it's ours to reload
193 importer = module.__dict__.get('__importer__')
194 if not importer:
195 ### oops. now what...
196 pass
Greg Steinf23aa1e2000-01-03 02:38:29 +0000197
Greg Steindd6eefb2000-07-18 09:09:48 +0000198 # okay. it is using the imputil system, and we must delegate it, but
199 # we don't know what to do (yet)
200 ### we should blast the module dict and do another get_code(). need to
201 ### flesh this out and add proper docco...
202 raise SystemError, "reload not yet implemented"
Greg Steinf23aa1e2000-01-03 02:38:29 +0000203
204
205class Importer:
Greg Steindd6eefb2000-07-18 09:09:48 +0000206 "Base class for replacing standard import functions."
Greg Steinf23aa1e2000-01-03 02:38:29 +0000207
Greg Steindd6eefb2000-07-18 09:09:48 +0000208 def import_top(self, name):
209 "Import a top-level module."
210 return self._import_one(None, name, name)
Greg Steinf23aa1e2000-01-03 02:38:29 +0000211
Greg Steindd6eefb2000-07-18 09:09:48 +0000212 ######################################################################
Greg Stein281b8d81999-11-07 12:54:45 +0000213 #
Greg Steindd6eefb2000-07-18 09:09:48 +0000214 # PRIVATE METHODS
Greg Stein281b8d81999-11-07 12:54:45 +0000215 #
Greg Steindd6eefb2000-07-18 09:09:48 +0000216 def _finish_import(self, top, parts, fromlist):
217 # if "a.b.c" was provided, then load the ".b.c" portion down from
218 # below the top-level module.
219 bottom = self._load_tail(top, parts)
Greg Stein281b8d81999-11-07 12:54:45 +0000220
Greg Steindd6eefb2000-07-18 09:09:48 +0000221 # if the form is "import a.b.c", then return "a"
222 if not fromlist:
223 # no fromlist: return the top of the import tree
224 return top
225
226 # the top module was imported by self.
227 #
228 # this means that the bottom module was also imported by self (just
229 # now, or in the past and we fetched it from sys.modules).
230 #
231 # since we imported/handled the bottom module, this means that we can
232 # also handle its fromlist (and reliably use __ispkg__).
233
234 # if the bottom node is a package, then (potentially) import some
235 # modules.
236 #
237 # note: if it is not a package, then "fromlist" refers to names in
238 # the bottom module rather than modules.
239 # note: for a mix of names and modules in the fromlist, we will
240 # import all modules and insert those into the namespace of
241 # the package module. Python will pick up all fromlist names
242 # from the bottom (package) module; some will be modules that
243 # we imported and stored in the namespace, others are expected
244 # to be present already.
245 if bottom.__ispkg__:
246 self._import_fromlist(bottom, fromlist)
247
248 # if the form is "from a.b import c, d" then return "b"
249 return bottom
250
251 def _import_one(self, parent, modname, fqname):
252 "Import a single module."
253
254 # has the module already been imported?
255 try:
256 return sys.modules[fqname]
257 except KeyError:
258 pass
259
260 # load the module's code, or fetch the module itself
261 result = self.get_code(parent, modname, fqname)
262 if result is None:
263 return None
264
265 module = self._process_result(result, fqname)
266
267 # insert the module into its parent
268 if parent:
269 setattr(parent, modname, module)
270 return module
271
272 def _process_result(self, (ispkg, code, values), fqname):
273 # did get_code() return an actual module? (rather than a code object)
274 is_module = isinstance(code, _ModuleType)
275
276 # use the returned module, or create a new one to exec code into
277 if is_module:
278 module = code
279 else:
280 module = imp.new_module(fqname)
281
282 ### record packages a bit differently??
283 module.__importer__ = self
284 module.__ispkg__ = ispkg
285
286 # insert additional values into the module (before executing the code)
287 module.__dict__.update(values)
288
289 # the module is almost ready... make it visible
290 sys.modules[fqname] = module
291
292 # execute the code within the module's namespace
293 if not is_module:
294 exec code in module.__dict__
295
Thomas Hellerbfae1962001-02-12 09:17:06 +0000296 # fetch from sys.modules instead of returning module directly.
Martin v. Löwis70195da2001-07-28 20:33:41 +0000297 # also make module's __name__ agree with fqname, in case
298 # the "exec code in module.__dict__" played games on us.
299 module = sys.modules[fqname]
300 module.__name__ = fqname
301 return module
Greg Steindd6eefb2000-07-18 09:09:48 +0000302
303 def _load_tail(self, m, parts):
304 """Import the rest of the modules, down from the top-level module.
305
306 Returns the last module in the dotted list of modules.
307 """
308 for part in parts:
309 fqname = "%s.%s" % (m.__name__, part)
310 m = self._import_one(m, part, fqname)
311 if not m:
312 raise ImportError, "No module named " + fqname
313 return m
314
315 def _import_fromlist(self, package, fromlist):
316 'Import any sub-modules in the "from" list.'
317
318 # if '*' is present in the fromlist, then look for the '__all__'
319 # variable to find additional items (modules) to import.
320 if '*' in fromlist:
321 fromlist = list(fromlist) + \
322 list(package.__dict__.get('__all__', []))
323
324 for sub in fromlist:
325 # if the name is already present, then don't try to import it (it
326 # might not be a module!).
327 if sub != '*' and not hasattr(package, sub):
328 subname = "%s.%s" % (package.__name__, sub)
329 submod = self._import_one(package, sub, subname)
330 if not submod:
331 raise ImportError, "cannot import name " + subname
332
333 def _do_import(self, parent, parts, fromlist):
334 """Attempt to import the module relative to parent.
335
336 This method is used when the import context specifies that <self>
337 imported the parent module.
338 """
339 top_name = parts[0]
340 top_fqname = parent.__name__ + '.' + top_name
341 top_module = self._import_one(parent, top_name, top_fqname)
342 if not top_module:
343 # this importer and parent could not find the module (relatively)
344 return None
345
346 return self._finish_import(top_module, parts[1:], fromlist)
347
348 ######################################################################
Greg Stein281b8d81999-11-07 12:54:45 +0000349 #
Greg Steindd6eefb2000-07-18 09:09:48 +0000350 # METHODS TO OVERRIDE
351 #
352 def get_code(self, parent, modname, fqname):
353 """Find and retrieve the code for the given module.
Greg Stein281b8d81999-11-07 12:54:45 +0000354
Greg Steindd6eefb2000-07-18 09:09:48 +0000355 parent specifies a parent module to define a context for importing. It
356 may be None, indicating no particular context for the search.
Greg Stein281b8d81999-11-07 12:54:45 +0000357
Greg Steindd6eefb2000-07-18 09:09:48 +0000358 modname specifies a single module (not dotted) within the parent.
Greg Stein281b8d81999-11-07 12:54:45 +0000359
Greg Steindd6eefb2000-07-18 09:09:48 +0000360 fqname specifies the fully-qualified module name. This is a
361 (potentially) dotted name from the "root" of the module namespace
362 down to the modname.
363 If there is no parent, then modname==fqname.
Greg Stein281b8d81999-11-07 12:54:45 +0000364
Greg Steindd6eefb2000-07-18 09:09:48 +0000365 This method should return None, or a 3-tuple.
Greg Stein281b8d81999-11-07 12:54:45 +0000366
Greg Steindd6eefb2000-07-18 09:09:48 +0000367 * If the module was not found, then None should be returned.
Greg Stein281b8d81999-11-07 12:54:45 +0000368
Greg Steindd6eefb2000-07-18 09:09:48 +0000369 * The first item of the 2- or 3-tuple should be the integer 0 or 1,
370 specifying whether the module that was found is a package or not.
Greg Stein281b8d81999-11-07 12:54:45 +0000371
Greg Steindd6eefb2000-07-18 09:09:48 +0000372 * The second item is the code object for the module (it will be
373 executed within the new module's namespace). This item can also
374 be a fully-loaded module object (e.g. loaded from a shared lib).
Greg Steinf23aa1e2000-01-03 02:38:29 +0000375
Greg Steindd6eefb2000-07-18 09:09:48 +0000376 * The third item is a dictionary of name/value pairs that will be
377 inserted into new module before the code object is executed. This
378 is provided in case the module's code expects certain values (such
379 as where the module was found). When the second item is a module
380 object, then these names/values will be inserted *after* the module
381 has been loaded/initialized.
382 """
383 raise RuntimeError, "get_code not implemented"
Greg Stein281b8d81999-11-07 12:54:45 +0000384
385
386######################################################################
387#
Greg Stein63faa011999-11-20 11:22:37 +0000388# Some handy stuff for the Importers
389#
390
Greg Steind4f1d202000-02-18 12:03:40 +0000391# byte-compiled file suffix character
Greg Stein63faa011999-11-20 11:22:37 +0000392_suffix_char = __debug__ and 'c' or 'o'
393
394# byte-compiled file suffix
395_suffix = '.py' + _suffix_char
396
Greg Stein63faa011999-11-20 11:22:37 +0000397def _compile(pathname, timestamp):
Greg Steindd6eefb2000-07-18 09:09:48 +0000398 """Compile (and cache) a Python source file.
Greg Stein63faa011999-11-20 11:22:37 +0000399
Greg Steindd6eefb2000-07-18 09:09:48 +0000400 The file specified by <pathname> is compiled to a code object and
401 returned.
Greg Stein63faa011999-11-20 11:22:37 +0000402
Greg Steindd6eefb2000-07-18 09:09:48 +0000403 Presuming the appropriate privileges exist, the bytecodes will be
404 saved back to the filesystem for future imports. The source file's
405 modification timestamp must be provided as a Long value.
406 """
407 codestring = open(pathname, 'r').read()
408 if codestring and codestring[-1] != '\n':
409 codestring = codestring + '\n'
410 code = __builtin__.compile(codestring, pathname, 'exec')
Greg Stein63faa011999-11-20 11:22:37 +0000411
Greg Steindd6eefb2000-07-18 09:09:48 +0000412 # try to cache the compiled code
413 try:
414 f = open(pathname + _suffix_char, 'wb')
415 except IOError:
416 pass
417 else:
418 f.write('\0\0\0\0')
419 f.write(struct.pack('<I', timestamp))
420 marshal.dump(code, f)
421 f.flush()
422 f.seek(0, 0)
423 f.write(imp.get_magic())
424 f.close()
Greg Stein63faa011999-11-20 11:22:37 +0000425
Greg Steindd6eefb2000-07-18 09:09:48 +0000426 return code
Greg Stein63faa011999-11-20 11:22:37 +0000427
428_os_stat = _os_path_join = None
429def _os_bootstrap():
Greg Steindd6eefb2000-07-18 09:09:48 +0000430 "Set up 'os' module replacement functions for use during import bootstrap."
Greg Stein63faa011999-11-20 11:22:37 +0000431
Greg Steindd6eefb2000-07-18 09:09:48 +0000432 names = sys.builtin_module_names
Greg Stein63faa011999-11-20 11:22:37 +0000433
Greg Steindd6eefb2000-07-18 09:09:48 +0000434 join = None
435 if 'posix' in names:
436 sep = '/'
437 from posix import stat
438 elif 'nt' in names:
439 sep = '\\'
440 from nt import stat
441 elif 'dos' in names:
442 sep = '\\'
443 from dos import stat
444 elif 'os2' in names:
445 sep = '\\'
446 from os2 import stat
447 elif 'mac' in names:
448 from mac import stat
449 def join(a, b):
450 if a == '':
451 return b
452 path = s
453 if ':' not in a:
454 a = ':' + a
Fred Drake8152d322000-12-12 23:20:45 +0000455 if a[-1:] != ':':
Greg Steindd6eefb2000-07-18 09:09:48 +0000456 a = a + ':'
457 return a + b
458 else:
459 raise ImportError, 'no os specific module found'
Greg Stein63faa011999-11-20 11:22:37 +0000460
Greg Steindd6eefb2000-07-18 09:09:48 +0000461 if join is None:
462 def join(a, b, sep=sep):
463 if a == '':
464 return b
465 lastchar = a[-1:]
466 if lastchar == '/' or lastchar == sep:
467 return a + b
468 return a + sep + b
Greg Stein63faa011999-11-20 11:22:37 +0000469
Greg Steindd6eefb2000-07-18 09:09:48 +0000470 global _os_stat
471 _os_stat = stat
472
473 global _os_path_join
474 _os_path_join = join
Greg Stein63faa011999-11-20 11:22:37 +0000475
476def _os_path_isdir(pathname):
Greg Steindd6eefb2000-07-18 09:09:48 +0000477 "Local replacement for os.path.isdir()."
478 try:
479 s = _os_stat(pathname)
480 except OSError:
481 return None
482 return (s[0] & 0170000) == 0040000
Greg Stein63faa011999-11-20 11:22:37 +0000483
484def _timestamp(pathname):
Greg Steindd6eefb2000-07-18 09:09:48 +0000485 "Return the file modification time as a Long."
486 try:
487 s = _os_stat(pathname)
488 except OSError:
489 return None
490 return long(s[8])
Greg Stein63faa011999-11-20 11:22:37 +0000491
Greg Stein63faa011999-11-20 11:22:37 +0000492
493######################################################################
494#
495# Emulate the import mechanism for builtin and frozen modules
496#
497class BuiltinImporter(Importer):
Greg Steindd6eefb2000-07-18 09:09:48 +0000498 def get_code(self, parent, modname, fqname):
499 if parent:
500 # these modules definitely do not occur within a package context
501 return None
Greg Stein63faa011999-11-20 11:22:37 +0000502
Greg Steindd6eefb2000-07-18 09:09:48 +0000503 # look for the module
504 if imp.is_builtin(modname):
505 type = imp.C_BUILTIN
506 elif imp.is_frozen(modname):
507 type = imp.PY_FROZEN
508 else:
509 # not found
510 return None
Greg Stein63faa011999-11-20 11:22:37 +0000511
Greg Steindd6eefb2000-07-18 09:09:48 +0000512 # got it. now load and return it.
513 module = imp.load_module(modname, None, modname, ('', '', type))
514 return 0, module, { }
Greg Stein63faa011999-11-20 11:22:37 +0000515
516
517######################################################################
Greg Steinf23aa1e2000-01-03 02:38:29 +0000518#
519# Internal importer used for importing from the filesystem
520#
521class _FilesystemImporter(Importer):
Greg Steindd6eefb2000-07-18 09:09:48 +0000522 def __init__(self):
523 self.suffixes = [ ]
Greg Stein3bb578c2000-02-18 13:04:10 +0000524
Greg Steindd6eefb2000-07-18 09:09:48 +0000525 def add_suffix(self, suffix, importFunc):
526 assert callable(importFunc)
527 self.suffixes.append((suffix, importFunc))
Greg Steinf23aa1e2000-01-03 02:38:29 +0000528
Greg Steindd6eefb2000-07-18 09:09:48 +0000529 def import_from_dir(self, dir, fqname):
530 result = self._import_pathname(_os_path_join(dir, fqname), fqname)
531 if result:
532 return self._process_result(result, fqname)
533 return None
Greg Steinf23aa1e2000-01-03 02:38:29 +0000534
Greg Steindd6eefb2000-07-18 09:09:48 +0000535 def get_code(self, parent, modname, fqname):
536 # This importer is never used with an empty parent. Its existence is
537 # private to the ImportManager. The ImportManager uses the
538 # import_from_dir() method to import top-level modules/packages.
539 # This method is only used when we look for a module within a package.
540 assert parent
Greg Steinf23aa1e2000-01-03 02:38:29 +0000541
Greg Steindd6eefb2000-07-18 09:09:48 +0000542 return self._import_pathname(_os_path_join(parent.__pkgdir__, modname),
Greg Steinf23aa1e2000-01-03 02:38:29 +0000543 fqname)
Greg Steinf23aa1e2000-01-03 02:38:29 +0000544
Greg Steindd6eefb2000-07-18 09:09:48 +0000545 def _import_pathname(self, pathname, fqname):
546 if _os_path_isdir(pathname):
547 result = self._import_pathname(_os_path_join(pathname, '__init__'),
548 fqname)
549 if result:
550 values = result[2]
551 values['__pkgdir__'] = pathname
552 values['__path__'] = [ pathname ]
553 return 1, result[1], values
554 return None
555
556 for suffix, importFunc in self.suffixes:
557 filename = pathname + suffix
558 try:
559 finfo = _os_stat(filename)
560 except OSError:
561 pass
562 else:
563 return importFunc(filename, finfo, fqname)
564 return None
Greg Steinf23aa1e2000-01-03 02:38:29 +0000565
566######################################################################
567#
568# SUFFIX-BASED IMPORTERS
569#
570
Greg Stein3bb578c2000-02-18 13:04:10 +0000571def py_suffix_importer(filename, finfo, fqname):
Greg Steindd6eefb2000-07-18 09:09:48 +0000572 file = filename[:-3] + _suffix
573 t_py = long(finfo[8])
574 t_pyc = _timestamp(file)
Greg Steinf23aa1e2000-01-03 02:38:29 +0000575
Greg Steindd6eefb2000-07-18 09:09:48 +0000576 code = None
577 if t_pyc is not None and t_pyc >= t_py:
578 f = open(file, 'rb')
579 if f.read(4) == imp.get_magic():
580 t = struct.unpack('<I', f.read(4))[0]
581 if t == t_py:
582 code = marshal.load(f)
583 f.close()
584 if code is None:
585 file = filename
586 code = _compile(file, t_py)
Greg Steinf23aa1e2000-01-03 02:38:29 +0000587
Greg Steindd6eefb2000-07-18 09:09:48 +0000588 return 0, code, { '__file__' : file }
Greg Steinf23aa1e2000-01-03 02:38:29 +0000589
Greg Stein3bb578c2000-02-18 13:04:10 +0000590class DynLoadSuffixImporter:
Greg Steindd6eefb2000-07-18 09:09:48 +0000591 def __init__(self, desc):
592 self.desc = desc
Greg Steinf23aa1e2000-01-03 02:38:29 +0000593
Greg Steindd6eefb2000-07-18 09:09:48 +0000594 def import_file(self, filename, finfo, fqname):
595 fp = open(filename, self.desc[1])
596 module = imp.load_module(fqname, fp, filename, self.desc)
597 module.__file__ = filename
598 return 0, module, { }
Greg Steinf23aa1e2000-01-03 02:38:29 +0000599
600
601######################################################################
Greg Stein63faa011999-11-20 11:22:37 +0000602
Greg Stein63faa011999-11-20 11:22:37 +0000603def _print_importers():
Greg Steindd6eefb2000-07-18 09:09:48 +0000604 items = sys.modules.items()
605 items.sort()
606 for name, module in items:
607 if module:
608 print name, module.__dict__.get('__importer__', '-- no importer')
609 else:
610 print name, '-- non-existent module'
Greg Stein63faa011999-11-20 11:22:37 +0000611
Greg Steinf23aa1e2000-01-03 02:38:29 +0000612def _test_revamp():
Greg Steindd6eefb2000-07-18 09:09:48 +0000613 ImportManager().install()
614 sys.path.insert(0, BuiltinImporter())
Greg Steinf23aa1e2000-01-03 02:38:29 +0000615
Greg Stein281b8d81999-11-07 12:54:45 +0000616######################################################################
Greg Stein42b9bc72000-02-19 13:36:23 +0000617
618#
619# TODO
620#
621# from Finn Bock:
Greg Stein42b9bc72000-02-19 13:36:23 +0000622# type(sys) is not a module in JPython. what to use instead?
623# imp.C_EXTENSION is not in JPython. same for get_suffixes and new_module
624#
625# given foo.py of:
626# import sys
627# sys.modules['foo'] = sys
628#
629# ---- standard import mechanism
630# >>> import foo
631# >>> foo
632# <module 'sys' (built-in)>
633#
634# ---- revamped import mechanism
635# >>> import imputil
636# >>> imputil._test_revamp()
637# >>> import foo
638# >>> foo
639# <module 'foo' from 'foo.py'>
640#
641#
642# from MAL:
643# should BuiltinImporter exist in sys.path or hard-wired in ImportManager?
644# need __path__ processing
645# performance
646# move chaining to a subclass [gjs: it's been nuked]
Greg Stein42b9bc72000-02-19 13:36:23 +0000647# deinstall should be possible
648# query mechanism needed: is a specific Importer installed?
649# py/pyc/pyo piping hooks to filter/process these files
650# wish list:
651# distutils importer hooked to list of standard Internet repositories
652# module->file location mapper to speed FS-based imports
653# relative imports
654# keep chaining so that it can play nice with other import hooks
655#
656# from Gordon:
657# push MAL's mapper into sys.path[0] as a cache (hard-coded for apps)
658#
659# from Guido:
660# need to change sys.* references for rexec environs
661# need hook for MAL's walk-me-up import strategy, or Tim's absolute strategy
Fred Drake8152d322000-12-12 23:20:45 +0000662# watch out for sys.modules[...] is None
Greg Stein42b9bc72000-02-19 13:36:23 +0000663# flag to force absolute imports? (speeds _determine_import_context and
664# checking for a relative module)
665# insert names of archives into sys.path (see quote below)
666# note: reload does NOT blast module dict
667# shift import mechanisms and policies around; provide for hooks, overrides
668# (see quote below)
669# add get_source stuff
670# get_topcode and get_subcode
671# CRLF handling in _compile
672# race condition in _compile
673# refactoring of os.py to deal with _os_bootstrap problem
674# any special handling to do for importing a module with a SyntaxError?
675# (e.g. clean up the traceback)
676# implement "domain" for path-type functionality using pkg namespace
677# (rather than FS-names like __path__)
678# don't use the word "private"... maybe "internal"
679#
680#
681# Guido's comments on sys.path caching:
Tim Peters07e99cb2001-01-14 23:47:14 +0000682#
Greg Stein42b9bc72000-02-19 13:36:23 +0000683# We could cache this in a dictionary: the ImportManager can have a
684# cache dict mapping pathnames to importer objects, and a separate
685# method for coming up with an importer given a pathname that's not yet
686# in the cache. The method should do a stat and/or look at the
687# extension to decide which importer class to use; you can register new
688# importer classes by registering a suffix or a Boolean function, plus a
689# class. If you register a new importer class, the cache is zapped.
690# The cache is independent from sys.path (but maintained per
691# ImportManager instance) so that rearrangements of sys.path do the
692# right thing. If a path is dropped from sys.path the corresponding
693# cache entry is simply no longer used.
694#
695# My/Guido's comments on factoring ImportManager and Importer:
696#
697# > However, we still have a tension occurring here:
Tim Peters07e99cb2001-01-14 23:47:14 +0000698# >
Greg Stein42b9bc72000-02-19 13:36:23 +0000699# > 1) implementing policy in ImportManager assists in single-point policy
700# > changes for app/rexec situations
701# > 2) implementing policy in Importer assists in package-private policy
702# > changes for normal, operating conditions
Tim Peters07e99cb2001-01-14 23:47:14 +0000703# >
Greg Stein42b9bc72000-02-19 13:36:23 +0000704# > I'll see if I can sort out a way to do this. Maybe the Importer class will
705# > implement the methods (which can be overridden to change policy) by
706# > delegating to ImportManager.
Tim Peters07e99cb2001-01-14 23:47:14 +0000707#
Greg Stein42b9bc72000-02-19 13:36:23 +0000708# Maybe also think about what kind of policies an Importer would be
709# likely to want to change. I have a feeling that a lot of the code
710# there is actually not so much policy but a *necessity* to get things
711# working given the calling conventions for the __import__ hook: whether
712# to return the head or tail of a dotted name, or when to do the "finish
713# fromlist" stuff.
714#