blob: 810f793ff186c3639f5d89ee8a5e2aa07703523f [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 Cannon06c9d962009-02-07 01:52:25 +000093def set___package__(fxn):
94 """Set __package__ on the returned module."""
95 def wrapper(*args, **kwargs):
96 module = fxn(*args, **kwargs)
97 if not hasattr(module, '__package__') or module.__package__ is None:
98 module.__package__ = module.__name__
99 if not hasattr(module, '__path__'):
100 module.__package__ = module.__package__.rpartition('.')[0]
101 return module
102 return wrapper
103
104
Brett Cannon5abdc932009-01-22 22:43:07 +0000105class BuiltinImporter:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000106
Brett Cannon5abdc932009-01-22 22:43:07 +0000107 """Meta path loader for built-in modules.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000108
Brett Cannon5abdc932009-01-22 22:43:07 +0000109 All methods are either class or static methods, allowing direct use of the
110 class.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000111
112 """
113
Brett Cannon5abdc932009-01-22 22:43:07 +0000114 @classmethod
115 def find_module(cls, fullname, path=None):
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000116 """Try to find the built-in module.
117
118 If 'path' is ever specified then the search is considered a failure.
119
120 """
121 if path is not None:
122 return None
Brett Cannon5abdc932009-01-22 22:43:07 +0000123 return cls if imp.is_builtin(fullname) else None
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000124
Brett Cannon78246b62009-01-25 04:56:30 +0000125 @classmethod
Brett Cannon06c9d962009-02-07 01:52:25 +0000126 @set___package__
Brett Cannon78246b62009-01-25 04:56:30 +0000127 def load_module(cls, fullname):
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000128 """Load a built-in module."""
129 if fullname not in sys.builtin_module_names:
130 raise ImportError("{0} is not a built-in module".format(fullname))
Brett Cannond94e5582009-02-07 01:40:19 +0000131 module = imp.init_builtin(fullname)
Brett Cannond94e5582009-02-07 01:40:19 +0000132 return module
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000133
134
Brett Cannon5abdc932009-01-22 22:43:07 +0000135class FrozenImporter:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000136
Brett Cannon5abdc932009-01-22 22:43:07 +0000137 """Meta path class for importing frozen modules.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000138
Brett Cannon5abdc932009-01-22 22:43:07 +0000139 All methods are either class or static method to allow direct use of the
140 class.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000141
Brett Cannon5abdc932009-01-22 22:43:07 +0000142 """
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000143
Brett Cannon5abdc932009-01-22 22:43:07 +0000144 @classmethod
145 def find_module(cls, fullname, path=None):
146 """Find a frozen module."""
147 return cls if imp.is_frozen(fullname) else None
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000148
Brett Cannon5abdc932009-01-22 22:43:07 +0000149 @classmethod
Brett Cannon06c9d962009-02-07 01:52:25 +0000150 @set___package__
Brett Cannon5abdc932009-01-22 22:43:07 +0000151 def load_module(cls, fullname):
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000152 """Load a frozen module."""
Brett Cannon5abdc932009-01-22 22:43:07 +0000153 if cls.find_module(fullname) is None:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000154 raise ImportError("{0} is not a frozen module".format(fullname))
Brett Cannon223a19d2009-02-01 01:34:13 +0000155 module = imp.init_frozen(fullname)
Brett Cannon223a19d2009-02-01 01:34:13 +0000156 return module
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000157
158
159class ChainedImporter(object):
160
161 """Finder that sequentially calls other finders."""
162
163 def __init__(self, *importers):
164 self._importers = importers
165
166 def find_module(self, fullname, path=None):
167 for importer in self._importers:
168 result = importer.find_module(fullname, path)
169 if result:
170 return result
171 else:
172 return None
173
174
175# XXX Don't make filesystem-specific and instead make generic for any path
176# hooks.
177def chaining_fs_path_hook(*path_hooks):
178 """Create a closure which calls the path hooks sequentially looking for
179 which path hooks can handle a path entry.
180
181
182 Passed-in path hooks work as any other path hooks, raising ImportError if
183 they cannot handle the path, otherwise returning a finder.
184
185 """
186 def chained_fs_path_hook(path_entry):
187 """Closure which sees which of the captured path hooks can handle the
188 path entry."""
189 absolute_path = _path_absolute(path_entry)
190 if not _path_isdir(absolute_path):
191 raise ImportError("only directories are supported")
192 accepted = []
193 for path_hook in path_hooks:
194 try:
195 accepted.append(path_hook(absolute_path))
196 except ImportError:
197 continue
198 if not accepted:
199 raise ImportError("no path hooks could handle %s" % path_entry)
200 return ChainedImporter(*accepted)
201 return chained_fs_path_hook
202
203
204def check_name(method):
205 """Decorator to verify that the module being requested matches the one the
206 loader can handle.
207
208 The first argument (self) must define _name which the second argument is
209 comapred against. If the comparison fails then ImportError is raised.
210
211 """
212 def inner(self, name, *args, **kwargs):
213 if self._name != name:
214 raise ImportError("loader cannot handle %s" % name)
215 return method(self, name, *args, **kwargs)
216 inner.__name__ = method.__name__
217 inner.__doc__ = method.__doc__
218 inner.__dict__.update(method.__dict__)
219 return inner
220
221
222class _ExtensionFileLoader(object):
223
224 """Loader for extension modules.
225
226 The constructor is designed to work with FileImporter.
227
228 """
229
230 def __init__(self, name, path, is_pkg):
231 """Initialize the loader.
232
233 If is_pkg is True then an exception is raised as extension modules
234 cannot be the __init__ module for an extension module.
235
236 """
237 self._name = name
238 self._path = path
239 if is_pkg:
240 raise ValueError("extension modules cannot be packages")
241
242 @check_name
Brett Cannon06c9d962009-02-07 01:52:25 +0000243 @set___package__
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000244 def load_module(self, fullname):
245 """Load an extension module."""
246 assert self._name == fullname
247 try:
248 module = imp.load_dynamic(fullname, self._path)
249 module.__loader__ = self
250 return module
251 except:
252 # If an error occurred, don't leave a partially initialized module.
253 if fullname in sys.modules:
254 del sys.modules[fullname]
255 raise
256
257 @check_name
258 def is_package(self, fullname):
259 """Return False as an extension module can never be a package."""
260 return False
261
262 @check_name
263 def get_code(self, fullname):
264 """Return None as an extension module cannot create a code object."""
265 return None
266
267 @check_name
268 def get_source(self, fullname):
269 """Return None as extension modules have no source code."""
270 return None
271
272
273def suffix_list(suffix_type):
274 """Return a list of file suffixes based on the imp file type."""
275 return [suffix[0] for suffix in imp.get_suffixes()
276 if suffix[2] == suffix_type]
277
278
279# XXX Need a better name.
280def get_module(fxn):
281 """Decorator to handle selecting the proper module for load_module
282 implementations.
283
284 Decorated modules are passed the module to use instead of the module name.
285 The module is either from sys.modules if it already exists (for reloading)
286 or is a new module which has __name__ set. If any exception is raised by
287 the decorated method then __loader__, __name__, __file__, and __path__ are
288 all restored on the module to their original values.
289
290 """
291 def decorated(self, fullname):
292 module = sys.modules.get(fullname)
293 is_reload = bool(module)
294 if not is_reload:
295 # This must be done before open() is called as the 'io' module
296 # implicitly imports 'locale' and would otherwise trigger an
297 # infinite loop.
298 module = imp.new_module(fullname)
299 module.__name__ = fullname
300 sys.modules[fullname] = module
301 else:
302 original_values = {}
303 modified_attrs = ['__loader__', '__name__', '__file__', '__path__']
304 for attr in modified_attrs:
305 try:
306 original_values[attr] = getattr(module, attr)
307 except AttributeError:
308 pass
309 try:
310 return fxn(self, module)
311 except:
312 if not is_reload:
313 del sys.modules[fullname]
314 else:
315 for attr in modified_attrs:
316 if attr in original_values:
317 setattr(module, attr, original_values[attr])
318 elif hasattr(module, attr):
319 delattr(module, attr)
320 raise
321 return decorated
322
323
324class _PyFileLoader(object):
325 # XXX Still smart to have this as a separate class? Or would it work
326 # better to integrate with PyFileImporter? Could cache _is_pkg info.
327 # FileImporter can be changed to return self instead of a specific loader
328 # call. Otherwise _base_path can be calculated on the fly without issue if
329 # it is known whether a module should be treated as a path or package to
330 # minimize stat calls. Could even go as far as to stat the directory the
331 # importer is in to detect changes and then cache all the info about what
332 # files were found (if stating directories is platform-dependent).
333
334 """Load a Python source or bytecode file."""
335
336 def __init__(self, name, path, is_pkg):
337 self._name = name
338 self._is_pkg = is_pkg
339 # Figure out the base path based on whether it was source or bytecode
340 # that was found.
341 try:
342 self._base_path = _path_without_ext(path, imp.PY_SOURCE)
343 except ValueError:
344 self._base_path = _path_without_ext(path, imp.PY_COMPILED)
345
346 def _find_path(self, ext_type):
347 """Find a path from the base path and the specified extension type that
348 exists, returning None if one is not found."""
349 for suffix in suffix_list(ext_type):
350 path = self._base_path + suffix
351 if _path_exists(path):
352 return path
353 else:
354 return None
355
Brett Cannon51c50262009-02-01 05:33:17 +0000356 @check_name
357 def source_path(self, fullname):
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000358 """Return the path to an existing source file for the module, or None
359 if one cannot be found."""
360 # Not a property so that it is easy to override.
361 return self._find_path(imp.PY_SOURCE)
362
Brett Cannon51c50262009-02-01 05:33:17 +0000363 @check_name
364 def bytecode_path(self, fullname):
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000365 """Return the path to a bytecode file, or None if one does not
366 exist."""
367 # Not a property for easy overriding.
368 return self._find_path(imp.PY_COMPILED)
369
370 @check_name
371 @get_module
372 def load_module(self, module):
373 """Load a Python source or bytecode module."""
Brett Cannon51c50262009-02-01 05:33:17 +0000374 name = module.__name__
375 source_path = self.source_path(name)
376 bytecode_path = self.bytecode_path(name)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000377 code_object = self.get_code(module.__name__)
378 module.__file__ = source_path if source_path else bytecode_path
379 module.__loader__ = self
380 if self._is_pkg:
381 module.__path__ = [module.__file__.rsplit(path_sep, 1)[0]]
Brett Cannon06c9d962009-02-07 01:52:25 +0000382 module.__package__ = module.__name__
383 if not hasattr(module, '__path__'):
384 module.__package__ = module.__package__.rpartition('.')[0]
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000385 exec(code_object, module.__dict__)
386 return module
387
388 @check_name
389 def source_mtime(self, name):
390 """Return the modification time of the source for the specified
391 module."""
Brett Cannon51c50262009-02-01 05:33:17 +0000392 source_path = self.source_path(name)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000393 if not source_path:
394 return None
395 return int(_os.stat(source_path).st_mtime)
396
397 @check_name
398 def get_source(self, fullname):
399 """Return the source for the module as a string.
400
401 Return None if the source is not available. Raise ImportError if the
402 laoder cannot handle the specified module.
403
404 """
Brett Cannon51c50262009-02-01 05:33:17 +0000405 source_path = self._source_path(name)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000406 if source_path is None:
407 return None
408 import tokenize
Brett Cannonb4a1b8c2009-01-19 06:56:16 +0000409 with closing(_fileio._FileIO(source_path, 'r')) as file:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000410 encoding, lines = tokenize.detect_encoding(file.readline)
411 # XXX Will fail when passed to compile() if the encoding is
412 # anything other than UTF-8.
413 return open(source_path, encoding=encoding).read()
414
415 @check_name
Brett Cannon776e7012009-02-01 06:07:57 +0000416 def write_bytecode(self, name, data):
417 """Write out 'data' for the specified module, returning a boolean
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000418 signifying if the write-out actually occurred.
419
420 Raises ImportError (just like get_source) if the specified module
421 cannot be handled by the loader.
422
423 """
Brett Cannon51c50262009-02-01 05:33:17 +0000424 bytecode_path = self.bytecode_path(name)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000425 if not bytecode_path:
426 bytecode_path = self._base_path + suffix_list(imp.PY_COMPILED)[0]
427 file = _fileio._FileIO(bytecode_path, 'w')
428 try:
429 with closing(file) as bytecode_file:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000430 bytecode_file.write(data)
431 return True
432 except IOError as exc:
433 if exc.errno == errno.EACCES:
434 return False
435 else:
436 raise
437
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000438 @check_name
439 def get_code(self, name):
Brett Cannon776e7012009-02-01 06:07:57 +0000440 """Return the code object for the module."""
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000441 # XXX Care enough to make sure this call does not happen if the magic
442 # number is bad?
443 source_timestamp = self.source_mtime(name)
444 # Try to use bytecode if it is available.
Brett Cannonba96f0f2009-02-01 05:43:31 +0000445 bytecode_path = self.bytecode_path(name)
446 if bytecode_path:
447 data = self.get_data(bytecode_path)
448 magic = data[:4]
449 pyc_timestamp = marshal._r_long(data[4:8])
450 bytecode = data[8:]
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000451 try:
452 # Verify that the magic number is valid.
453 if imp.get_magic() != magic:
454 raise ImportError("bad magic number")
455 # Verify that the bytecode is not stale (only matters when
456 # there is source to fall back on.
457 if source_timestamp:
458 if pyc_timestamp < source_timestamp:
459 raise ImportError("bytcode is stale")
460 except ImportError:
461 # If source is available give it a shot.
462 if source_timestamp is not None:
463 pass
464 else:
465 raise
466 else:
467 # Bytecode seems fine, so try to use it.
468 # XXX If the bytecode is ill-formed, would it be beneficial to
469 # try for using source if available and issue a warning?
470 return marshal.loads(bytecode)
471 elif source_timestamp is None:
472 raise ImportError("no source or bytecode available to create code "
473 "object for {0!r}".format(name))
474 # Use the source.
Brett Cannonba96f0f2009-02-01 05:43:31 +0000475 source_path = self.source_path(name)
476 source = self.get_data(source_path)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000477 # Convert to universal newlines.
478 line_endings = b'\n'
479 for index, c in enumerate(source):
480 if c == ord(b'\n'):
481 break
482 elif c == ord(b'\r'):
483 line_endings = b'\r'
484 try:
485 if source[index+1] == ord(b'\n'):
486 line_endings += b'\n'
487 except IndexError:
488 pass
489 break
490 if line_endings != b'\n':
491 source = source.replace(line_endings, b'\n')
492 code_object = compile(source, source_path, 'exec', dont_inherit=True)
493 # Generate bytecode and write it out.
494 if not sys.dont_write_bytecode:
Brett Cannon776e7012009-02-01 06:07:57 +0000495 data = bytearray(imp.get_magic())
496 data.extend(marshal._w_long(source_timestamp))
497 data.extend(marshal.dumps(code_object))
498 self.write_bytecode(name, data)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000499 return code_object
500
501 def get_data(self, path):
502 """Return the data from path as raw bytes."""
503 return _fileio._FileIO(path, 'r').read()
504
505 @check_name
506 def is_package(self, fullname):
507 """Return a boolean based on whether the module is a package.
508
509 Raises ImportError (like get_source) if the loader cannot handle the
510 package.
511
512 """
513 return self._is_pkg
514
515
516class FileImporter(object):
517
518 """Base class for file importers.
519
520 Subclasses are expected to define the following attributes:
521
522 * _suffixes
523 Sequence of file suffixes whose order will be followed.
524
525 * _possible_package
526 True if importer should check for packages.
527
528 * _loader
529 A callable that takes the module name, a file path, and whether
530 the path points to a package and returns a loader for the module
531 found at that path.
532
533 """
534
535 def __init__(self, path_entry):
536 """Initialize an importer for the passed-in sys.path entry (which is
537 assumed to have already been verified as an existing directory).
538
539 Can be used as an entry on sys.path_hook.
540
541 """
542 self._path_entry = path_entry
543
544 def find_module(self, fullname, path=None):
545 tail_module = fullname.rsplit('.', 1)[-1]
546 package_directory = None
547 if self._possible_package:
548 for ext in self._suffixes:
549 package_directory = _path_join(self._path_entry, tail_module)
550 init_filename = '__init__' + ext
551 package_init = _path_join(package_directory, init_filename)
552 if (_path_isfile(package_init) and
553 _case_ok(self._path_entry, tail_module) and
554 _case_ok(package_directory, init_filename)):
555 return self._loader(fullname, package_init, True)
556 for ext in self._suffixes:
557 file_name = tail_module + ext
558 file_path = _path_join(self._path_entry, file_name)
559 if (_path_isfile(file_path) and
560 _case_ok(self._path_entry, file_name)):
561 return self._loader(fullname, file_path, False)
562 else:
563 # Raise a warning if it matches a directory w/o an __init__ file.
564 if (package_directory is not None and
565 _path_isdir(package_directory) and
566 _case_ok(self._path_entry, tail_module)):
567 _warnings.warn("Not importing directory %s: missing __init__"
568 % package_directory, ImportWarning)
569 return None
570
571
572class ExtensionFileImporter(FileImporter):
573
574 """Importer for extension files."""
575
576 _possible_package = False
577 _loader = _ExtensionFileLoader
578
579 def __init__(self, path_entry):
580 # Assigning to _suffixes here instead of at the class level because
581 # imp is not imported at the time of class creation.
582 self._suffixes = suffix_list(imp.C_EXTENSION)
583 super(ExtensionFileImporter, self).__init__(path_entry)
584
585
586class PyFileImporter(FileImporter):
587
588 """Importer for source/bytecode files."""
589
590 _possible_package = True
591 _loader = _PyFileLoader
592
593 def __init__(self, path_entry):
594 # Lack of imp during class creation means _suffixes is set here.
595 # Make sure that Python source files are listed first! Needed for an
596 # optimization by the loader.
597 self._suffixes = suffix_list(imp.PY_SOURCE)
598 self._suffixes += suffix_list(imp.PY_COMPILED)
599 super(PyFileImporter, self).__init__(path_entry)
600
601
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000602class PathFinder:
Brett Cannon1d376682009-02-02 19:19:36 +0000603
604 """Meta path finder for sys.(path|path_hooks|path_importer_cache)."""
605
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000606 _default_hook = staticmethod(chaining_fs_path_hook(ExtensionFileImporter,
607 PyFileImporter))
Brett Cannon1d376682009-02-02 19:19:36 +0000608
609 # The list of implicit hooks cannot be a class attribute because of
610 # bootstrapping issues for accessing imp.
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000611 @classmethod
612 def _implicit_hooks(cls):
Brett Cannon1d376682009-02-02 19:19:36 +0000613 """Return a list of the implicit path hooks."""
Brett Cannon1f9bcd32009-02-05 23:36:02 +0000614 return [cls._default_hook, imp.NullImporter]
Brett Cannon1d376682009-02-02 19:19:36 +0000615
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000616 @classmethod
617 def _path_hooks(cls, path):
Brett Cannon1d376682009-02-02 19:19:36 +0000618 """Search sys.path_hooks for a finder for 'path'.
619
620 Guaranteed to return a finder for the path as NullImporter is the
621 default importer for any path that does not have an explicit finder.
622
623 """
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000624 for hook in sys.path_hooks + cls._implicit_hooks():
Brett Cannon1d376682009-02-02 19:19:36 +0000625 try:
626 return hook(path)
627 except ImportError:
628 continue
629 else:
630 # This point should never be reached thanks to NullImporter.
631 raise SystemError("no hook could find an importer for "
632 "{0}".format(path))
633
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000634 @classmethod
635 def _path_importer_cache(cls, path):
Brett Cannon1d376682009-02-02 19:19:36 +0000636 """Get the finder for the path from sys.path_importer_cache.
637
638 If the path is not in the cache, find the appropriate finder and cache
639 it. If None is cached, get the default finder and cache that
640 (if applicable).
641
642 Because of NullImporter, some finder should be returned. The only
643 explicit fail case is if None is cached but the path cannot be used for
644 the default hook, for which ImportError is raised.
645
646 """
647 try:
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000648 finder = sys.path_importer_cache[path]
Brett Cannon1d376682009-02-02 19:19:36 +0000649 except KeyError:
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000650 finder = cls._path_hooks(path)
Brett Cannon1d376682009-02-02 19:19:36 +0000651 sys.path_importer_cache[path] = finder
652 else:
653 if finder is None:
654 # Raises ImportError on failure.
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000655 finder = cls._default_hook(path)
Brett Cannon1d376682009-02-02 19:19:36 +0000656 sys.path_importer_cache[path] = finder
657 return finder
658
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000659 @classmethod
660 def find_module(cls, fullname, path=None):
Brett Cannon1d376682009-02-02 19:19:36 +0000661 """Find the module on sys.path or 'path'."""
662 if not path:
663 path = sys.path
664 for entry in path:
665 try:
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000666 finder = cls._path_importer_cache(entry)
Brett Cannon1d376682009-02-02 19:19:36 +0000667 except ImportError:
668 continue
669 loader = finder.find_module(fullname)
670 if loader:
671 return loader
672 else:
673 return None
674
675
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000676class ImportLockContext(object):
677
678 """Context manager for the import lock."""
679
680 def __enter__(self):
681 """Acquire the import lock."""
682 imp.acquire_lock()
683
684 def __exit__(self, exc_type, exc_value, exc_traceback):
685 """Release the import lock regardless of any raised exceptions."""
686 imp.release_lock()
687
688
Brett Cannon7f9876c2009-02-06 02:47:33 +0000689def _gcd_import(name, package=None, level=0):
690 """Import and return the module based on its name, the package the call is
691 being made from, and the level adjustment.
692
693 This function represents the greatest common denominator of functionality
Brett Cannon2c318a12009-02-07 01:15:27 +0000694 between import_module and __import__. This includes settting __package__ if
695 the loader did not.
696
Brett Cannon7f9876c2009-02-06 02:47:33 +0000697 """
Brett Cannon2c318a12009-02-07 01:15:27 +0000698 if package:
699 if not hasattr(package, 'rindex'):
700 raise ValueError("__package__ not set to a string")
701 elif package not in sys.modules:
702 msg = ("Parent module {0!r} not loaded, cannot perform relative "
703 "import")
704 raise SystemError(msg.format(package))
705 if not name and level == 0:
706 raise ValueError("Empty module name")
Brett Cannon7f9876c2009-02-06 02:47:33 +0000707 if level > 0:
Brett Cannon2c318a12009-02-07 01:15:27 +0000708 dot = len(package)
Brett Cannon7f9876c2009-02-06 02:47:33 +0000709 for x in range(level, 1, -1):
710 try:
711 dot = package.rindex('.', 0, dot)
Brett Cannon7f9876c2009-02-06 02:47:33 +0000712 except ValueError:
Brett Cannon2c318a12009-02-07 01:15:27 +0000713 raise ValueError("attempted relative import beyond "
714 "top-level package")
715 if name:
716 name = "{0}.{1}".format(package[:dot], name)
717 else:
718 name = package[:dot]
Brett Cannon7f9876c2009-02-06 02:47:33 +0000719 with ImportLockContext():
720 try:
721 return sys.modules[name]
722 except KeyError:
723 pass
724 parent = name.rpartition('.')[0]
725 path = None
726 if parent:
727 if parent not in sys.modules:
Brett Cannon2c318a12009-02-07 01:15:27 +0000728 _gcd_import(parent)
729 # Backwards-compatibility; be nicer to skip the dict lookup.
730 parent_module = sys.modules[parent]
Brett Cannon7f9876c2009-02-06 02:47:33 +0000731 path = parent_module.__path__
Brett Cannon2c318a12009-02-07 01:15:27 +0000732 meta_path = (sys.meta_path +
733 [BuiltinImporter, FrozenImporter, PathFinder])
734 for finder in meta_path:
Brett Cannon7f9876c2009-02-06 02:47:33 +0000735 loader = finder.find_module(name, path)
Brett Cannon2c318a12009-02-07 01:15:27 +0000736 if loader is not None:
737 loader.load_module(name)
738 break
Brett Cannon7f9876c2009-02-06 02:47:33 +0000739 else:
740 raise ImportError("No module named {0}".format(name))
Brett Cannon2c318a12009-02-07 01:15:27 +0000741 # Backwards-compatibility; be nicer to skip the dict lookup.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000742 module = sys.modules[name]
743 if parent:
Brett Cannon2c318a12009-02-07 01:15:27 +0000744 # Set the module as an attribute on its parent.
745 setattr(parent_module, name.rpartition('.')[2], module)
746 # Set __package__ if the loader did not.
747 if not hasattr(module, '__package__') or module.__package__ is None:
748 # Watch out for what comes out of sys.modules to not be a module,
749 # e.g. an int.
750 try:
751 module.__package__ = module.__name__
752 if not hasattr(module, '__path__'):
753 module.__package__ = module.__package__.rpartition('.')[0]
754 except AttributeError:
755 pass
756 return module
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000757
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000758
Brett Cannon2c318a12009-02-07 01:15:27 +0000759def _import(name, globals={}, locals={}, fromlist=[], level=0):
760 """Import a module.
761
762 The 'globals' argument is used to infer where the import is occuring from
763 to handle relative imports. The 'locals' argument is ignored. The
764 'fromlist' argument specifies what should exist as attributes on the module
765 being imported (e.g. ``from module import <fromlist>``). The 'level'
766 argument represents the package location to import from in a relative
767 import (e.g. ``from ..pkg import mod`` would have a 'level' of 2).
768
769 """
770 if level == 0:
771 module = _gcd_import(name)
772 else:
773 # __package__ is not guaranteed to be defined.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000774 try:
Brett Cannon2c318a12009-02-07 01:15:27 +0000775 package = globals['__package__']
776 except KeyError:
777 package = globals['__name__']
778 if '__path__' not in globals:
779 package = package.rpartition('.')[0]
780 module = _gcd_import(name, package, level)
781 # The hell that is fromlist ...
782 if not fromlist:
783 # Return up to the first dot in 'name'. This is complicated by the fact
784 # that 'name' may be relative.
785 if level == 0:
786 return sys.modules[name.partition('.')[0]]
787 elif not name:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000788 return module
Brett Cannon2c318a12009-02-07 01:15:27 +0000789 else:
790 cut_off = len(name) - len(name.partition('.')[0])
791 return sys.modules[module.__name__[:-cut_off]]
792 else:
793 # If a package was imported, try to import stuff from fromlist.
794 if hasattr(module, '__path__'):
795 if '*' in fromlist and hasattr(module, '__all__'):
796 fromlist.remove('*')
797 fromlist.extend(module.__all__)
798 for x in (y for y in fromlist if not hasattr(module,y)):
799 try:
800 _gcd_import('{0}.{1}'.format(module.__name__, x))
801 except ImportError:
802 pass
803 return module
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000804
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000805
806# XXX Eventually replace with a proper __all__ value (i.e., don't expose os
807# replacements but do expose _ExtensionFileLoader, etc. for testing).
808__all__ = [obj for obj in globals().keys() if not obj.startswith('__')]