blob: a2a29cca9f118cfa2458d158a6660e6f24c88cc4 [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
Brett Cannon7c9875c2009-03-04 01:10:09 +000010# Injected modules are '_warnings', 'imp', 'sys', 'marshal', 'errno', '_io',
11# and '_os' (a.k.a. 'posix', 'nt' or 'os2').
Brett Cannon23cbd8a2009-01-18 00:24:28 +000012# 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 Cannon91cf8822009-02-21 05:41:15 +0000318class PyLoader:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000319
Brett Cannon91cf8822009-02-21 05:41:15 +0000320 """Loader base class for Python source.
321
322 Requires implementing the optional PEP 302 protocols as well as
Brett Cannon94aaf9e2009-02-21 23:12:24 +0000323 source_path.
Brett Cannon91cf8822009-02-21 05:41:15 +0000324
325 """
326
327 @module_for_loader
328 def load_module(self, module):
329 """Load a source module."""
330 return _load_module(module)
331
332 def _load_module(self, module):
333 """Initialize a module from source."""
334 name = module.__name__
335 source_path = self.source_path(name)
336 code_object = self.get_code(module.__name__)
337 if not hasattr(module, '__file__'):
338 module.__file__ = source_path
339 if self.is_package(name):
340 module.__path__ = [module.__file__.rsplit(path_sep, 1)[0]]
341 module.__package__ = module.__name__
342 if not hasattr(module, '__path__'):
343 module.__package__ = module.__package__.rpartition('.')[0]
344 exec(code_object, module.__dict__)
345 return module
346
347 def get_code(self, fullname):
348 """Get a code object from source."""
349 source_path = self.source_path(fullname)
350 source = self.get_data(source_path)
351 # Convert to universal newlines.
352 line_endings = b'\n'
353 for index, c in enumerate(source):
354 if c == ord(b'\n'):
355 break
356 elif c == ord(b'\r'):
357 line_endings = b'\r'
358 try:
359 if source[index+1] == ord(b'\n'):
360 line_endings += b'\n'
361 except IndexError:
362 pass
363 break
364 if line_endings != b'\n':
365 source = source.replace(line_endings, b'\n')
366 return compile(source, source_path, 'exec', dont_inherit=True)
367
368
369class PyPycLoader(PyLoader):
370
371 """Loader base class for Python source and bytecode.
372
373 Requires implementing the methods needed for PyLoader as well as
Brett Cannon94aaf9e2009-02-21 23:12:24 +0000374 source_mtime, bytecode_path, and write_bytecode.
Brett Cannon91cf8822009-02-21 05:41:15 +0000375
376 """
377
378 @module_for_loader
379 def load_module(self, module):
380 """Load a module from source or bytecode."""
381 name = module.__name__
382 source_path = self.source_path(name)
383 bytecode_path = self.bytecode_path(name)
384 module.__file__ = source_path if source_path else bytecode_path
385 return self._load_module(module)
386
387 def get_code(self, fullname):
388 """Get a code object from source or bytecode."""
389 # XXX Care enough to make sure this call does not happen if the magic
390 # number is bad?
391 source_timestamp = self.source_mtime(fullname)
392 # Try to use bytecode if it is available.
393 bytecode_path = self.bytecode_path(fullname)
394 if bytecode_path:
395 data = self.get_data(bytecode_path)
396 magic = data[:4]
397 pyc_timestamp = marshal._r_long(data[4:8])
398 bytecode = data[8:]
399 try:
400 # Verify that the magic number is valid.
401 if imp.get_magic() != magic:
402 raise ImportError("bad magic number")
403 # Verify that the bytecode is not stale (only matters when
404 # there is source to fall back on.
405 if source_timestamp:
406 if pyc_timestamp < source_timestamp:
407 raise ImportError("bytecode is stale")
408 except ImportError:
409 # If source is available give it a shot.
410 if source_timestamp is not None:
411 pass
412 else:
413 raise
414 else:
415 # Bytecode seems fine, so try to use it.
416 # XXX If the bytecode is ill-formed, would it be beneficial to
417 # try for using source if available and issue a warning?
418 return marshal.loads(bytecode)
419 elif source_timestamp is None:
420 raise ImportError("no source or bytecode available to create code "
421 "object for {0!r}".format(fullname))
422 # Use the source.
423 code_object = super().get_code(fullname)
424 # Generate bytecode and write it out.
425 if not sys.dont_write_bytecode:
426 data = bytearray(imp.get_magic())
427 data.extend(marshal._w_long(source_timestamp))
428 data.extend(marshal.dumps(code_object))
429 self.write_bytecode(fullname, data)
430 return code_object
431
432
433class PyFileLoader(PyLoader):
434
435 """Load a Python source file."""
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000436
437 def __init__(self, name, path, is_pkg):
438 self._name = name
439 self._is_pkg = is_pkg
440 # Figure out the base path based on whether it was source or bytecode
441 # that was found.
442 try:
443 self._base_path = _path_without_ext(path, imp.PY_SOURCE)
444 except ValueError:
445 self._base_path = _path_without_ext(path, imp.PY_COMPILED)
446
447 def _find_path(self, ext_type):
448 """Find a path from the base path and the specified extension type that
449 exists, returning None if one is not found."""
450 for suffix in suffix_list(ext_type):
451 path = self._base_path + suffix
452 if _path_exists(path):
453 return path
454 else:
455 return None
456
Brett Cannon51c50262009-02-01 05:33:17 +0000457 @check_name
458 def source_path(self, fullname):
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000459 """Return the path to an existing source file for the module, or None
460 if one cannot be found."""
461 # Not a property so that it is easy to override.
462 return self._find_path(imp.PY_SOURCE)
463
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000464 @check_name
465 def get_source(self, fullname):
466 """Return the source for the module as a string.
467
468 Return None if the source is not available. Raise ImportError if the
469 laoder cannot handle the specified module.
470
471 """
Brett Cannon51c50262009-02-01 05:33:17 +0000472 source_path = self._source_path(name)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000473 if source_path is None:
474 return None
475 import tokenize
Brett Cannon7c9875c2009-03-04 01:10:09 +0000476 with closing(_io.FileIO(source_path, 'r')) as file: # Assuming bytes.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000477 encoding, lines = tokenize.detect_encoding(file.readline)
478 # XXX Will fail when passed to compile() if the encoding is
479 # anything other than UTF-8.
480 return open(source_path, encoding=encoding).read()
481
Brett Cannon91cf8822009-02-21 05:41:15 +0000482
483 def get_data(self, path):
484 """Return the data from path as raw bytes."""
Brett Cannon7c9875c2009-03-04 01:10:09 +0000485 return _io.FileIO(path, 'r').read() # Assuming bytes.
Brett Cannon91cf8822009-02-21 05:41:15 +0000486
487 @check_name
488 def is_package(self, fullname):
489 """Return a boolean based on whether the module is a package.
490
491 Raises ImportError (like get_source) if the loader cannot handle the
492 package.
493
494 """
495 return self._is_pkg
496
497
Brett Cannon91cf8822009-02-21 05:41:15 +0000498class PyPycFileLoader(PyPycLoader, PyFileLoader):
499
500 """Load a module from a source or bytecode file."""
501
502 @check_name
Brett Cannon94aaf9e2009-02-21 23:12:24 +0000503 def source_mtime(self, name):
504 """Return the modification time of the source for the specified
505 module."""
506 source_path = self.source_path(name)
507 if not source_path:
508 return None
509 return int(_os.stat(source_path).st_mtime)
510
511 @check_name
Brett Cannon91cf8822009-02-21 05:41:15 +0000512 def bytecode_path(self, fullname):
513 """Return the path to a bytecode file, or None if one does not
514 exist."""
515 # Not a property for easy overriding.
516 return self._find_path(imp.PY_COMPILED)
517
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000518 @check_name
Brett Cannon776e7012009-02-01 06:07:57 +0000519 def write_bytecode(self, name, data):
520 """Write out 'data' for the specified module, returning a boolean
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000521 signifying if the write-out actually occurred.
522
523 Raises ImportError (just like get_source) if the specified module
524 cannot be handled by the loader.
525
526 """
Brett Cannon51c50262009-02-01 05:33:17 +0000527 bytecode_path = self.bytecode_path(name)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000528 if not bytecode_path:
529 bytecode_path = self._base_path + suffix_list(imp.PY_COMPILED)[0]
Brett Cannon7c9875c2009-03-04 01:10:09 +0000530 file = _io.FileIO(bytecode_path, 'w') # Assuming bytes.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000531 try:
532 with closing(file) as bytecode_file:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000533 bytecode_file.write(data)
534 return True
535 except IOError as exc:
536 if exc.errno == errno.EACCES:
537 return False
538 else:
539 raise
540
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000541
Brett Cannon2dee5972009-02-21 03:15:37 +0000542class FileFinder:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000543
Brett Cannon2dee5972009-02-21 03:15:37 +0000544 """Base class for file finders.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000545
546 Subclasses are expected to define the following attributes:
547
548 * _suffixes
549 Sequence of file suffixes whose order will be followed.
550
551 * _possible_package
552 True if importer should check for packages.
553
554 * _loader
555 A callable that takes the module name, a file path, and whether
556 the path points to a package and returns a loader for the module
557 found at that path.
558
559 """
560
561 def __init__(self, path_entry):
562 """Initialize an importer for the passed-in sys.path entry (which is
563 assumed to have already been verified as an existing directory).
564
565 Can be used as an entry on sys.path_hook.
566
567 """
Brett Cannon2dee5972009-02-21 03:15:37 +0000568 absolute_path = _path_absolute(path_entry)
569 if not _path_isdir(absolute_path):
570 raise ImportError("only directories are supported")
571 self._path_entry = absolute_path
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000572
573 def find_module(self, fullname, path=None):
Brett Cannon2dee5972009-02-21 03:15:37 +0000574 tail_module = fullname.rpartition('.')[2]
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000575 package_directory = None
576 if self._possible_package:
577 for ext in self._suffixes:
578 package_directory = _path_join(self._path_entry, tail_module)
579 init_filename = '__init__' + ext
580 package_init = _path_join(package_directory, init_filename)
581 if (_path_isfile(package_init) and
582 _case_ok(self._path_entry, tail_module) and
583 _case_ok(package_directory, init_filename)):
584 return self._loader(fullname, package_init, True)
585 for ext in self._suffixes:
586 file_name = tail_module + ext
587 file_path = _path_join(self._path_entry, file_name)
588 if (_path_isfile(file_path) and
589 _case_ok(self._path_entry, file_name)):
590 return self._loader(fullname, file_path, False)
591 else:
592 # Raise a warning if it matches a directory w/o an __init__ file.
593 if (package_directory is not None and
594 _path_isdir(package_directory) and
595 _case_ok(self._path_entry, tail_module)):
596 _warnings.warn("Not importing directory %s: missing __init__"
597 % package_directory, ImportWarning)
598 return None
599
600
Brett Cannon2dee5972009-02-21 03:15:37 +0000601class ExtensionFileFinder(FileFinder):
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000602
603 """Importer for extension files."""
604
605 _possible_package = False
606 _loader = _ExtensionFileLoader
607
608 def __init__(self, path_entry):
609 # Assigning to _suffixes here instead of at the class level because
610 # imp is not imported at the time of class creation.
611 self._suffixes = suffix_list(imp.C_EXTENSION)
Brett Cannon2dee5972009-02-21 03:15:37 +0000612 super().__init__(path_entry)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000613
614
Brett Cannon2dee5972009-02-21 03:15:37 +0000615class PyFileFinder(FileFinder):
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000616
617 """Importer for source/bytecode files."""
618
619 _possible_package = True
Brett Cannon91cf8822009-02-21 05:41:15 +0000620 _loader = PyFileLoader
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000621
622 def __init__(self, path_entry):
623 # Lack of imp during class creation means _suffixes is set here.
624 # Make sure that Python source files are listed first! Needed for an
625 # optimization by the loader.
626 self._suffixes = suffix_list(imp.PY_SOURCE)
Brett Cannon2dee5972009-02-21 03:15:37 +0000627 super().__init__(path_entry)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000628
629
Brett Cannon4afab6b2009-02-21 03:31:35 +0000630class PyPycFileFinder(PyFileFinder):
631
632 """Finder for source and bytecode files."""
633
Brett Cannon91cf8822009-02-21 05:41:15 +0000634 _loader = PyPycFileLoader
635
Brett Cannon4afab6b2009-02-21 03:31:35 +0000636 def __init__(self, path_entry):
637 super().__init__(path_entry)
638 self._suffixes += suffix_list(imp.PY_COMPILED)
639
640
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000641class PathFinder:
Brett Cannon1d376682009-02-02 19:19:36 +0000642
643 """Meta path finder for sys.(path|path_hooks|path_importer_cache)."""
644
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000645 @classmethod
Brett Cannon32732e32009-02-15 05:48:13 +0000646 def _path_hooks(cls, path, hooks=None):
647 """Search sequence of hooks for a finder for 'path'.
Brett Cannon1d376682009-02-02 19:19:36 +0000648
Brett Cannon32732e32009-02-15 05:48:13 +0000649 If 'hooks' is false then use sys.path_hooks.
Brett Cannon1d376682009-02-02 19:19:36 +0000650
651 """
Brett Cannon32732e32009-02-15 05:48:13 +0000652 if not hooks:
653 hooks = sys.path_hooks
654 for hook in hooks:
Brett Cannon1d376682009-02-02 19:19:36 +0000655 try:
656 return hook(path)
657 except ImportError:
658 continue
659 else:
Brett Cannon32732e32009-02-15 05:48:13 +0000660 raise ImportError("no path hook found for {0}".format(path))
Brett Cannon1d376682009-02-02 19:19:36 +0000661
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000662 @classmethod
Brett Cannon32732e32009-02-15 05:48:13 +0000663 def _path_importer_cache(cls, path, default=None):
Brett Cannon1d376682009-02-02 19:19:36 +0000664 """Get the finder for the path from sys.path_importer_cache.
665
666 If the path is not in the cache, find the appropriate finder and cache
667 it. If None is cached, get the default finder and cache that
668 (if applicable).
669
670 Because of NullImporter, some finder should be returned. The only
671 explicit fail case is if None is cached but the path cannot be used for
672 the default hook, for which ImportError is raised.
673
674 """
675 try:
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000676 finder = sys.path_importer_cache[path]
Brett Cannon1d376682009-02-02 19:19:36 +0000677 except KeyError:
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000678 finder = cls._path_hooks(path)
Brett Cannon1d376682009-02-02 19:19:36 +0000679 sys.path_importer_cache[path] = finder
680 else:
Brett Cannon32732e32009-02-15 05:48:13 +0000681 if finder is None and default:
Brett Cannon1d376682009-02-02 19:19:36 +0000682 # Raises ImportError on failure.
Brett Cannon32732e32009-02-15 05:48:13 +0000683 finder = default(path)
Brett Cannon1d376682009-02-02 19:19:36 +0000684 sys.path_importer_cache[path] = finder
685 return finder
686
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000687 @classmethod
688 def find_module(cls, fullname, path=None):
Brett Cannon1d376682009-02-02 19:19:36 +0000689 """Find the module on sys.path or 'path'."""
690 if not path:
691 path = sys.path
692 for entry in path:
693 try:
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000694 finder = cls._path_importer_cache(entry)
Brett Cannon1d376682009-02-02 19:19:36 +0000695 except ImportError:
696 continue
697 loader = finder.find_module(fullname)
698 if loader:
699 return loader
700 else:
701 return None
702
703
Brett Cannon4afab6b2009-02-21 03:31:35 +0000704_DEFAULT_PATH_HOOK = chained_path_hook(ExtensionFileFinder, PyPycFileFinder)
Brett Cannon2dee5972009-02-21 03:15:37 +0000705
Brett Cannon32732e32009-02-15 05:48:13 +0000706class _DefaultPathFinder(PathFinder):
707
708 """Subclass of PathFinder that implements implicit semantics for
709 __import__."""
710
Brett Cannon32732e32009-02-15 05:48:13 +0000711 @classmethod
712 def _path_hooks(cls, path):
713 """Search sys.path_hooks as well as implicit path hooks."""
714 try:
715 return super()._path_hooks(path)
716 except ImportError:
Brett Cannon2dee5972009-02-21 03:15:37 +0000717 implicit_hooks = [_DEFAULT_PATH_HOOK, imp.NullImporter]
Brett Cannon32732e32009-02-15 05:48:13 +0000718 return super()._path_hooks(path, implicit_hooks)
719
720 @classmethod
721 def _path_importer_cache(cls, path):
722 """Use the default path hook when None is stored in
723 sys.path_importer_cache."""
Brett Cannon2dee5972009-02-21 03:15:37 +0000724 return super()._path_importer_cache(path, _DEFAULT_PATH_HOOK)
Brett Cannon32732e32009-02-15 05:48:13 +0000725
726
Brett Cannon2dee5972009-02-21 03:15:37 +0000727class ImportLockContext:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000728
729 """Context manager for the import lock."""
730
731 def __enter__(self):
732 """Acquire the import lock."""
733 imp.acquire_lock()
734
735 def __exit__(self, exc_type, exc_value, exc_traceback):
736 """Release the import lock regardless of any raised exceptions."""
737 imp.release_lock()
738
739
Brett Cannon32732e32009-02-15 05:48:13 +0000740_IMPLICIT_META_PATH = [BuiltinImporter, FrozenImporter, _DefaultPathFinder]
741
Brett Cannon7f9876c2009-02-06 02:47:33 +0000742def _gcd_import(name, package=None, level=0):
743 """Import and return the module based on its name, the package the call is
744 being made from, and the level adjustment.
745
746 This function represents the greatest common denominator of functionality
Brett Cannon2c318a12009-02-07 01:15:27 +0000747 between import_module and __import__. This includes settting __package__ if
748 the loader did not.
749
Brett Cannon7f9876c2009-02-06 02:47:33 +0000750 """
Brett Cannon2c318a12009-02-07 01:15:27 +0000751 if package:
752 if not hasattr(package, 'rindex'):
753 raise ValueError("__package__ not set to a string")
754 elif package not in sys.modules:
755 msg = ("Parent module {0!r} not loaded, cannot perform relative "
756 "import")
757 raise SystemError(msg.format(package))
758 if not name and level == 0:
759 raise ValueError("Empty module name")
Brett Cannon7f9876c2009-02-06 02:47:33 +0000760 if level > 0:
Brett Cannon2c318a12009-02-07 01:15:27 +0000761 dot = len(package)
Brett Cannon7f9876c2009-02-06 02:47:33 +0000762 for x in range(level, 1, -1):
763 try:
764 dot = package.rindex('.', 0, dot)
Brett Cannon7f9876c2009-02-06 02:47:33 +0000765 except ValueError:
Brett Cannon2c318a12009-02-07 01:15:27 +0000766 raise ValueError("attempted relative import beyond "
767 "top-level package")
768 if name:
769 name = "{0}.{1}".format(package[:dot], name)
770 else:
771 name = package[:dot]
Brett Cannon7f9876c2009-02-06 02:47:33 +0000772 with ImportLockContext():
773 try:
774 return sys.modules[name]
775 except KeyError:
776 pass
777 parent = name.rpartition('.')[0]
778 path = None
779 if parent:
780 if parent not in sys.modules:
Brett Cannon2c318a12009-02-07 01:15:27 +0000781 _gcd_import(parent)
782 # Backwards-compatibility; be nicer to skip the dict lookup.
783 parent_module = sys.modules[parent]
Brett Cannon7f9876c2009-02-06 02:47:33 +0000784 path = parent_module.__path__
Brett Cannon32732e32009-02-15 05:48:13 +0000785 meta_path = sys.meta_path + _IMPLICIT_META_PATH
Brett Cannon2c318a12009-02-07 01:15:27 +0000786 for finder in meta_path:
Brett Cannon7f9876c2009-02-06 02:47:33 +0000787 loader = finder.find_module(name, path)
Brett Cannon2c318a12009-02-07 01:15:27 +0000788 if loader is not None:
789 loader.load_module(name)
790 break
Brett Cannon7f9876c2009-02-06 02:47:33 +0000791 else:
792 raise ImportError("No module named {0}".format(name))
Brett Cannon2c318a12009-02-07 01:15:27 +0000793 # Backwards-compatibility; be nicer to skip the dict lookup.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000794 module = sys.modules[name]
795 if parent:
Brett Cannon2c318a12009-02-07 01:15:27 +0000796 # Set the module as an attribute on its parent.
797 setattr(parent_module, name.rpartition('.')[2], module)
798 # Set __package__ if the loader did not.
799 if not hasattr(module, '__package__') or module.__package__ is None:
800 # Watch out for what comes out of sys.modules to not be a module,
801 # e.g. an int.
802 try:
803 module.__package__ = module.__name__
804 if not hasattr(module, '__path__'):
805 module.__package__ = module.__package__.rpartition('.')[0]
806 except AttributeError:
807 pass
808 return module
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000809
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000810
Brett Cannon2c318a12009-02-07 01:15:27 +0000811def _import(name, globals={}, locals={}, fromlist=[], level=0):
812 """Import a module.
813
814 The 'globals' argument is used to infer where the import is occuring from
815 to handle relative imports. The 'locals' argument is ignored. The
816 'fromlist' argument specifies what should exist as attributes on the module
817 being imported (e.g. ``from module import <fromlist>``). The 'level'
818 argument represents the package location to import from in a relative
819 import (e.g. ``from ..pkg import mod`` would have a 'level' of 2).
820
821 """
822 if level == 0:
823 module = _gcd_import(name)
824 else:
825 # __package__ is not guaranteed to be defined.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000826 try:
Brett Cannon2c318a12009-02-07 01:15:27 +0000827 package = globals['__package__']
828 except KeyError:
829 package = globals['__name__']
830 if '__path__' not in globals:
831 package = package.rpartition('.')[0]
832 module = _gcd_import(name, package, level)
833 # The hell that is fromlist ...
834 if not fromlist:
835 # Return up to the first dot in 'name'. This is complicated by the fact
836 # that 'name' may be relative.
837 if level == 0:
838 return sys.modules[name.partition('.')[0]]
839 elif not name:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000840 return module
Brett Cannon2c318a12009-02-07 01:15:27 +0000841 else:
842 cut_off = len(name) - len(name.partition('.')[0])
843 return sys.modules[module.__name__[:-cut_off]]
844 else:
845 # If a package was imported, try to import stuff from fromlist.
846 if hasattr(module, '__path__'):
847 if '*' in fromlist and hasattr(module, '__all__'):
848 fromlist.remove('*')
849 fromlist.extend(module.__all__)
850 for x in (y for y in fromlist if not hasattr(module,y)):
851 try:
852 _gcd_import('{0}.{1}'.format(module.__name__, x))
853 except ImportError:
854 pass
855 return module
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000856
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000857
858# XXX Eventually replace with a proper __all__ value (i.e., don't expose os
859# replacements but do expose _ExtensionFileLoader, etc. for testing).
860__all__ = [obj for obj in globals().keys() if not obj.startswith('__')]