blob: 068ee1021cc63e4df9c20bd053130614608ead1b [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 Cannon51d8bfc2009-02-07 02:13:28 +000093def wrap(new, old):
94 """Simple substitute for functools.wraps."""
95 for replace in ['__module__', '__name__', '__doc__']:
96 setattr(new, replace, getattr(old, replace))
97 new.__dict__.update(old.__dict__)
98
99
Brett Cannon06c9d962009-02-07 01:52:25 +0000100def set___package__(fxn):
101 """Set __package__ on the returned module."""
102 def wrapper(*args, **kwargs):
103 module = fxn(*args, **kwargs)
104 if not hasattr(module, '__package__') or module.__package__ is None:
105 module.__package__ = module.__name__
106 if not hasattr(module, '__path__'):
107 module.__package__ = module.__package__.rpartition('.')[0]
108 return module
Brett Cannon51d8bfc2009-02-07 02:13:28 +0000109 wrap(wrapper, fxn)
Brett Cannon06c9d962009-02-07 01:52:25 +0000110 return wrapper
111
112
Brett Cannon5abdc932009-01-22 22:43:07 +0000113class BuiltinImporter:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000114
Brett Cannon5abdc932009-01-22 22:43:07 +0000115 """Meta path loader for built-in modules.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000116
Brett Cannon5abdc932009-01-22 22:43:07 +0000117 All methods are either class or static methods, allowing direct use of the
118 class.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000119
120 """
121
Brett Cannon5abdc932009-01-22 22:43:07 +0000122 @classmethod
123 def find_module(cls, fullname, path=None):
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000124 """Try to find the built-in module.
125
126 If 'path' is ever specified then the search is considered a failure.
127
128 """
129 if path is not None:
130 return None
Brett Cannon5abdc932009-01-22 22:43:07 +0000131 return cls if imp.is_builtin(fullname) else None
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000132
Brett Cannon78246b62009-01-25 04:56:30 +0000133 @classmethod
Brett Cannon06c9d962009-02-07 01:52:25 +0000134 @set___package__
Brett Cannon78246b62009-01-25 04:56:30 +0000135 def load_module(cls, fullname):
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000136 """Load a built-in module."""
137 if fullname not in sys.builtin_module_names:
138 raise ImportError("{0} is not a built-in module".format(fullname))
Brett Cannond2e7b332009-02-17 02:45:03 +0000139 is_reload = fullname in sys.modules
140 try:
141 return imp.init_builtin(fullname)
142 except:
143 if not is_reload and fullname in sys.modules:
144 del sys.modules[fullname]
145 raise
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000146
147
Brett Cannon5abdc932009-01-22 22:43:07 +0000148class FrozenImporter:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000149
Brett Cannon5abdc932009-01-22 22:43:07 +0000150 """Meta path class for importing frozen modules.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000151
Brett Cannon5abdc932009-01-22 22:43:07 +0000152 All methods are either class or static method to allow direct use of the
153 class.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000154
Brett Cannon5abdc932009-01-22 22:43:07 +0000155 """
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000156
Brett Cannon5abdc932009-01-22 22:43:07 +0000157 @classmethod
158 def find_module(cls, fullname, path=None):
159 """Find a frozen module."""
160 return cls if imp.is_frozen(fullname) else None
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000161
Brett Cannon5abdc932009-01-22 22:43:07 +0000162 @classmethod
Brett Cannon06c9d962009-02-07 01:52:25 +0000163 @set___package__
Brett Cannon5abdc932009-01-22 22:43:07 +0000164 def load_module(cls, fullname):
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000165 """Load a frozen module."""
Brett Cannon5abdc932009-01-22 22:43:07 +0000166 if cls.find_module(fullname) is None:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000167 raise ImportError("{0} is not a frozen module".format(fullname))
Brett Cannond2e7b332009-02-17 02:45:03 +0000168 is_reload = fullname in sys.modules
169 try:
170 return imp.init_frozen(fullname)
171 except:
172 if not is_reload and fullname in sys.modules:
173 del sys.modules[fullname]
174 raise
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000175
176
Brett Cannon2dee5972009-02-21 03:15:37 +0000177def chained_path_hook(*path_hooks):
178 """Create a closure which sequentially checks path hooks to see which ones
179 (if any) can work with a path."""
180 def path_hook(entry):
181 """Check to see if 'entry' matches any of the enclosed path hooks."""
182 finders = []
183 for hook in path_hooks:
184 try:
185 finder = hook(entry)
186 except ImportError:
187 continue
188 else:
189 finders.append(finder)
190 if not finders:
191 raise ImportError("no finder found")
192 else:
193 return ChainedFinder(*finders)
194
195 return path_hook
196
197
198class ChainedFinder:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000199
200 """Finder that sequentially calls other finders."""
201
Brett Cannon2dee5972009-02-21 03:15:37 +0000202 def __init__(self, *finders):
203 self._finders = finders
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000204
205 def find_module(self, fullname, path=None):
Brett Cannon2dee5972009-02-21 03:15:37 +0000206 for finder in self._finders:
207 result = finder.find_module(fullname, path)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000208 if result:
209 return result
210 else:
211 return None
212
213
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000214def check_name(method):
215 """Decorator to verify that the module being requested matches the one the
216 loader can handle.
217
218 The first argument (self) must define _name which the second argument is
219 comapred against. If the comparison fails then ImportError is raised.
220
221 """
222 def inner(self, name, *args, **kwargs):
223 if self._name != name:
224 raise ImportError("loader cannot handle %s" % name)
225 return method(self, name, *args, **kwargs)
Brett Cannon51d8bfc2009-02-07 02:13:28 +0000226 wrap(inner, method)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000227 return inner
228
229
Brett Cannon2dee5972009-02-21 03:15:37 +0000230class _ExtensionFileLoader:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000231
232 """Loader for extension modules.
233
Brett Cannon2dee5972009-02-21 03:15:37 +0000234 The constructor is designed to work with FileFinder.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000235
236 """
237
238 def __init__(self, name, path, is_pkg):
239 """Initialize the loader.
240
241 If is_pkg is True then an exception is raised as extension modules
242 cannot be the __init__ module for an extension module.
243
244 """
245 self._name = name
246 self._path = path
247 if is_pkg:
248 raise ValueError("extension modules cannot be packages")
249
250 @check_name
Brett Cannon06c9d962009-02-07 01:52:25 +0000251 @set___package__
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000252 def load_module(self, fullname):
253 """Load an extension module."""
Brett Cannond2e7b332009-02-17 02:45:03 +0000254 is_reload = fullname in sys.modules
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000255 try:
256 module = imp.load_dynamic(fullname, self._path)
257 module.__loader__ = self
258 return module
259 except:
Brett Cannond2e7b332009-02-17 02:45:03 +0000260 if not is_reload and fullname in sys.modules:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000261 del sys.modules[fullname]
262 raise
263
264 @check_name
265 def is_package(self, fullname):
266 """Return False as an extension module can never be a package."""
267 return False
268
269 @check_name
270 def get_code(self, fullname):
271 """Return None as an extension module cannot create a code object."""
272 return None
273
274 @check_name
275 def get_source(self, fullname):
276 """Return None as extension modules have no source code."""
277 return None
278
279
280def suffix_list(suffix_type):
281 """Return a list of file suffixes based on the imp file type."""
282 return [suffix[0] for suffix in imp.get_suffixes()
283 if suffix[2] == suffix_type]
284
285
Brett Cannond2e7b332009-02-17 02:45:03 +0000286def module_for_loader(fxn):
287 """Decorator to handle selecting the proper module for loaders.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000288
289 Decorated modules are passed the module to use instead of the module name.
290 The module is either from sys.modules if it already exists (for reloading)
291 or is a new module which has __name__ set. If any exception is raised by
Brett Cannond2e7b332009-02-17 02:45:03 +0000292 the decorated method and the decorator added a module to sys.modules, then
293 the module is deleted from sys.modules.
294
295 The decorator assumes that the decorated method takes self/cls as a first
296 argument and the module as the second argument.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000297
298 """
299 def decorated(self, fullname):
300 module = sys.modules.get(fullname)
301 is_reload = bool(module)
302 if not is_reload:
303 # This must be done before open() is called as the 'io' module
304 # implicitly imports 'locale' and would otherwise trigger an
305 # infinite loop.
306 module = imp.new_module(fullname)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000307 sys.modules[fullname] = module
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000308 try:
309 return fxn(self, module)
310 except:
311 if not is_reload:
312 del sys.modules[fullname]
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000313 raise
Brett Cannon51d8bfc2009-02-07 02:13:28 +0000314 wrap(decorated, fxn)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000315 return decorated
316
317
Brett Cannon2dee5972009-02-21 03:15:37 +0000318class _PyFileLoader:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000319 # XXX Still smart to have this as a separate class? Or would it work
Brett Cannon2dee5972009-02-21 03:15:37 +0000320 # better to integrate with PyFileFinder? Could cache _is_pkg info.
321 # FileFinder can be changed to return self instead of a specific loader
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000322 # call. Otherwise _base_path can be calculated on the fly without issue if
323 # it is known whether a module should be treated as a path or package to
324 # minimize stat calls. Could even go as far as to stat the directory the
325 # importer is in to detect changes and then cache all the info about what
326 # files were found (if stating directories is platform-dependent).
327
328 """Load a Python source or bytecode file."""
329
330 def __init__(self, name, path, is_pkg):
331 self._name = name
332 self._is_pkg = is_pkg
333 # Figure out the base path based on whether it was source or bytecode
334 # that was found.
335 try:
336 self._base_path = _path_without_ext(path, imp.PY_SOURCE)
337 except ValueError:
338 self._base_path = _path_without_ext(path, imp.PY_COMPILED)
339
340 def _find_path(self, ext_type):
341 """Find a path from the base path and the specified extension type that
342 exists, returning None if one is not found."""
343 for suffix in suffix_list(ext_type):
344 path = self._base_path + suffix
345 if _path_exists(path):
346 return path
347 else:
348 return None
349
Brett Cannon51c50262009-02-01 05:33:17 +0000350 @check_name
351 def source_path(self, fullname):
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000352 """Return the path to an existing source file for the module, or None
353 if one cannot be found."""
354 # Not a property so that it is easy to override.
355 return self._find_path(imp.PY_SOURCE)
356
Brett Cannon51c50262009-02-01 05:33:17 +0000357 @check_name
358 def bytecode_path(self, fullname):
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000359 """Return the path to a bytecode file, or None if one does not
360 exist."""
361 # Not a property for easy overriding.
362 return self._find_path(imp.PY_COMPILED)
363
364 @check_name
Brett Cannond2e7b332009-02-17 02:45:03 +0000365 @module_for_loader
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000366 def load_module(self, module):
367 """Load a Python source or bytecode module."""
Brett Cannon51c50262009-02-01 05:33:17 +0000368 name = module.__name__
369 source_path = self.source_path(name)
370 bytecode_path = self.bytecode_path(name)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000371 code_object = self.get_code(module.__name__)
372 module.__file__ = source_path if source_path else bytecode_path
373 module.__loader__ = self
374 if self._is_pkg:
375 module.__path__ = [module.__file__.rsplit(path_sep, 1)[0]]
Brett Cannon06c9d962009-02-07 01:52:25 +0000376 module.__package__ = module.__name__
377 if not hasattr(module, '__path__'):
378 module.__package__ = module.__package__.rpartition('.')[0]
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000379 exec(code_object, module.__dict__)
380 return module
381
382 @check_name
383 def source_mtime(self, name):
384 """Return the modification time of the source for the specified
385 module."""
Brett Cannon51c50262009-02-01 05:33:17 +0000386 source_path = self.source_path(name)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000387 if not source_path:
388 return None
389 return int(_os.stat(source_path).st_mtime)
390
391 @check_name
392 def get_source(self, fullname):
393 """Return the source for the module as a string.
394
395 Return None if the source is not available. Raise ImportError if the
396 laoder cannot handle the specified module.
397
398 """
Brett Cannon51c50262009-02-01 05:33:17 +0000399 source_path = self._source_path(name)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000400 if source_path is None:
401 return None
402 import tokenize
Brett Cannonb4a1b8c2009-01-19 06:56:16 +0000403 with closing(_fileio._FileIO(source_path, 'r')) as file:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000404 encoding, lines = tokenize.detect_encoding(file.readline)
405 # XXX Will fail when passed to compile() if the encoding is
406 # anything other than UTF-8.
407 return open(source_path, encoding=encoding).read()
408
409 @check_name
Brett Cannon776e7012009-02-01 06:07:57 +0000410 def write_bytecode(self, name, data):
411 """Write out 'data' for the specified module, returning a boolean
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000412 signifying if the write-out actually occurred.
413
414 Raises ImportError (just like get_source) if the specified module
415 cannot be handled by the loader.
416
417 """
Brett Cannon51c50262009-02-01 05:33:17 +0000418 bytecode_path = self.bytecode_path(name)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000419 if not bytecode_path:
420 bytecode_path = self._base_path + suffix_list(imp.PY_COMPILED)[0]
421 file = _fileio._FileIO(bytecode_path, 'w')
422 try:
423 with closing(file) as bytecode_file:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000424 bytecode_file.write(data)
425 return True
426 except IOError as exc:
427 if exc.errno == errno.EACCES:
428 return False
429 else:
430 raise
431
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000432 @check_name
433 def get_code(self, name):
Brett Cannon776e7012009-02-01 06:07:57 +0000434 """Return the code object for the module."""
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000435 # XXX Care enough to make sure this call does not happen if the magic
436 # number is bad?
437 source_timestamp = self.source_mtime(name)
438 # Try to use bytecode if it is available.
Brett Cannonba96f0f2009-02-01 05:43:31 +0000439 bytecode_path = self.bytecode_path(name)
440 if bytecode_path:
441 data = self.get_data(bytecode_path)
442 magic = data[:4]
443 pyc_timestamp = marshal._r_long(data[4:8])
444 bytecode = data[8:]
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000445 try:
446 # Verify that the magic number is valid.
447 if imp.get_magic() != magic:
448 raise ImportError("bad magic number")
449 # Verify that the bytecode is not stale (only matters when
450 # there is source to fall back on.
451 if source_timestamp:
452 if pyc_timestamp < source_timestamp:
453 raise ImportError("bytcode is stale")
454 except ImportError:
455 # If source is available give it a shot.
456 if source_timestamp is not None:
457 pass
458 else:
459 raise
460 else:
461 # Bytecode seems fine, so try to use it.
462 # XXX If the bytecode is ill-formed, would it be beneficial to
463 # try for using source if available and issue a warning?
464 return marshal.loads(bytecode)
465 elif source_timestamp is None:
466 raise ImportError("no source or bytecode available to create code "
467 "object for {0!r}".format(name))
468 # Use the source.
Brett Cannonba96f0f2009-02-01 05:43:31 +0000469 source_path = self.source_path(name)
470 source = self.get_data(source_path)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000471 # Convert to universal newlines.
472 line_endings = b'\n'
473 for index, c in enumerate(source):
474 if c == ord(b'\n'):
475 break
476 elif c == ord(b'\r'):
477 line_endings = b'\r'
478 try:
479 if source[index+1] == ord(b'\n'):
480 line_endings += b'\n'
481 except IndexError:
482 pass
483 break
484 if line_endings != b'\n':
485 source = source.replace(line_endings, b'\n')
486 code_object = compile(source, source_path, 'exec', dont_inherit=True)
487 # Generate bytecode and write it out.
488 if not sys.dont_write_bytecode:
Brett Cannon776e7012009-02-01 06:07:57 +0000489 data = bytearray(imp.get_magic())
490 data.extend(marshal._w_long(source_timestamp))
491 data.extend(marshal.dumps(code_object))
492 self.write_bytecode(name, data)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000493 return code_object
494
495 def get_data(self, path):
496 """Return the data from path as raw bytes."""
497 return _fileio._FileIO(path, 'r').read()
498
499 @check_name
500 def is_package(self, fullname):
501 """Return a boolean based on whether the module is a package.
502
503 Raises ImportError (like get_source) if the loader cannot handle the
504 package.
505
506 """
507 return self._is_pkg
508
509
Brett Cannon2dee5972009-02-21 03:15:37 +0000510class FileFinder:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000511
Brett Cannon2dee5972009-02-21 03:15:37 +0000512 """Base class for file finders.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000513
514 Subclasses are expected to define the following attributes:
515
516 * _suffixes
517 Sequence of file suffixes whose order will be followed.
518
519 * _possible_package
520 True if importer should check for packages.
521
522 * _loader
523 A callable that takes the module name, a file path, and whether
524 the path points to a package and returns a loader for the module
525 found at that path.
526
527 """
528
529 def __init__(self, path_entry):
530 """Initialize an importer for the passed-in sys.path entry (which is
531 assumed to have already been verified as an existing directory).
532
533 Can be used as an entry on sys.path_hook.
534
535 """
Brett Cannon2dee5972009-02-21 03:15:37 +0000536 absolute_path = _path_absolute(path_entry)
537 if not _path_isdir(absolute_path):
538 raise ImportError("only directories are supported")
539 self._path_entry = absolute_path
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000540
541 def find_module(self, fullname, path=None):
Brett Cannon2dee5972009-02-21 03:15:37 +0000542 tail_module = fullname.rpartition('.')[2]
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000543 package_directory = None
544 if self._possible_package:
545 for ext in self._suffixes:
546 package_directory = _path_join(self._path_entry, tail_module)
547 init_filename = '__init__' + ext
548 package_init = _path_join(package_directory, init_filename)
549 if (_path_isfile(package_init) and
550 _case_ok(self._path_entry, tail_module) and
551 _case_ok(package_directory, init_filename)):
552 return self._loader(fullname, package_init, True)
553 for ext in self._suffixes:
554 file_name = tail_module + ext
555 file_path = _path_join(self._path_entry, file_name)
556 if (_path_isfile(file_path) and
557 _case_ok(self._path_entry, file_name)):
558 return self._loader(fullname, file_path, False)
559 else:
560 # Raise a warning if it matches a directory w/o an __init__ file.
561 if (package_directory is not None and
562 _path_isdir(package_directory) and
563 _case_ok(self._path_entry, tail_module)):
564 _warnings.warn("Not importing directory %s: missing __init__"
565 % package_directory, ImportWarning)
566 return None
567
568
Brett Cannon2dee5972009-02-21 03:15:37 +0000569class ExtensionFileFinder(FileFinder):
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000570
571 """Importer for extension files."""
572
573 _possible_package = False
574 _loader = _ExtensionFileLoader
575
576 def __init__(self, path_entry):
577 # Assigning to _suffixes here instead of at the class level because
578 # imp is not imported at the time of class creation.
579 self._suffixes = suffix_list(imp.C_EXTENSION)
Brett Cannon2dee5972009-02-21 03:15:37 +0000580 super().__init__(path_entry)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000581
582
Brett Cannon2dee5972009-02-21 03:15:37 +0000583class PyFileFinder(FileFinder):
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000584
585 """Importer for source/bytecode files."""
586
587 _possible_package = True
588 _loader = _PyFileLoader
589
590 def __init__(self, path_entry):
591 # Lack of imp during class creation means _suffixes is set here.
592 # Make sure that Python source files are listed first! Needed for an
593 # optimization by the loader.
594 self._suffixes = suffix_list(imp.PY_SOURCE)
Brett Cannon2dee5972009-02-21 03:15:37 +0000595 super().__init__(path_entry)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000596
597
Brett Cannon4afab6b2009-02-21 03:31:35 +0000598class PyPycFileFinder(PyFileFinder):
599
600 """Finder for source and bytecode files."""
601
602 def __init__(self, path_entry):
603 super().__init__(path_entry)
604 self._suffixes += suffix_list(imp.PY_COMPILED)
605
606
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000607class PathFinder:
Brett Cannon1d376682009-02-02 19:19:36 +0000608
609 """Meta path finder for sys.(path|path_hooks|path_importer_cache)."""
610
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000611 @classmethod
Brett Cannon32732e32009-02-15 05:48:13 +0000612 def _path_hooks(cls, path, hooks=None):
613 """Search sequence of hooks for a finder for 'path'.
Brett Cannon1d376682009-02-02 19:19:36 +0000614
Brett Cannon32732e32009-02-15 05:48:13 +0000615 If 'hooks' is false then use sys.path_hooks.
Brett Cannon1d376682009-02-02 19:19:36 +0000616
617 """
Brett Cannon32732e32009-02-15 05:48:13 +0000618 if not hooks:
619 hooks = sys.path_hooks
620 for hook in hooks:
Brett Cannon1d376682009-02-02 19:19:36 +0000621 try:
622 return hook(path)
623 except ImportError:
624 continue
625 else:
Brett Cannon32732e32009-02-15 05:48:13 +0000626 raise ImportError("no path hook found for {0}".format(path))
Brett Cannon1d376682009-02-02 19:19:36 +0000627
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000628 @classmethod
Brett Cannon32732e32009-02-15 05:48:13 +0000629 def _path_importer_cache(cls, path, default=None):
Brett Cannon1d376682009-02-02 19:19:36 +0000630 """Get the finder for the path from sys.path_importer_cache.
631
632 If the path is not in the cache, find the appropriate finder and cache
633 it. If None is cached, get the default finder and cache that
634 (if applicable).
635
636 Because of NullImporter, some finder should be returned. The only
637 explicit fail case is if None is cached but the path cannot be used for
638 the default hook, for which ImportError is raised.
639
640 """
641 try:
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000642 finder = sys.path_importer_cache[path]
Brett Cannon1d376682009-02-02 19:19:36 +0000643 except KeyError:
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000644 finder = cls._path_hooks(path)
Brett Cannon1d376682009-02-02 19:19:36 +0000645 sys.path_importer_cache[path] = finder
646 else:
Brett Cannon32732e32009-02-15 05:48:13 +0000647 if finder is None and default:
Brett Cannon1d376682009-02-02 19:19:36 +0000648 # Raises ImportError on failure.
Brett Cannon32732e32009-02-15 05:48:13 +0000649 finder = default(path)
Brett Cannon1d376682009-02-02 19:19:36 +0000650 sys.path_importer_cache[path] = finder
651 return finder
652
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000653 @classmethod
654 def find_module(cls, fullname, path=None):
Brett Cannon1d376682009-02-02 19:19:36 +0000655 """Find the module on sys.path or 'path'."""
656 if not path:
657 path = sys.path
658 for entry in path:
659 try:
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000660 finder = cls._path_importer_cache(entry)
Brett Cannon1d376682009-02-02 19:19:36 +0000661 except ImportError:
662 continue
663 loader = finder.find_module(fullname)
664 if loader:
665 return loader
666 else:
667 return None
668
669
Brett Cannon4afab6b2009-02-21 03:31:35 +0000670_DEFAULT_PATH_HOOK = chained_path_hook(ExtensionFileFinder, PyPycFileFinder)
Brett Cannon2dee5972009-02-21 03:15:37 +0000671
Brett Cannon32732e32009-02-15 05:48:13 +0000672class _DefaultPathFinder(PathFinder):
673
674 """Subclass of PathFinder that implements implicit semantics for
675 __import__."""
676
Brett Cannon32732e32009-02-15 05:48:13 +0000677 @classmethod
678 def _path_hooks(cls, path):
679 """Search sys.path_hooks as well as implicit path hooks."""
680 try:
681 return super()._path_hooks(path)
682 except ImportError:
Brett Cannon2dee5972009-02-21 03:15:37 +0000683 implicit_hooks = [_DEFAULT_PATH_HOOK, imp.NullImporter]
Brett Cannon32732e32009-02-15 05:48:13 +0000684 return super()._path_hooks(path, implicit_hooks)
685
686 @classmethod
687 def _path_importer_cache(cls, path):
688 """Use the default path hook when None is stored in
689 sys.path_importer_cache."""
Brett Cannon2dee5972009-02-21 03:15:37 +0000690 return super()._path_importer_cache(path, _DEFAULT_PATH_HOOK)
Brett Cannon32732e32009-02-15 05:48:13 +0000691
692
Brett Cannon2dee5972009-02-21 03:15:37 +0000693class ImportLockContext:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000694
695 """Context manager for the import lock."""
696
697 def __enter__(self):
698 """Acquire the import lock."""
699 imp.acquire_lock()
700
701 def __exit__(self, exc_type, exc_value, exc_traceback):
702 """Release the import lock regardless of any raised exceptions."""
703 imp.release_lock()
704
705
Brett Cannon32732e32009-02-15 05:48:13 +0000706_IMPLICIT_META_PATH = [BuiltinImporter, FrozenImporter, _DefaultPathFinder]
707
Brett Cannon7f9876c2009-02-06 02:47:33 +0000708def _gcd_import(name, package=None, level=0):
709 """Import and return the module based on its name, the package the call is
710 being made from, and the level adjustment.
711
712 This function represents the greatest common denominator of functionality
Brett Cannon2c318a12009-02-07 01:15:27 +0000713 between import_module and __import__. This includes settting __package__ if
714 the loader did not.
715
Brett Cannon7f9876c2009-02-06 02:47:33 +0000716 """
Brett Cannon2c318a12009-02-07 01:15:27 +0000717 if package:
718 if not hasattr(package, 'rindex'):
719 raise ValueError("__package__ not set to a string")
720 elif package not in sys.modules:
721 msg = ("Parent module {0!r} not loaded, cannot perform relative "
722 "import")
723 raise SystemError(msg.format(package))
724 if not name and level == 0:
725 raise ValueError("Empty module name")
Brett Cannon7f9876c2009-02-06 02:47:33 +0000726 if level > 0:
Brett Cannon2c318a12009-02-07 01:15:27 +0000727 dot = len(package)
Brett Cannon7f9876c2009-02-06 02:47:33 +0000728 for x in range(level, 1, -1):
729 try:
730 dot = package.rindex('.', 0, dot)
Brett Cannon7f9876c2009-02-06 02:47:33 +0000731 except ValueError:
Brett Cannon2c318a12009-02-07 01:15:27 +0000732 raise ValueError("attempted relative import beyond "
733 "top-level package")
734 if name:
735 name = "{0}.{1}".format(package[:dot], name)
736 else:
737 name = package[:dot]
Brett Cannon7f9876c2009-02-06 02:47:33 +0000738 with ImportLockContext():
739 try:
740 return sys.modules[name]
741 except KeyError:
742 pass
743 parent = name.rpartition('.')[0]
744 path = None
745 if parent:
746 if parent not in sys.modules:
Brett Cannon2c318a12009-02-07 01:15:27 +0000747 _gcd_import(parent)
748 # Backwards-compatibility; be nicer to skip the dict lookup.
749 parent_module = sys.modules[parent]
Brett Cannon7f9876c2009-02-06 02:47:33 +0000750 path = parent_module.__path__
Brett Cannon32732e32009-02-15 05:48:13 +0000751 meta_path = sys.meta_path + _IMPLICIT_META_PATH
Brett Cannon2c318a12009-02-07 01:15:27 +0000752 for finder in meta_path:
Brett Cannon7f9876c2009-02-06 02:47:33 +0000753 loader = finder.find_module(name, path)
Brett Cannon2c318a12009-02-07 01:15:27 +0000754 if loader is not None:
755 loader.load_module(name)
756 break
Brett Cannon7f9876c2009-02-06 02:47:33 +0000757 else:
758 raise ImportError("No module named {0}".format(name))
Brett Cannon2c318a12009-02-07 01:15:27 +0000759 # Backwards-compatibility; be nicer to skip the dict lookup.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000760 module = sys.modules[name]
761 if parent:
Brett Cannon2c318a12009-02-07 01:15:27 +0000762 # Set the module as an attribute on its parent.
763 setattr(parent_module, name.rpartition('.')[2], module)
764 # Set __package__ if the loader did not.
765 if not hasattr(module, '__package__') or module.__package__ is None:
766 # Watch out for what comes out of sys.modules to not be a module,
767 # e.g. an int.
768 try:
769 module.__package__ = module.__name__
770 if not hasattr(module, '__path__'):
771 module.__package__ = module.__package__.rpartition('.')[0]
772 except AttributeError:
773 pass
774 return module
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000775
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000776
Brett Cannon2c318a12009-02-07 01:15:27 +0000777def _import(name, globals={}, locals={}, fromlist=[], level=0):
778 """Import a module.
779
780 The 'globals' argument is used to infer where the import is occuring from
781 to handle relative imports. The 'locals' argument is ignored. The
782 'fromlist' argument specifies what should exist as attributes on the module
783 being imported (e.g. ``from module import <fromlist>``). The 'level'
784 argument represents the package location to import from in a relative
785 import (e.g. ``from ..pkg import mod`` would have a 'level' of 2).
786
787 """
788 if level == 0:
789 module = _gcd_import(name)
790 else:
791 # __package__ is not guaranteed to be defined.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000792 try:
Brett Cannon2c318a12009-02-07 01:15:27 +0000793 package = globals['__package__']
794 except KeyError:
795 package = globals['__name__']
796 if '__path__' not in globals:
797 package = package.rpartition('.')[0]
798 module = _gcd_import(name, package, level)
799 # The hell that is fromlist ...
800 if not fromlist:
801 # Return up to the first dot in 'name'. This is complicated by the fact
802 # that 'name' may be relative.
803 if level == 0:
804 return sys.modules[name.partition('.')[0]]
805 elif not name:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000806 return module
Brett Cannon2c318a12009-02-07 01:15:27 +0000807 else:
808 cut_off = len(name) - len(name.partition('.')[0])
809 return sys.modules[module.__name__[:-cut_off]]
810 else:
811 # If a package was imported, try to import stuff from fromlist.
812 if hasattr(module, '__path__'):
813 if '*' in fromlist and hasattr(module, '__all__'):
814 fromlist.remove('*')
815 fromlist.extend(module.__all__)
816 for x in (y for y in fromlist if not hasattr(module,y)):
817 try:
818 _gcd_import('{0}.{1}'.format(module.__name__, x))
819 except ImportError:
820 pass
821 return module
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000822
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000823
824# XXX Eventually replace with a proper __all__ value (i.e., don't expose os
825# replacements but do expose _ExtensionFileLoader, etc. for testing).
826__all__ = [obj for obj in globals().keys() if not obj.startswith('__')]