blob: 0e59aa1c55cc169c4a934182980ab77ab9beedd7 [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]."""
Brett Cannon3eeaa0a2009-03-12 22:07:17 +000059 for suffix in _suffix_list(ext_type):
Brett Cannon23cbd8a2009-01-18 00:24:28 +000060 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
Brett Cannon3eeaa0a2009-03-12 22:07:17 +000079class _closing:
Brett Cannon23cbd8a2009-01-18 00:24:28 +000080
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 Cannon3eeaa0a2009-03-12 22:07:17 +000093def _wrap(new, old):
Brett Cannon51d8bfc2009-02-07 02:13:28 +000094 """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 Cannon435aad82009-03-04 16:07:00 +0000100def set_package(fxn):
Brett Cannon06c9d962009-02-07 01:52:25 +0000101 """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 Cannon3eeaa0a2009-03-12 22:07:17 +0000109 _wrap(wrapper, fxn)
Brett Cannon06c9d962009-02-07 01:52:25 +0000110 return wrapper
111
112
Brett Cannon2cf03a82009-03-10 05:17:37 +0000113def set_loader(fxn):
114 """Set __loader__ on the returned module."""
115 def wrapper(self, *args, **kwargs):
116 module = fxn(self, *args, **kwargs)
117 if not hasattr(module, '__loader__'):
118 module.__loader__ = self
119 return module
Brett Cannon3eeaa0a2009-03-12 22:07:17 +0000120 _wrap(wrapper, fxn)
Brett Cannon2cf03a82009-03-10 05:17:37 +0000121 return wrapper
122
123
Brett Cannon5abdc932009-01-22 22:43:07 +0000124class BuiltinImporter:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000125
Brett Cannon5abdc932009-01-22 22:43:07 +0000126 """Meta path loader for built-in modules.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000127
Brett Cannon5abdc932009-01-22 22:43:07 +0000128 All methods are either class or static methods, allowing direct use of the
129 class.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000130
131 """
132
Brett Cannon5abdc932009-01-22 22:43:07 +0000133 @classmethod
134 def find_module(cls, fullname, path=None):
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000135 """Try to find the built-in module.
136
137 If 'path' is ever specified then the search is considered a failure.
138
139 """
140 if path is not None:
141 return None
Brett Cannon5abdc932009-01-22 22:43:07 +0000142 return cls if imp.is_builtin(fullname) else None
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000143
Brett Cannon78246b62009-01-25 04:56:30 +0000144 @classmethod
Brett Cannon435aad82009-03-04 16:07:00 +0000145 @set_package
Brett Cannon2cf03a82009-03-10 05:17:37 +0000146 @set_loader
Brett Cannon78246b62009-01-25 04:56:30 +0000147 def load_module(cls, fullname):
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000148 """Load a built-in module."""
149 if fullname not in sys.builtin_module_names:
150 raise ImportError("{0} is not a built-in module".format(fullname))
Brett Cannond2e7b332009-02-17 02:45:03 +0000151 is_reload = fullname in sys.modules
152 try:
153 return imp.init_builtin(fullname)
154 except:
155 if not is_reload and fullname in sys.modules:
156 del sys.modules[fullname]
157 raise
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000158
159
Brett Cannon5abdc932009-01-22 22:43:07 +0000160class FrozenImporter:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000161
Brett Cannon5abdc932009-01-22 22:43:07 +0000162 """Meta path class for importing frozen modules.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000163
Brett Cannon5abdc932009-01-22 22:43:07 +0000164 All methods are either class or static method to allow direct use of the
165 class.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000166
Brett Cannon5abdc932009-01-22 22:43:07 +0000167 """
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000168
Brett Cannon5abdc932009-01-22 22:43:07 +0000169 @classmethod
170 def find_module(cls, fullname, path=None):
171 """Find a frozen module."""
172 return cls if imp.is_frozen(fullname) else None
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000173
Brett Cannon5abdc932009-01-22 22:43:07 +0000174 @classmethod
Brett Cannon435aad82009-03-04 16:07:00 +0000175 @set_package
Brett Cannon2cf03a82009-03-10 05:17:37 +0000176 @set_loader
Brett Cannon5abdc932009-01-22 22:43:07 +0000177 def load_module(cls, fullname):
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000178 """Load a frozen module."""
Brett Cannon5abdc932009-01-22 22:43:07 +0000179 if cls.find_module(fullname) is None:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000180 raise ImportError("{0} is not a frozen module".format(fullname))
Brett Cannond2e7b332009-02-17 02:45:03 +0000181 is_reload = fullname in sys.modules
182 try:
183 return imp.init_frozen(fullname)
184 except:
185 if not is_reload and fullname in sys.modules:
186 del sys.modules[fullname]
187 raise
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000188
189
Brett Cannon3eeaa0a2009-03-12 22:07:17 +0000190def _chained_path_hook(*path_hooks):
Brett Cannon2dee5972009-02-21 03:15:37 +0000191 """Create a closure which sequentially checks path hooks to see which ones
192 (if any) can work with a path."""
193 def path_hook(entry):
194 """Check to see if 'entry' matches any of the enclosed path hooks."""
195 finders = []
196 for hook in path_hooks:
197 try:
198 finder = hook(entry)
199 except ImportError:
200 continue
201 else:
202 finders.append(finder)
203 if not finders:
204 raise ImportError("no finder found")
205 else:
Brett Cannon3eeaa0a2009-03-12 22:07:17 +0000206 return _ChainedFinder(*finders)
Brett Cannon2dee5972009-02-21 03:15:37 +0000207
208 return path_hook
209
210
Brett Cannon3eeaa0a2009-03-12 22:07:17 +0000211class _ChainedFinder:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000212
213 """Finder that sequentially calls other finders."""
214
Brett Cannon2dee5972009-02-21 03:15:37 +0000215 def __init__(self, *finders):
216 self._finders = finders
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000217
218 def find_module(self, fullname, path=None):
Brett Cannon2dee5972009-02-21 03:15:37 +0000219 for finder in self._finders:
220 result = finder.find_module(fullname, path)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000221 if result:
222 return result
223 else:
224 return None
225
226
Brett Cannon3eeaa0a2009-03-12 22:07:17 +0000227def _check_name(method):
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000228 """Decorator to verify that the module being requested matches the one the
229 loader can handle.
230
231 The first argument (self) must define _name which the second argument is
232 comapred against. If the comparison fails then ImportError is raised.
233
234 """
235 def inner(self, name, *args, **kwargs):
236 if self._name != name:
237 raise ImportError("loader cannot handle %s" % name)
238 return method(self, name, *args, **kwargs)
Brett Cannon3eeaa0a2009-03-12 22:07:17 +0000239 _wrap(inner, method)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000240 return inner
241
242
Brett Cannon2dee5972009-02-21 03:15:37 +0000243class _ExtensionFileLoader:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000244
245 """Loader for extension modules.
246
Brett Cannon2dee5972009-02-21 03:15:37 +0000247 The constructor is designed to work with FileFinder.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000248
249 """
250
251 def __init__(self, name, path, is_pkg):
252 """Initialize the loader.
253
254 If is_pkg is True then an exception is raised as extension modules
255 cannot be the __init__ module for an extension module.
256
257 """
258 self._name = name
259 self._path = path
260 if is_pkg:
261 raise ValueError("extension modules cannot be packages")
262
Brett Cannon3eeaa0a2009-03-12 22:07:17 +0000263 @_check_name
Brett Cannon435aad82009-03-04 16:07:00 +0000264 @set_package
Brett Cannon2cf03a82009-03-10 05:17:37 +0000265 @set_loader
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000266 def load_module(self, fullname):
267 """Load an extension module."""
Brett Cannond2e7b332009-02-17 02:45:03 +0000268 is_reload = fullname in sys.modules
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000269 try:
Brett Cannon2cf03a82009-03-10 05:17:37 +0000270 return imp.load_dynamic(fullname, self._path)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000271 except:
Brett Cannond2e7b332009-02-17 02:45:03 +0000272 if not is_reload and fullname in sys.modules:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000273 del sys.modules[fullname]
274 raise
275
Brett Cannon3eeaa0a2009-03-12 22:07:17 +0000276 @_check_name
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000277 def is_package(self, fullname):
278 """Return False as an extension module can never be a package."""
279 return False
280
Brett Cannon3eeaa0a2009-03-12 22:07:17 +0000281 @_check_name
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000282 def get_code(self, fullname):
283 """Return None as an extension module cannot create a code object."""
284 return None
285
Brett Cannon3eeaa0a2009-03-12 22:07:17 +0000286 @_check_name
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000287 def get_source(self, fullname):
288 """Return None as extension modules have no source code."""
289 return None
290
291
Brett Cannon3eeaa0a2009-03-12 22:07:17 +0000292def _suffix_list(suffix_type):
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000293 """Return a list of file suffixes based on the imp file type."""
294 return [suffix[0] for suffix in imp.get_suffixes()
295 if suffix[2] == suffix_type]
296
297
Brett Cannond2e7b332009-02-17 02:45:03 +0000298def module_for_loader(fxn):
299 """Decorator to handle selecting the proper module for loaders.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000300
301 Decorated modules are passed the module to use instead of the module name.
302 The module is either from sys.modules if it already exists (for reloading)
303 or is a new module which has __name__ set. If any exception is raised by
Brett Cannond2e7b332009-02-17 02:45:03 +0000304 the decorated method and the decorator added a module to sys.modules, then
305 the module is deleted from sys.modules.
306
307 The decorator assumes that the decorated method takes self/cls as a first
308 argument and the module as the second argument.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000309
310 """
311 def decorated(self, fullname):
312 module = sys.modules.get(fullname)
313 is_reload = bool(module)
314 if not is_reload:
315 # This must be done before open() is called as the 'io' module
316 # implicitly imports 'locale' and would otherwise trigger an
317 # infinite loop.
318 module = imp.new_module(fullname)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000319 sys.modules[fullname] = module
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000320 try:
321 return fxn(self, module)
322 except:
323 if not is_reload:
324 del sys.modules[fullname]
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000325 raise
Brett Cannon3eeaa0a2009-03-12 22:07:17 +0000326 _wrap(decorated, fxn)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000327 return decorated
328
329
Brett Cannon91cf8822009-02-21 05:41:15 +0000330class PyLoader:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000331
Brett Cannon91cf8822009-02-21 05:41:15 +0000332 """Loader base class for Python source.
333
334 Requires implementing the optional PEP 302 protocols as well as
Brett Cannon94aaf9e2009-02-21 23:12:24 +0000335 source_path.
Brett Cannon91cf8822009-02-21 05:41:15 +0000336
337 """
338
339 @module_for_loader
340 def load_module(self, module):
341 """Load a source module."""
Brett Cannon1014d422009-03-08 20:53:50 +0000342 return self._load_module(module)
Brett Cannon91cf8822009-02-21 05:41:15 +0000343
344 def _load_module(self, module):
345 """Initialize a module from source."""
346 name = module.__name__
Brett Cannon91cf8822009-02-21 05:41:15 +0000347 code_object = self.get_code(module.__name__)
Brett Cannon1014d422009-03-08 20:53:50 +0000348 # __file__ may have been set by the caller, e.g. bytecode path.
Brett Cannon91cf8822009-02-21 05:41:15 +0000349 if not hasattr(module, '__file__'):
Brett Cannon1014d422009-03-08 20:53:50 +0000350 module.__file__ = self.source_path(name)
Brett Cannon91cf8822009-02-21 05:41:15 +0000351 if self.is_package(name):
352 module.__path__ = [module.__file__.rsplit(path_sep, 1)[0]]
353 module.__package__ = module.__name__
354 if not hasattr(module, '__path__'):
355 module.__package__ = module.__package__.rpartition('.')[0]
Brett Cannon1014d422009-03-08 20:53:50 +0000356 module.__loader__ = self
Brett Cannon91cf8822009-02-21 05:41:15 +0000357 exec(code_object, module.__dict__)
358 return module
359
360 def get_code(self, fullname):
361 """Get a code object from source."""
362 source_path = self.source_path(fullname)
Brett Cannon1014d422009-03-08 20:53:50 +0000363 if source_path is None:
364 message = "a source path must exist to load {0}".format(fullname)
365 raise ImportError(message)
Brett Cannon91cf8822009-02-21 05:41:15 +0000366 source = self.get_data(source_path)
367 # Convert to universal newlines.
368 line_endings = b'\n'
369 for index, c in enumerate(source):
370 if c == ord(b'\n'):
371 break
372 elif c == ord(b'\r'):
373 line_endings = b'\r'
374 try:
375 if source[index+1] == ord(b'\n'):
376 line_endings += b'\n'
377 except IndexError:
378 pass
379 break
380 if line_endings != b'\n':
381 source = source.replace(line_endings, b'\n')
382 return compile(source, source_path, 'exec', dont_inherit=True)
383
Brett Cannond43b30b2009-03-10 03:29:23 +0000384 # Never use in implementing import! Imports code within the method.
385 def get_source(self, fullname):
386 """Return the source code for a module.
387
388 self.source_path() and self.get_data() are used to implement this
389 method.
390
391 """
392 path = self.source_path(fullname)
393 if path is None:
394 return None
395 try:
396 source_bytes = self.get_data(path)
397 except IOError:
398 return ImportError("source not available through get_data()")
399 import io
400 import tokenize
401 encoding = tokenize.detect_encoding(io.BytesIO(source_bytes).readline)
402 return source_bytes.decode(encoding[0])
403
Brett Cannon91cf8822009-02-21 05:41:15 +0000404
405class PyPycLoader(PyLoader):
406
407 """Loader base class for Python source and bytecode.
408
409 Requires implementing the methods needed for PyLoader as well as
Brett Cannon94aaf9e2009-02-21 23:12:24 +0000410 source_mtime, bytecode_path, and write_bytecode.
Brett Cannon91cf8822009-02-21 05:41:15 +0000411
412 """
413
414 @module_for_loader
415 def load_module(self, module):
416 """Load a module from source or bytecode."""
417 name = module.__name__
Brett Cannon2a922ed2009-03-09 03:35:50 +0000418 source_path = self.source_path(name)
419 bytecode_path = self.bytecode_path(name)
Brett Cannon29dff8a2009-03-09 00:14:37 +0000420 # get_code can worry about no viable paths existing.
421 module.__file__ = source_path or bytecode_path
Brett Cannon91cf8822009-02-21 05:41:15 +0000422 return self._load_module(module)
423
424 def get_code(self, fullname):
425 """Get a code object from source or bytecode."""
426 # XXX Care enough to make sure this call does not happen if the magic
427 # number is bad?
428 source_timestamp = self.source_mtime(fullname)
429 # Try to use bytecode if it is available.
430 bytecode_path = self.bytecode_path(fullname)
431 if bytecode_path:
432 data = self.get_data(bytecode_path)
433 magic = data[:4]
434 pyc_timestamp = marshal._r_long(data[4:8])
435 bytecode = data[8:]
436 try:
437 # Verify that the magic number is valid.
438 if imp.get_magic() != magic:
439 raise ImportError("bad magic number")
440 # Verify that the bytecode is not stale (only matters when
441 # there is source to fall back on.
442 if source_timestamp:
443 if pyc_timestamp < source_timestamp:
444 raise ImportError("bytecode is stale")
445 except ImportError:
446 # If source is available give it a shot.
447 if source_timestamp is not None:
448 pass
449 else:
450 raise
451 else:
452 # Bytecode seems fine, so try to use it.
453 # XXX If the bytecode is ill-formed, would it be beneficial to
454 # try for using source if available and issue a warning?
455 return marshal.loads(bytecode)
456 elif source_timestamp is None:
457 raise ImportError("no source or bytecode available to create code "
458 "object for {0!r}".format(fullname))
459 # Use the source.
460 code_object = super().get_code(fullname)
461 # Generate bytecode and write it out.
462 if not sys.dont_write_bytecode:
463 data = bytearray(imp.get_magic())
464 data.extend(marshal._w_long(source_timestamp))
465 data.extend(marshal.dumps(code_object))
466 self.write_bytecode(fullname, data)
467 return code_object
468
469
470class PyFileLoader(PyLoader):
471
472 """Load a Python source file."""
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000473
474 def __init__(self, name, path, is_pkg):
475 self._name = name
476 self._is_pkg = is_pkg
477 # Figure out the base path based on whether it was source or bytecode
478 # that was found.
479 try:
480 self._base_path = _path_without_ext(path, imp.PY_SOURCE)
481 except ValueError:
482 self._base_path = _path_without_ext(path, imp.PY_COMPILED)
483
484 def _find_path(self, ext_type):
485 """Find a path from the base path and the specified extension type that
486 exists, returning None if one is not found."""
Brett Cannon3eeaa0a2009-03-12 22:07:17 +0000487 for suffix in _suffix_list(ext_type):
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000488 path = self._base_path + suffix
489 if _path_exists(path):
490 return path
491 else:
492 return None
493
Brett Cannon3eeaa0a2009-03-12 22:07:17 +0000494 @_check_name
Brett Cannon51c50262009-02-01 05:33:17 +0000495 def source_path(self, fullname):
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000496 """Return the path to an existing source file for the module, or None
497 if one cannot be found."""
498 # Not a property so that it is easy to override.
499 return self._find_path(imp.PY_SOURCE)
500
Brett Cannon3eeaa0a2009-03-12 22:07:17 +0000501 @_check_name
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000502 def get_source(self, fullname):
503 """Return the source for the module as a string.
504
505 Return None if the source is not available. Raise ImportError if the
506 laoder cannot handle the specified module.
507
508 """
Brett Cannon51c50262009-02-01 05:33:17 +0000509 source_path = self._source_path(name)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000510 if source_path is None:
511 return None
512 import tokenize
Brett Cannon3eeaa0a2009-03-12 22:07:17 +0000513 with _closing(_io.FileIO(source_path, 'r')) as file: # Assuming bytes.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000514 encoding, lines = tokenize.detect_encoding(file.readline)
515 # XXX Will fail when passed to compile() if the encoding is
516 # anything other than UTF-8.
517 return open(source_path, encoding=encoding).read()
518
Brett Cannon91cf8822009-02-21 05:41:15 +0000519
520 def get_data(self, path):
521 """Return the data from path as raw bytes."""
Brett Cannon7c9875c2009-03-04 01:10:09 +0000522 return _io.FileIO(path, 'r').read() # Assuming bytes.
Brett Cannon91cf8822009-02-21 05:41:15 +0000523
Brett Cannon3eeaa0a2009-03-12 22:07:17 +0000524 @_check_name
Brett Cannon91cf8822009-02-21 05:41:15 +0000525 def is_package(self, fullname):
526 """Return a boolean based on whether the module is a package.
527
528 Raises ImportError (like get_source) if the loader cannot handle the
529 package.
530
531 """
532 return self._is_pkg
533
534
Brett Cannon91cf8822009-02-21 05:41:15 +0000535class PyPycFileLoader(PyPycLoader, PyFileLoader):
536
537 """Load a module from a source or bytecode file."""
538
Brett Cannon3eeaa0a2009-03-12 22:07:17 +0000539 @_check_name
Brett Cannon94aaf9e2009-02-21 23:12:24 +0000540 def source_mtime(self, name):
541 """Return the modification time of the source for the specified
542 module."""
543 source_path = self.source_path(name)
544 if not source_path:
545 return None
546 return int(_os.stat(source_path).st_mtime)
547
Brett Cannon3eeaa0a2009-03-12 22:07:17 +0000548 @_check_name
Brett Cannon91cf8822009-02-21 05:41:15 +0000549 def bytecode_path(self, fullname):
550 """Return the path to a bytecode file, or None if one does not
551 exist."""
552 # Not a property for easy overriding.
553 return self._find_path(imp.PY_COMPILED)
554
Brett Cannon3eeaa0a2009-03-12 22:07:17 +0000555 @_check_name
Brett Cannon776e7012009-02-01 06:07:57 +0000556 def write_bytecode(self, name, data):
557 """Write out 'data' for the specified module, returning a boolean
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000558 signifying if the write-out actually occurred.
559
560 Raises ImportError (just like get_source) if the specified module
561 cannot be handled by the loader.
562
563 """
Brett Cannon51c50262009-02-01 05:33:17 +0000564 bytecode_path = self.bytecode_path(name)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000565 if not bytecode_path:
Brett Cannon3eeaa0a2009-03-12 22:07:17 +0000566 bytecode_path = self._base_path + _suffix_list(imp.PY_COMPILED)[0]
Brett Cannon7c9875c2009-03-04 01:10:09 +0000567 file = _io.FileIO(bytecode_path, 'w') # Assuming bytes.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000568 try:
Brett Cannon3eeaa0a2009-03-12 22:07:17 +0000569 with _closing(file) as bytecode_file:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000570 bytecode_file.write(data)
571 return True
572 except IOError as exc:
573 if exc.errno == errno.EACCES:
574 return False
575 else:
576 raise
577
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000578
Brett Cannon2dee5972009-02-21 03:15:37 +0000579class FileFinder:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000580
Brett Cannon2dee5972009-02-21 03:15:37 +0000581 """Base class for file finders.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000582
583 Subclasses are expected to define the following attributes:
584
585 * _suffixes
586 Sequence of file suffixes whose order will be followed.
587
588 * _possible_package
589 True if importer should check for packages.
590
591 * _loader
592 A callable that takes the module name, a file path, and whether
593 the path points to a package and returns a loader for the module
594 found at that path.
595
596 """
597
598 def __init__(self, path_entry):
599 """Initialize an importer for the passed-in sys.path entry (which is
600 assumed to have already been verified as an existing directory).
601
602 Can be used as an entry on sys.path_hook.
603
604 """
Brett Cannon2dee5972009-02-21 03:15:37 +0000605 absolute_path = _path_absolute(path_entry)
606 if not _path_isdir(absolute_path):
607 raise ImportError("only directories are supported")
608 self._path_entry = absolute_path
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000609
610 def find_module(self, fullname, path=None):
Brett Cannon2dee5972009-02-21 03:15:37 +0000611 tail_module = fullname.rpartition('.')[2]
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000612 package_directory = None
613 if self._possible_package:
614 for ext in self._suffixes:
615 package_directory = _path_join(self._path_entry, tail_module)
616 init_filename = '__init__' + ext
617 package_init = _path_join(package_directory, init_filename)
618 if (_path_isfile(package_init) and
619 _case_ok(self._path_entry, tail_module) and
620 _case_ok(package_directory, init_filename)):
621 return self._loader(fullname, package_init, True)
622 for ext in self._suffixes:
623 file_name = tail_module + ext
624 file_path = _path_join(self._path_entry, file_name)
625 if (_path_isfile(file_path) and
626 _case_ok(self._path_entry, file_name)):
627 return self._loader(fullname, file_path, False)
628 else:
629 # Raise a warning if it matches a directory w/o an __init__ file.
630 if (package_directory is not None and
631 _path_isdir(package_directory) and
632 _case_ok(self._path_entry, tail_module)):
633 _warnings.warn("Not importing directory %s: missing __init__"
634 % package_directory, ImportWarning)
635 return None
636
637
Brett Cannon2dee5972009-02-21 03:15:37 +0000638class ExtensionFileFinder(FileFinder):
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000639
640 """Importer for extension files."""
641
642 _possible_package = False
643 _loader = _ExtensionFileLoader
644
645 def __init__(self, path_entry):
646 # Assigning to _suffixes here instead of at the class level because
647 # imp is not imported at the time of class creation.
Brett Cannon3eeaa0a2009-03-12 22:07:17 +0000648 self._suffixes = _suffix_list(imp.C_EXTENSION)
Brett Cannon2dee5972009-02-21 03:15:37 +0000649 super().__init__(path_entry)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000650
651
Brett Cannon2dee5972009-02-21 03:15:37 +0000652class PyFileFinder(FileFinder):
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000653
654 """Importer for source/bytecode files."""
655
656 _possible_package = True
Brett Cannon91cf8822009-02-21 05:41:15 +0000657 _loader = PyFileLoader
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000658
659 def __init__(self, path_entry):
660 # Lack of imp during class creation means _suffixes is set here.
661 # Make sure that Python source files are listed first! Needed for an
662 # optimization by the loader.
Brett Cannon3eeaa0a2009-03-12 22:07:17 +0000663 self._suffixes = _suffix_list(imp.PY_SOURCE)
Brett Cannon2dee5972009-02-21 03:15:37 +0000664 super().__init__(path_entry)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000665
666
Brett Cannon4afab6b2009-02-21 03:31:35 +0000667class PyPycFileFinder(PyFileFinder):
668
669 """Finder for source and bytecode files."""
670
Brett Cannon91cf8822009-02-21 05:41:15 +0000671 _loader = PyPycFileLoader
672
Brett Cannon4afab6b2009-02-21 03:31:35 +0000673 def __init__(self, path_entry):
674 super().__init__(path_entry)
Brett Cannon3eeaa0a2009-03-12 22:07:17 +0000675 self._suffixes += _suffix_list(imp.PY_COMPILED)
Brett Cannon4afab6b2009-02-21 03:31:35 +0000676
677
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000678class PathFinder:
Brett Cannon1d376682009-02-02 19:19:36 +0000679
680 """Meta path finder for sys.(path|path_hooks|path_importer_cache)."""
681
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000682 @classmethod
Brett Cannon32732e32009-02-15 05:48:13 +0000683 def _path_hooks(cls, path, hooks=None):
684 """Search sequence of hooks for a finder for 'path'.
Brett Cannon1d376682009-02-02 19:19:36 +0000685
Brett Cannon32732e32009-02-15 05:48:13 +0000686 If 'hooks' is false then use sys.path_hooks.
Brett Cannon1d376682009-02-02 19:19:36 +0000687
688 """
Brett Cannon32732e32009-02-15 05:48:13 +0000689 if not hooks:
690 hooks = sys.path_hooks
691 for hook in hooks:
Brett Cannon1d376682009-02-02 19:19:36 +0000692 try:
693 return hook(path)
694 except ImportError:
695 continue
696 else:
Brett Cannon32732e32009-02-15 05:48:13 +0000697 raise ImportError("no path hook found for {0}".format(path))
Brett Cannon1d376682009-02-02 19:19:36 +0000698
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000699 @classmethod
Brett Cannon32732e32009-02-15 05:48:13 +0000700 def _path_importer_cache(cls, path, default=None):
Brett Cannon1d376682009-02-02 19:19:36 +0000701 """Get the finder for the path from sys.path_importer_cache.
702
703 If the path is not in the cache, find the appropriate finder and cache
704 it. If None is cached, get the default finder and cache that
705 (if applicable).
706
707 Because of NullImporter, some finder should be returned. The only
708 explicit fail case is if None is cached but the path cannot be used for
709 the default hook, for which ImportError is raised.
710
711 """
712 try:
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000713 finder = sys.path_importer_cache[path]
Brett Cannon1d376682009-02-02 19:19:36 +0000714 except KeyError:
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000715 finder = cls._path_hooks(path)
Brett Cannon1d376682009-02-02 19:19:36 +0000716 sys.path_importer_cache[path] = finder
717 else:
Brett Cannon32732e32009-02-15 05:48:13 +0000718 if finder is None and default:
Brett Cannon1d376682009-02-02 19:19:36 +0000719 # Raises ImportError on failure.
Brett Cannon32732e32009-02-15 05:48:13 +0000720 finder = default(path)
Brett Cannon1d376682009-02-02 19:19:36 +0000721 sys.path_importer_cache[path] = finder
722 return finder
723
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000724 @classmethod
725 def find_module(cls, fullname, path=None):
Brett Cannon1d376682009-02-02 19:19:36 +0000726 """Find the module on sys.path or 'path'."""
727 if not path:
728 path = sys.path
729 for entry in path:
730 try:
Brett Cannonf7e5a8c2009-02-05 02:52:18 +0000731 finder = cls._path_importer_cache(entry)
Brett Cannon1d376682009-02-02 19:19:36 +0000732 except ImportError:
733 continue
734 loader = finder.find_module(fullname)
735 if loader:
736 return loader
737 else:
738 return None
739
740
Brett Cannon3eeaa0a2009-03-12 22:07:17 +0000741_DEFAULT_PATH_HOOK = _chained_path_hook(ExtensionFileFinder, PyPycFileFinder)
Brett Cannon2dee5972009-02-21 03:15:37 +0000742
Brett Cannon32732e32009-02-15 05:48:13 +0000743class _DefaultPathFinder(PathFinder):
744
745 """Subclass of PathFinder that implements implicit semantics for
746 __import__."""
747
Brett Cannon32732e32009-02-15 05:48:13 +0000748 @classmethod
749 def _path_hooks(cls, path):
750 """Search sys.path_hooks as well as implicit path hooks."""
751 try:
752 return super()._path_hooks(path)
753 except ImportError:
Brett Cannon2dee5972009-02-21 03:15:37 +0000754 implicit_hooks = [_DEFAULT_PATH_HOOK, imp.NullImporter]
Brett Cannon32732e32009-02-15 05:48:13 +0000755 return super()._path_hooks(path, implicit_hooks)
756
757 @classmethod
758 def _path_importer_cache(cls, path):
759 """Use the default path hook when None is stored in
760 sys.path_importer_cache."""
Brett Cannon2dee5972009-02-21 03:15:37 +0000761 return super()._path_importer_cache(path, _DEFAULT_PATH_HOOK)
Brett Cannon32732e32009-02-15 05:48:13 +0000762
763
Brett Cannon3eeaa0a2009-03-12 22:07:17 +0000764class _ImportLockContext:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000765
766 """Context manager for the import lock."""
767
768 def __enter__(self):
769 """Acquire the import lock."""
770 imp.acquire_lock()
771
772 def __exit__(self, exc_type, exc_value, exc_traceback):
773 """Release the import lock regardless of any raised exceptions."""
774 imp.release_lock()
775
776
Brett Cannon32732e32009-02-15 05:48:13 +0000777_IMPLICIT_META_PATH = [BuiltinImporter, FrozenImporter, _DefaultPathFinder]
778
Brett Cannon7f9876c2009-02-06 02:47:33 +0000779def _gcd_import(name, package=None, level=0):
780 """Import and return the module based on its name, the package the call is
781 being made from, and the level adjustment.
782
783 This function represents the greatest common denominator of functionality
Brett Cannon2c318a12009-02-07 01:15:27 +0000784 between import_module and __import__. This includes settting __package__ if
785 the loader did not.
786
Brett Cannon7f9876c2009-02-06 02:47:33 +0000787 """
Brett Cannon2c318a12009-02-07 01:15:27 +0000788 if package:
789 if not hasattr(package, 'rindex'):
790 raise ValueError("__package__ not set to a string")
791 elif package not in sys.modules:
792 msg = ("Parent module {0!r} not loaded, cannot perform relative "
793 "import")
794 raise SystemError(msg.format(package))
795 if not name and level == 0:
796 raise ValueError("Empty module name")
Brett Cannon7f9876c2009-02-06 02:47:33 +0000797 if level > 0:
Brett Cannon2c318a12009-02-07 01:15:27 +0000798 dot = len(package)
Brett Cannon7f9876c2009-02-06 02:47:33 +0000799 for x in range(level, 1, -1):
800 try:
801 dot = package.rindex('.', 0, dot)
Brett Cannon7f9876c2009-02-06 02:47:33 +0000802 except ValueError:
Brett Cannon2c318a12009-02-07 01:15:27 +0000803 raise ValueError("attempted relative import beyond "
804 "top-level package")
805 if name:
806 name = "{0}.{1}".format(package[:dot], name)
807 else:
808 name = package[:dot]
Brett Cannon3eeaa0a2009-03-12 22:07:17 +0000809 with _ImportLockContext():
Brett Cannon7f9876c2009-02-06 02:47:33 +0000810 try:
811 return sys.modules[name]
812 except KeyError:
813 pass
814 parent = name.rpartition('.')[0]
815 path = None
816 if parent:
817 if parent not in sys.modules:
Brett Cannon2c318a12009-02-07 01:15:27 +0000818 _gcd_import(parent)
819 # Backwards-compatibility; be nicer to skip the dict lookup.
820 parent_module = sys.modules[parent]
Brett Cannon7f9876c2009-02-06 02:47:33 +0000821 path = parent_module.__path__
Brett Cannon32732e32009-02-15 05:48:13 +0000822 meta_path = sys.meta_path + _IMPLICIT_META_PATH
Brett Cannon2c318a12009-02-07 01:15:27 +0000823 for finder in meta_path:
Brett Cannon7f9876c2009-02-06 02:47:33 +0000824 loader = finder.find_module(name, path)
Brett Cannon2c318a12009-02-07 01:15:27 +0000825 if loader is not None:
826 loader.load_module(name)
827 break
Brett Cannon7f9876c2009-02-06 02:47:33 +0000828 else:
829 raise ImportError("No module named {0}".format(name))
Brett Cannon2c318a12009-02-07 01:15:27 +0000830 # Backwards-compatibility; be nicer to skip the dict lookup.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000831 module = sys.modules[name]
832 if parent:
Brett Cannon2c318a12009-02-07 01:15:27 +0000833 # Set the module as an attribute on its parent.
834 setattr(parent_module, name.rpartition('.')[2], module)
835 # Set __package__ if the loader did not.
836 if not hasattr(module, '__package__') or module.__package__ is None:
837 # Watch out for what comes out of sys.modules to not be a module,
838 # e.g. an int.
839 try:
840 module.__package__ = module.__name__
841 if not hasattr(module, '__path__'):
842 module.__package__ = module.__package__.rpartition('.')[0]
843 except AttributeError:
844 pass
845 return module
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000846
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000847
Brett Cannon2c318a12009-02-07 01:15:27 +0000848def _import(name, globals={}, locals={}, fromlist=[], level=0):
849 """Import a module.
850
851 The 'globals' argument is used to infer where the import is occuring from
852 to handle relative imports. The 'locals' argument is ignored. The
853 'fromlist' argument specifies what should exist as attributes on the module
854 being imported (e.g. ``from module import <fromlist>``). The 'level'
855 argument represents the package location to import from in a relative
856 import (e.g. ``from ..pkg import mod`` would have a 'level' of 2).
857
858 """
859 if level == 0:
860 module = _gcd_import(name)
861 else:
862 # __package__ is not guaranteed to be defined.
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000863 try:
Brett Cannon2c318a12009-02-07 01:15:27 +0000864 package = globals['__package__']
865 except KeyError:
866 package = globals['__name__']
867 if '__path__' not in globals:
868 package = package.rpartition('.')[0]
869 module = _gcd_import(name, package, level)
870 # The hell that is fromlist ...
871 if not fromlist:
872 # Return up to the first dot in 'name'. This is complicated by the fact
873 # that 'name' may be relative.
874 if level == 0:
875 return sys.modules[name.partition('.')[0]]
876 elif not name:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000877 return module
Brett Cannon2c318a12009-02-07 01:15:27 +0000878 else:
879 cut_off = len(name) - len(name.partition('.')[0])
880 return sys.modules[module.__name__[:-cut_off]]
881 else:
882 # If a package was imported, try to import stuff from fromlist.
883 if hasattr(module, '__path__'):
884 if '*' in fromlist and hasattr(module, '__all__'):
885 fromlist.remove('*')
886 fromlist.extend(module.__all__)
887 for x in (y for y in fromlist if not hasattr(module,y)):
888 try:
889 _gcd_import('{0}.{1}'.format(module.__name__, x))
890 except ImportError:
891 pass
892 return module
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000893
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000894
895# XXX Eventually replace with a proper __all__ value (i.e., don't expose os
896# replacements but do expose _ExtensionFileLoader, etc. for testing).
897__all__ = [obj for obj in globals().keys() if not obj.startswith('__')]