blob: 2107e9e377ebef0fc74e82a1250b92a8ff64ab1d [file] [log] [blame]
Brett Cannon23cbd8a2009-01-18 00:24:28 +00001"""Core implementation of import.
2
3This module is NOT meant to be directly imported! It has been designed such
4that it can be bootstrapped into Python as the implementation of import. As
5such it requires the injection of specific modules and attributes in order to
6work. One should use importlib as the public-facing version of this module.
7
8"""
9
10# Injected modules are '_warnings', 'imp', 'sys', 'marshal', 'errno', and '_os'
11# (a.k.a. 'posix', 'nt' or 'os2').
12# Injected attribute is path_sep.
13#
14# When editing this code be aware that code executed at import time CANNOT
15# reference any injected objects! This includes not only global code but also
16# anything specified at the class level.
17
18
19# XXX Could also expose Modules/getpath.c:joinpath()
20def _path_join(*args):
21 """Replacement for os.path.join."""
22 return path_sep.join(x[:-len(path_sep)] if x.endswith(path_sep) else x
23 for x in args)
24
25
26def _path_exists(path):
27 """Replacement for os.path.exists."""
28 try:
29 _os.stat(path)
30 except OSError:
31 return False
32 else:
33 return True
34
35
36def _path_is_mode_type(path, mode):
37 """Test whether the path is the specified mode type."""
38 try:
39 stat_info = _os.stat(path)
40 except OSError:
41 return False
42 return (stat_info.st_mode & 0o170000) == mode
43
44
45# XXX Could also expose Modules/getpath.c:isfile()
46def _path_isfile(path):
47 """Replacement for os.path.isfile."""
48 return _path_is_mode_type(path, 0o100000)
49
50
51# XXX Could also expose Modules/getpath.c:isdir()
52def _path_isdir(path):
53 """Replacement for os.path.isdir."""
54 return _path_is_mode_type(path, 0o040000)
55
56
57def _path_without_ext(path, ext_type):
58 """Replacement for os.path.splitext()[0]."""
59 for suffix in suffix_list(ext_type):
60 if path.endswith(suffix):
61 return path[:-len(suffix)]
62 else:
63 raise ValueError("path is not of the specified type")
64
65
66def _path_absolute(path):
67 """Replacement for os.path.abspath."""
68 if not path:
69 path = _os.getcwd()
70 try:
71 return _os._getfullpathname(path)
72 except AttributeError:
73 if path.startswith('/'):
74 return path
75 else:
76 return _path_join(_os.getcwd(), path)
77
78
79class closing:
80
81 """Simple replacement for contextlib.closing."""
82
83 def __init__(self, obj):
84 self.obj = obj
85
86 def __enter__(self):
87 return self.obj
88
89 def __exit__(self, *args):
90 self.obj.close()
91
92
Brett Cannon5abdc932009-01-22 22:43:07 +000093class BuiltinImporter:
Brett Cannon23cbd8a2009-01-18 00:24:28 +000094
Brett Cannon5abdc932009-01-22 22:43:07 +000095 """Meta path loader for built-in modules.
Brett Cannon23cbd8a2009-01-18 00:24:28 +000096
Brett Cannon5abdc932009-01-22 22:43:07 +000097 All methods are either class or static methods, allowing direct use of the
98 class.
Brett Cannon23cbd8a2009-01-18 00:24:28 +000099
100 """
101
Brett Cannon5abdc932009-01-22 22:43:07 +0000102 @classmethod
103 def find_module(cls, fullname, path=None):
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000104 """Try to find the built-in module.
105
106 If 'path' is ever specified then the search is considered a failure.
107
108 """
109 if path is not None:
110 return None
Brett Cannon5abdc932009-01-22 22:43:07 +0000111 return cls if imp.is_builtin(fullname) else None
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000112
Brett Cannon78246b62009-01-25 04:56:30 +0000113 @classmethod
114 def load_module(cls, fullname):
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000115 """Load a built-in module."""
116 if fullname not in sys.builtin_module_names:
117 raise ImportError("{0} is not a built-in module".format(fullname))
Brett Cannon5abdc932009-01-22 22:43:07 +0000118 return imp.init_builtin(fullname)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000119
120
Brett Cannon5abdc932009-01-22 22:43:07 +0000121class FrozenImporter:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000122
Brett Cannon5abdc932009-01-22 22:43:07 +0000123 """Meta path class for importing frozen modules.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000124
Brett Cannon5abdc932009-01-22 22:43:07 +0000125 All methods are either class or static method to allow direct use of the
126 class.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000127
Brett Cannon5abdc932009-01-22 22:43:07 +0000128 """
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000129
Brett Cannon5abdc932009-01-22 22:43:07 +0000130 @classmethod
131 def find_module(cls, fullname, path=None):
132 """Find a frozen module."""
133 return cls if imp.is_frozen(fullname) else None
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000134
Brett Cannon5abdc932009-01-22 22:43:07 +0000135 @classmethod
136 def load_module(cls, fullname):
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000137 """Load a frozen module."""
Brett Cannon5abdc932009-01-22 22:43:07 +0000138 if cls.find_module(fullname) is None:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000139 raise ImportError("{0} is not a frozen module".format(fullname))
Brett Cannon223a19d2009-02-01 01:34:13 +0000140 module = imp.init_frozen(fullname)
141 if hasattr(module, '__path__'):
142 module.__package__ = module.__name__
143 elif '.' in module.__name__:
144 module.__package__ = module.__name__.rsplit('.', 1)[0]
145 return module
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000146
147
148class ChainedImporter(object):
149
150 """Finder that sequentially calls other finders."""
151
152 def __init__(self, *importers):
153 self._importers = importers
154
155 def find_module(self, fullname, path=None):
156 for importer in self._importers:
157 result = importer.find_module(fullname, path)
158 if result:
159 return result
160 else:
161 return None
162
163
164# XXX Don't make filesystem-specific and instead make generic for any path
165# hooks.
166def chaining_fs_path_hook(*path_hooks):
167 """Create a closure which calls the path hooks sequentially looking for
168 which path hooks can handle a path entry.
169
170
171 Passed-in path hooks work as any other path hooks, raising ImportError if
172 they cannot handle the path, otherwise returning a finder.
173
174 """
175 def chained_fs_path_hook(path_entry):
176 """Closure which sees which of the captured path hooks can handle the
177 path entry."""
178 absolute_path = _path_absolute(path_entry)
179 if not _path_isdir(absolute_path):
180 raise ImportError("only directories are supported")
181 accepted = []
182 for path_hook in path_hooks:
183 try:
184 accepted.append(path_hook(absolute_path))
185 except ImportError:
186 continue
187 if not accepted:
188 raise ImportError("no path hooks could handle %s" % path_entry)
189 return ChainedImporter(*accepted)
190 return chained_fs_path_hook
191
192
193def check_name(method):
194 """Decorator to verify that the module being requested matches the one the
195 loader can handle.
196
197 The first argument (self) must define _name which the second argument is
198 comapred against. If the comparison fails then ImportError is raised.
199
200 """
201 def inner(self, name, *args, **kwargs):
202 if self._name != name:
203 raise ImportError("loader cannot handle %s" % name)
204 return method(self, name, *args, **kwargs)
205 inner.__name__ = method.__name__
206 inner.__doc__ = method.__doc__
207 inner.__dict__.update(method.__dict__)
208 return inner
209
210
211class _ExtensionFileLoader(object):
212
213 """Loader for extension modules.
214
215 The constructor is designed to work with FileImporter.
216
217 """
218
219 def __init__(self, name, path, is_pkg):
220 """Initialize the loader.
221
222 If is_pkg is True then an exception is raised as extension modules
223 cannot be the __init__ module for an extension module.
224
225 """
226 self._name = name
227 self._path = path
228 if is_pkg:
229 raise ValueError("extension modules cannot be packages")
230
231 @check_name
232 def load_module(self, fullname):
233 """Load an extension module."""
234 assert self._name == fullname
235 try:
236 module = imp.load_dynamic(fullname, self._path)
237 module.__loader__ = self
238 return module
239 except:
240 # If an error occurred, don't leave a partially initialized module.
241 if fullname in sys.modules:
242 del sys.modules[fullname]
243 raise
244
245 @check_name
246 def is_package(self, fullname):
247 """Return False as an extension module can never be a package."""
248 return False
249
250 @check_name
251 def get_code(self, fullname):
252 """Return None as an extension module cannot create a code object."""
253 return None
254
255 @check_name
256 def get_source(self, fullname):
257 """Return None as extension modules have no source code."""
258 return None
259
260
261def suffix_list(suffix_type):
262 """Return a list of file suffixes based on the imp file type."""
263 return [suffix[0] for suffix in imp.get_suffixes()
264 if suffix[2] == suffix_type]
265
266
267# XXX Need a better name.
268def get_module(fxn):
269 """Decorator to handle selecting the proper module for load_module
270 implementations.
271
272 Decorated modules are passed the module to use instead of the module name.
273 The module is either from sys.modules if it already exists (for reloading)
274 or is a new module which has __name__ set. If any exception is raised by
275 the decorated method then __loader__, __name__, __file__, and __path__ are
276 all restored on the module to their original values.
277
278 """
279 def decorated(self, fullname):
280 module = sys.modules.get(fullname)
281 is_reload = bool(module)
282 if not is_reload:
283 # This must be done before open() is called as the 'io' module
284 # implicitly imports 'locale' and would otherwise trigger an
285 # infinite loop.
286 module = imp.new_module(fullname)
287 module.__name__ = fullname
288 sys.modules[fullname] = module
289 else:
290 original_values = {}
291 modified_attrs = ['__loader__', '__name__', '__file__', '__path__']
292 for attr in modified_attrs:
293 try:
294 original_values[attr] = getattr(module, attr)
295 except AttributeError:
296 pass
297 try:
298 return fxn(self, module)
299 except:
300 if not is_reload:
301 del sys.modules[fullname]
302 else:
303 for attr in modified_attrs:
304 if attr in original_values:
305 setattr(module, attr, original_values[attr])
306 elif hasattr(module, attr):
307 delattr(module, attr)
308 raise
309 return decorated
310
311
312class _PyFileLoader(object):
313 # XXX Still smart to have this as a separate class? Or would it work
314 # better to integrate with PyFileImporter? Could cache _is_pkg info.
315 # FileImporter can be changed to return self instead of a specific loader
316 # call. Otherwise _base_path can be calculated on the fly without issue if
317 # it is known whether a module should be treated as a path or package to
318 # minimize stat calls. Could even go as far as to stat the directory the
319 # importer is in to detect changes and then cache all the info about what
320 # files were found (if stating directories is platform-dependent).
321
322 """Load a Python source or bytecode file."""
323
324 def __init__(self, name, path, is_pkg):
325 self._name = name
326 self._is_pkg = is_pkg
327 # Figure out the base path based on whether it was source or bytecode
328 # that was found.
329 try:
330 self._base_path = _path_without_ext(path, imp.PY_SOURCE)
331 except ValueError:
332 self._base_path = _path_without_ext(path, imp.PY_COMPILED)
333
334 def _find_path(self, ext_type):
335 """Find a path from the base path and the specified extension type that
336 exists, returning None if one is not found."""
337 for suffix in suffix_list(ext_type):
338 path = self._base_path + suffix
339 if _path_exists(path):
340 return path
341 else:
342 return None
343
Brett Cannon51c50262009-02-01 05:33:17 +0000344 @check_name
345 def source_path(self, fullname):
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000346 """Return the path to an existing source file for the module, or None
347 if one cannot be found."""
348 # Not a property so that it is easy to override.
349 return self._find_path(imp.PY_SOURCE)
350
Brett Cannon51c50262009-02-01 05:33:17 +0000351 @check_name
352 def bytecode_path(self, fullname):
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000353 """Return the path to a bytecode file, or None if one does not
354 exist."""
355 # Not a property for easy overriding.
356 return self._find_path(imp.PY_COMPILED)
357
358 @check_name
359 @get_module
360 def load_module(self, module):
361 """Load a Python source or bytecode module."""
Brett Cannon51c50262009-02-01 05:33:17 +0000362 name = module.__name__
363 source_path = self.source_path(name)
364 bytecode_path = self.bytecode_path(name)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000365 code_object = self.get_code(module.__name__)
366 module.__file__ = source_path if source_path else bytecode_path
367 module.__loader__ = self
368 if self._is_pkg:
369 module.__path__ = [module.__file__.rsplit(path_sep, 1)[0]]
370 module.__package__ = module.__name__
371 elif '.' in module.__name__:
372 module.__package__ = module.__name__.rsplit('.', 1)[0]
373 else:
374 module.__package__ = None
375 exec(code_object, module.__dict__)
376 return module
377
378 @check_name
379 def source_mtime(self, name):
380 """Return the modification time of the source for the specified
381 module."""
Brett Cannon51c50262009-02-01 05:33:17 +0000382 source_path = self.source_path(name)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000383 if not source_path:
384 return None
385 return int(_os.stat(source_path).st_mtime)
386
387 @check_name
388 def get_source(self, fullname):
389 """Return the source for the module as a string.
390
391 Return None if the source is not available. Raise ImportError if the
392 laoder cannot handle the specified module.
393
394 """
Brett Cannon51c50262009-02-01 05:33:17 +0000395 source_path = self._source_path(name)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000396 if source_path is None:
397 return None
398 import tokenize
Brett Cannonb4a1b8c2009-01-19 06:56:16 +0000399 with closing(_fileio._FileIO(source_path, 'r')) as file:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000400 encoding, lines = tokenize.detect_encoding(file.readline)
401 # XXX Will fail when passed to compile() if the encoding is
402 # anything other than UTF-8.
403 return open(source_path, encoding=encoding).read()
404
405 @check_name
Brett Cannon776e7012009-02-01 06:07:57 +0000406 def write_bytecode(self, name, data):
407 """Write out 'data' for the specified module, returning a boolean
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000408 signifying if the write-out actually occurred.
409
410 Raises ImportError (just like get_source) if the specified module
411 cannot be handled by the loader.
412
413 """
Brett Cannon51c50262009-02-01 05:33:17 +0000414 bytecode_path = self.bytecode_path(name)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000415 if not bytecode_path:
416 bytecode_path = self._base_path + suffix_list(imp.PY_COMPILED)[0]
417 file = _fileio._FileIO(bytecode_path, 'w')
418 try:
419 with closing(file) as bytecode_file:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000420 bytecode_file.write(data)
421 return True
422 except IOError as exc:
423 if exc.errno == errno.EACCES:
424 return False
425 else:
426 raise
427
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000428 @check_name
429 def get_code(self, name):
Brett Cannon776e7012009-02-01 06:07:57 +0000430 """Return the code object for the module."""
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000431 # XXX Care enough to make sure this call does not happen if the magic
432 # number is bad?
433 source_timestamp = self.source_mtime(name)
434 # Try to use bytecode if it is available.
Brett Cannonba96f0f2009-02-01 05:43:31 +0000435 bytecode_path = self.bytecode_path(name)
436 if bytecode_path:
437 data = self.get_data(bytecode_path)
438 magic = data[:4]
439 pyc_timestamp = marshal._r_long(data[4:8])
440 bytecode = data[8:]
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000441 try:
442 # Verify that the magic number is valid.
443 if imp.get_magic() != magic:
444 raise ImportError("bad magic number")
445 # Verify that the bytecode is not stale (only matters when
446 # there is source to fall back on.
447 if source_timestamp:
448 if pyc_timestamp < source_timestamp:
449 raise ImportError("bytcode is stale")
450 except ImportError:
451 # If source is available give it a shot.
452 if source_timestamp is not None:
453 pass
454 else:
455 raise
456 else:
457 # Bytecode seems fine, so try to use it.
458 # XXX If the bytecode is ill-formed, would it be beneficial to
459 # try for using source if available and issue a warning?
460 return marshal.loads(bytecode)
461 elif source_timestamp is None:
462 raise ImportError("no source or bytecode available to create code "
463 "object for {0!r}".format(name))
464 # Use the source.
Brett Cannonba96f0f2009-02-01 05:43:31 +0000465 source_path = self.source_path(name)
466 source = self.get_data(source_path)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000467 # Convert to universal newlines.
468 line_endings = b'\n'
469 for index, c in enumerate(source):
470 if c == ord(b'\n'):
471 break
472 elif c == ord(b'\r'):
473 line_endings = b'\r'
474 try:
475 if source[index+1] == ord(b'\n'):
476 line_endings += b'\n'
477 except IndexError:
478 pass
479 break
480 if line_endings != b'\n':
481 source = source.replace(line_endings, b'\n')
482 code_object = compile(source, source_path, 'exec', dont_inherit=True)
483 # Generate bytecode and write it out.
484 if not sys.dont_write_bytecode:
Brett Cannon776e7012009-02-01 06:07:57 +0000485 data = bytearray(imp.get_magic())
486 data.extend(marshal._w_long(source_timestamp))
487 data.extend(marshal.dumps(code_object))
488 self.write_bytecode(name, data)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000489 return code_object
490
491 def get_data(self, path):
492 """Return the data from path as raw bytes."""
493 return _fileio._FileIO(path, 'r').read()
494
495 @check_name
496 def is_package(self, fullname):
497 """Return a boolean based on whether the module is a package.
498
499 Raises ImportError (like get_source) if the loader cannot handle the
500 package.
501
502 """
503 return self._is_pkg
504
505
506class FileImporter(object):
507
508 """Base class for file importers.
509
510 Subclasses are expected to define the following attributes:
511
512 * _suffixes
513 Sequence of file suffixes whose order will be followed.
514
515 * _possible_package
516 True if importer should check for packages.
517
518 * _loader
519 A callable that takes the module name, a file path, and whether
520 the path points to a package and returns a loader for the module
521 found at that path.
522
523 """
524
525 def __init__(self, path_entry):
526 """Initialize an importer for the passed-in sys.path entry (which is
527 assumed to have already been verified as an existing directory).
528
529 Can be used as an entry on sys.path_hook.
530
531 """
532 self._path_entry = path_entry
533
534 def find_module(self, fullname, path=None):
535 tail_module = fullname.rsplit('.', 1)[-1]
536 package_directory = None
537 if self._possible_package:
538 for ext in self._suffixes:
539 package_directory = _path_join(self._path_entry, tail_module)
540 init_filename = '__init__' + ext
541 package_init = _path_join(package_directory, init_filename)
542 if (_path_isfile(package_init) and
543 _case_ok(self._path_entry, tail_module) and
544 _case_ok(package_directory, init_filename)):
545 return self._loader(fullname, package_init, True)
546 for ext in self._suffixes:
547 file_name = tail_module + ext
548 file_path = _path_join(self._path_entry, file_name)
549 if (_path_isfile(file_path) and
550 _case_ok(self._path_entry, file_name)):
551 return self._loader(fullname, file_path, False)
552 else:
553 # Raise a warning if it matches a directory w/o an __init__ file.
554 if (package_directory is not None and
555 _path_isdir(package_directory) and
556 _case_ok(self._path_entry, tail_module)):
557 _warnings.warn("Not importing directory %s: missing __init__"
558 % package_directory, ImportWarning)
559 return None
560
561
562class ExtensionFileImporter(FileImporter):
563
564 """Importer for extension files."""
565
566 _possible_package = False
567 _loader = _ExtensionFileLoader
568
569 def __init__(self, path_entry):
570 # Assigning to _suffixes here instead of at the class level because
571 # imp is not imported at the time of class creation.
572 self._suffixes = suffix_list(imp.C_EXTENSION)
573 super(ExtensionFileImporter, self).__init__(path_entry)
574
575
576class PyFileImporter(FileImporter):
577
578 """Importer for source/bytecode files."""
579
580 _possible_package = True
581 _loader = _PyFileLoader
582
583 def __init__(self, path_entry):
584 # Lack of imp during class creation means _suffixes is set here.
585 # Make sure that Python source files are listed first! Needed for an
586 # optimization by the loader.
587 self._suffixes = suffix_list(imp.PY_SOURCE)
588 self._suffixes += suffix_list(imp.PY_COMPILED)
589 super(PyFileImporter, self).__init__(path_entry)
590
591
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000592class PathFinder:
Brett Cannon1d376682009-02-02 19:19:36 +0000593
594 """Meta path finder for sys.(path|path_hooks|path_importer_cache)."""
595
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000596 _default_hook = staticmethod(chaining_fs_path_hook(ExtensionFileImporter,
597 PyFileImporter))
Brett Cannon1d376682009-02-02 19:19:36 +0000598
599 # The list of implicit hooks cannot be a class attribute because of
600 # bootstrapping issues for accessing imp.
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000601 @classmethod
602 def _implicit_hooks(cls):
Brett Cannon1d376682009-02-02 19:19:36 +0000603 """Return a list of the implicit path hooks."""
Brett Cannon1f9bcd32009-02-05 23:36:02 +0000604 return [cls._default_hook, imp.NullImporter]
Brett Cannon1d376682009-02-02 19:19:36 +0000605
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000606 @classmethod
607 def _path_hooks(cls, path):
Brett Cannon1d376682009-02-02 19:19:36 +0000608 """Search sys.path_hooks for a finder for 'path'.
609
610 Guaranteed to return a finder for the path as NullImporter is the
611 default importer for any path that does not have an explicit finder.
612
613 """
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000614 for hook in sys.path_hooks + cls._implicit_hooks():
Brett Cannon1d376682009-02-02 19:19:36 +0000615 try:
616 return hook(path)
617 except ImportError:
618 continue
619 else:
620 # This point should never be reached thanks to NullImporter.
621 raise SystemError("no hook could find an importer for "
622 "{0}".format(path))
623
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000624 @classmethod
625 def _path_importer_cache(cls, path):
Brett Cannon1d376682009-02-02 19:19:36 +0000626 """Get the finder for the path from sys.path_importer_cache.
627
628 If the path is not in the cache, find the appropriate finder and cache
629 it. If None is cached, get the default finder and cache that
630 (if applicable).
631
632 Because of NullImporter, some finder should be returned. The only
633 explicit fail case is if None is cached but the path cannot be used for
634 the default hook, for which ImportError is raised.
635
636 """
637 try:
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000638 finder = sys.path_importer_cache[path]
Brett Cannon1d376682009-02-02 19:19:36 +0000639 except KeyError:
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000640 finder = cls._path_hooks(path)
Brett Cannon1d376682009-02-02 19:19:36 +0000641 sys.path_importer_cache[path] = finder
642 else:
643 if finder is None:
644 # Raises ImportError on failure.
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000645 finder = cls._default_hook(path)
Brett Cannon1d376682009-02-02 19:19:36 +0000646 sys.path_importer_cache[path] = finder
647 return finder
648
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000649 @classmethod
650 def find_module(cls, fullname, path=None):
Brett Cannon1d376682009-02-02 19:19:36 +0000651 """Find the module on sys.path or 'path'."""
652 if not path:
653 path = sys.path
654 for entry in path:
655 try:
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000656 finder = cls._path_importer_cache(entry)
Brett Cannon1d376682009-02-02 19:19:36 +0000657 except ImportError:
658 continue
659 loader = finder.find_module(fullname)
660 if loader:
661 return loader
662 else:
663 return None
664
665
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000666class ImportLockContext(object):
667
668 """Context manager for the import lock."""
669
670 def __enter__(self):
671 """Acquire the import lock."""
672 imp.acquire_lock()
673
674 def __exit__(self, exc_type, exc_value, exc_traceback):
675 """Release the import lock regardless of any raised exceptions."""
676 imp.release_lock()
677
678
Brett Cannon7f9876c2009-02-06 02:47:33 +0000679def _gcd_import(name, package=None, level=0):
680 """Import and return the module based on its name, the package the call is
681 being made from, and the level adjustment.
682
683 This function represents the greatest common denominator of functionality
684 between import_module and __import__.
685 """
686 if package and package not in sys.modules:
687 msg = "Parent module {0!r} not loaded, cannot perform relative import"
688 raise SystemError(msg.format(package))
689 dot = len(package)
690 if level > 0:
691 for x in range(level, 1, -1):
692 try:
693 dot = package.rindex('.', 0, dot)
694 except AttributeError:
695 raise ValueError("__package__ not set to a string")
696 except ValueError:
697 raise ValueError("attempted relative import beyond top-level "
698 "package")
699 name = "{0}.{1}".format(package[:dot], name)
700 with ImportLockContext():
701 try:
702 return sys.modules[name]
703 except KeyError:
704 pass
705 parent = name.rpartition('.')[0]
706 path = None
707 if parent:
708 if parent not in sys.modules:
709 parent_module = _gcd_import(parent)
710 else:
711 parent_module = sys.modules[parent]
712 path = parent_module.__path__
713 for finder in sys.meta_path + [PathFinder]:
714 loader = finder.find_module(name, path)
715 if loader: # XXX Worth checking for None explicitly?
716 return loader.load_module(name)
717 else:
718 raise ImportError("No module named {0}".format(name))
719
720
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000721class Import(object):
722
723 """Class that implements the __import__ interface.
724
725 Backwards compatibility is maintained by extending sys.meta_path
726 interally (for handling built-in and frozen modules) and providing a
727 default path hooks entry for extension modules, .py, and .pyc
728 files. Both are controlled during instance initialization.
729
730 """
731
732 def __init__(self, default_path_hook=None,
733 extended_meta_path=None):
734 """Store a default path hook entry and a sequence to internally extend
735 sys.meta_path by (passing in None uses default importers)."""
736 if extended_meta_path is None:
Brett Cannon5abdc932009-01-22 22:43:07 +0000737 self.extended_meta_path = BuiltinImporter, FrozenImporter
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000738 else:
739 self.extended_meta_path = extended_meta_path
740 self.default_path_hook = default_path_hook
741 if self.default_path_hook is None:
742 # Create a handler to deal with extension modules, .py, and .pyc
743 # files. Built-in and frozen modules are handled by sys.meta_path
744 # entries.
745 importers = [ExtensionFileImporter, PyFileImporter]
746 self.default_path_hook = chaining_fs_path_hook(*importers)
747
748 def _search_meta_path(self, name, path=None):
749 """Check the importers on sys.meta_path for a loader along with the
750 extended meta path sequence stored within this instance.
751
752 The extended sys.meta_path entries are searched after the entries on
753 sys.meta_path.
754
755 """
756 for entry in (tuple(sys.meta_path) + self.extended_meta_path):
757 loader = entry.find_module(name, path)
758 if loader:
759 return loader
760 else:
761 raise ImportError("No module named %s" % name)
762
763 def _sys_path_importer(self, path_entry):
764 """Return the importer for the specified path, from
765 sys.path_importer_cache if possible.
766
767 If None is stored in sys.path_importer_cache then use the default path
768 hook.
769
770 """
771 try:
772 # See if an importer is cached.
773 importer = sys.path_importer_cache[path_entry]
774 # If None was returned, use default importer factory.
775 if importer is None:
776 return self.default_path_hook(path_entry)
777 else:
778 return importer
779 except KeyError:
780 # No cached importer found; try to get a new one from
781 # sys.path_hooks or imp.NullImporter.
782 for importer_factory in (sys.path_hooks + [imp.NullImporter]):
783 try:
784 importer = importer_factory(path_entry)
785 sys.path_importer_cache[path_entry] = importer
786 return importer
787 except ImportError:
788 continue
789 else:
790 # No importer factory on sys.path_hooks works; use the default
791 # importer factory and store None in sys.path_importer_cache.
792 try:
793 importer = self.default_path_hook(path_entry)
794 sys.path_importer_cache[path_entry] = None
795 return importer
796 except ImportError:
797 raise ImportError("no importer found for %s" % path_entry)
798
799 def _search_std_path(self, name, path=None):
800 """Check sys.path or 'path' (depending if 'path' is set) for the
801 named module and return its loader."""
802 if path:
803 search_paths = path
804 else:
805 search_paths = sys.path
806 for entry in search_paths:
807 try:
808 importer = self._sys_path_importer(entry)
809 except ImportError:
810 continue
811 loader = importer.find_module(name)
812 if loader:
813 return loader
814 else:
815 raise ImportError("No module named %s" % name)
816
817 def module_from_cache(self, name):
818 """Try to return the named module from sys.modules.
819
820 Return False if the module is not in the cache.
821 """
822 if name in sys.modules:
823 return sys.modules[name]
824 else:
825 return False
826
827 def post_import(self, module):
828 """Perform any desired post-import processing on the module."""
829 return module
830
831 def _import_module(self, name, path=None):
832 """Import the specified module with no handling of parent modules.
833
834 If None is set for a value in sys.modules (to signify that a relative
835 import was attempted and failed) then ImportError is raised.
836
837 """
838 cached_module = self.module_from_cache(name)
839 if cached_module is not False:
840 if cached_module is None:
841 raise ImportError("relative import redirect")
842 else:
843 return cached_module
844 try:
845 # Attempt to find a loader on sys.meta_path.
846 loader = self._search_meta_path(name, path)
847 except ImportError:
848 # sys.meta_path search failed. Attempt to find a loader on
849 # sys.path. If this fails then module cannot be found.
850 loader = self._search_std_path(name, path)
851 # A loader was found. It is the loader's responsibility to have put an
852 # entry in sys.modules.
853 module = self.post_import(loader.load_module(name))
854 # 'module' could be something like None.
855 if not hasattr(module, '__name__'):
856 return module
857 # Set __package__.
858 if not hasattr(module, '__package__') or module.__package__ is None:
859 if hasattr(module, '__path__'):
860 module.__package__ = module.__name__
861 elif '.' in module.__name__:
862 pkg_name = module.__name__.rsplit('.', 1)[0]
863 module.__package__ = pkg_name
864 else:
865 module.__package__ = None
866 return module
867
868
869 def _import_full_module(self, name):
870 """Import a module and set it on its parent if needed."""
871 path_list = None
872 parent_name = name.rsplit('.', 1)[0]
873 parent = None
874 if parent_name != name:
875 parent = sys.modules[parent_name]
876 try:
877 path_list = parent.__path__
878 except AttributeError:
879 pass
880 self._import_module(name, path_list)
881 module = sys.modules[name]
882 if parent:
883 tail = name.rsplit('.', 1)[-1]
884 setattr(parent, tail, module)
885
886 def _find_package(self, name, has_path):
887 """Return the package that the caller is in or None."""
888 if has_path:
889 return name
890 elif '.' in name:
891 return name.rsplit('.', 1)[0]
892 else:
893 return None
894
895 @staticmethod
896 def _resolve_name(name, package, level):
897 """Return the absolute name of the module to be imported."""
898 level -= 1
899 try:
900 if package.count('.') < level:
901 raise ValueError("attempted relative import beyond top-level "
902 "package")
903 except AttributeError:
904 raise ValueError("__package__ not set to a string")
905 base = package.rsplit('.', level)[0]
906 if name:
907 return "{0}.{1}".format(base, name)
908 else:
909 return base
910
911 def _return_module(self, absolute_name, relative_name, fromlist):
912 """Return the proper module based on what module was requested (and its
913 absolute module name), who is requesting it, and whether any specific
914 attributes were specified.
915
916 The semantics of this method revolve around 'fromlist'. When it is
917 empty, the module up to the first dot is to be returned. When the
918 module being requested is an absolute name this is simple (and
919 relative_name is an empty string). But if the requested module was
920 a relative import (as signaled by relative_name having a non-false
921 value), then the name up to the first dot in the relative name resolved
922 to an absolute name is to be returned.
923
924 When fromlist is not empty and the module being imported is a package,
925 then the values
926 in fromlist need to be checked for. If a value is not a pre-existing
927 attribute a relative import is attempted. If it fails then suppressed
928 the failure silently.
929
930 """
931 if not fromlist:
932 if relative_name:
933 absolute_base = absolute_name.rpartition(relative_name)[0]
934 relative_head = relative_name.split('.', 1)[0]
935 to_return = absolute_base + relative_head
936 else:
937 to_return = absolute_name.split('.', 1)[0]
938 return sys.modules[to_return]
939 # When fromlist is not empty, return the actual module specified in
940 # the import.
941 else:
942 module = sys.modules[absolute_name]
943 if hasattr(module, '__path__') and hasattr(module, '__name__'):
944 # When fromlist has a value and the imported module is a
945 # package, then if a name in fromlist is not found as an
946 # attribute on module, try a relative import to find it.
947 # Failure is fine and the exception is suppressed.
948 check_for = list(fromlist)
949 if '*' in check_for and hasattr(module, '__all__'):
950 check_for.extend(module.__all__)
951 for item in check_for:
952 if item == '*':
953 continue
954 if not hasattr(module, item):
955 resolved_name = self._resolve_name(item,
956 module.__name__, 1)
957 try:
958 self._import_full_module(resolved_name)
959 except ImportError:
960 pass
961 return module
962
963 def __call__(self, name, globals={}, locals={}, fromlist=[], level=0):
964 """Import a module.
965
966 The 'name' argument is the name of the module to be imported (e.g.,
967 'foo' in ``import foo`` or ``from foo import ...``).
968
969 'globals' and 'locals' are the global and local namespace dictionaries
970 of the module where the import statement appears. 'globals' is used to
971 introspect the __path__ and __name__ attributes of the module making
972 the call. 'local's is ignored.
973
974 'fromlist' lists any specific objects that are to eventually be put
975 into the namespace (e.g., ``from for.bar import baz`` would have 'baz'
976 in the fromlist, and this includes '*'). An entry of '*' will lead to
977 a check for __all__ being defined on the module. If it is defined then
978 the values in __all__ will be checked to make sure that all values are
979 attributes on the module, attempting a module import relative to 'name'
980 to set that attribute.
981
982 When 'name' is a dotted name, there are two different situations to
983 consider for the return value. One is when the fromlist is empty.
984 In this situation the import statement imports and returns the name up
985 to the first dot. All subsequent names are imported but set as
986 attributes as needed on parent modules. When fromlist is not empty
987 then the module represented by the full dotted name is returned.
988
989 'level' represents possible relative imports.
990 A value of 0 is for absolute module names. Any positive value
991 represents the number of dots listed in the relative import statement
992 (e.g. has a value of 2 for ``from .. import foo``).
993
994 """
Brett Cannon7f9876c2009-02-06 02:47:33 +0000995 # TODO(brett.cannon) outdated check; just care that level >= 0
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000996 if not name and level < 1:
997 raise ValueError("Empty module name")
998 is_pkg = True if '__path__' in globals else False
999 caller_name = globals.get('__name__')
1000 package = globals.get('__package__')
1001 if caller_name and not package:
1002 package = self._find_package(caller_name, '__path__' in globals)
1003 if package and package not in sys.modules:
1004 if not hasattr(package, 'rsplit'):
1005 raise ValueError("__package__ not set to a string")
1006 msg = ("Parent module {0!r} not loaded, "
1007 "cannot perform relative import")
1008 raise SystemError(msg.format(package))
1009 with ImportLockContext():
1010 if level:
1011 imported_name = self._resolve_name(name, package, level)
1012 else:
1013 imported_name = name
1014 parent_name = imported_name.rsplit('.', 1)[0]
1015 if parent_name != imported_name and parent_name not in sys.modules:
1016 self.__call__(parent_name, level=0)
1017 # This call will also handle setting the attribute on the
1018 # package.
1019 self._import_full_module(imported_name)
1020 relative_name = '' if imported_name == name else name
1021 return self._return_module(imported_name, relative_name, fromlist)
1022
1023# XXX Eventually replace with a proper __all__ value (i.e., don't expose os
1024# replacements but do expose _ExtensionFileLoader, etc. for testing).
1025__all__ = [obj for obj in globals().keys() if not obj.startswith('__')]