blob: 387567a450f23e0688aa67de8f4e89a84284d186 [file] [log] [blame]
Brett Cannon2a922ed2009-03-09 03:35:50 +00001"""Abstract base classes related to import."""
2from . import _bootstrap
3from . import machinery
Brett Cannon938d44d2012-04-22 19:58:33 -04004try:
5 import _frozen_importlib
6except ImportError as exc:
7 if exc.name != '_frozen_importlib':
8 raise
9 _frozen_importlib = None
Brett Cannon2a922ed2009-03-09 03:35:50 +000010import abc
Brett Cannonf23e3742010-06-27 23:57:46 +000011import imp
Brett Cannonf23e3742010-06-27 23:57:46 +000012import marshal
Brett Cannonf23e3742010-06-27 23:57:46 +000013import sys
14import tokenize
Brett Cannonf23e3742010-06-27 23:57:46 +000015import warnings
Brett Cannon2a922ed2009-03-09 03:35:50 +000016
17
Brett Cannon938d44d2012-04-22 19:58:33 -040018def _register(abstract_cls, *classes):
19 for cls in classes:
20 abstract_cls.register(cls)
21 if _frozen_importlib is not None:
22 frozen_cls = getattr(_frozen_importlib, cls.__name__)
23 abstract_cls.register(frozen_cls)
24
25
Nick Coghlan8a9080f2012-08-02 21:26:03 +100026class Finder(metaclass=abc.ABCMeta):
27
Brett Cannonf4dc9202012-08-10 12:21:12 -040028 """Legacy abstract base class for import finders.
Nick Coghlan8a9080f2012-08-02 21:26:03 +100029
Brett Cannonf4dc9202012-08-10 12:21:12 -040030 It may be subclassed for compatibility with legacy third party
31 reimplementations of the import system. Otherwise, finder
32 implementations should derive from the more specific MetaPathFinder
33 or PathEntryFinder ABCs.
Nick Coghlan8a9080f2012-08-02 21:26:03 +100034 """
35
Brett Cannonf4dc9202012-08-10 12:21:12 -040036 @abc.abstractmethod
Nick Coghlan8a9080f2012-08-02 21:26:03 +100037 def find_module(self, fullname, path=None):
Brett Cannonf4dc9202012-08-10 12:21:12 -040038 """An abstract method that should find a module.
Nick Coghlan8a9080f2012-08-02 21:26:03 +100039 The fullname is a str and the optional path is a str or None.
40 Returns a Loader object.
Nick Coghlan8a9080f2012-08-02 21:26:03 +100041 """
42 raise NotImplementedError
43
Nick Coghlan8a9080f2012-08-02 21:26:03 +100044
45class MetaPathFinder(Finder):
46
47 """Abstract base class for import finders on sys.meta_path."""
48
49 @abc.abstractmethod
50 def find_module(self, fullname, path):
Brett Cannonf4dc9202012-08-10 12:21:12 -040051 """Abstract method which, when implemented, should find a module.
Nick Coghlan8a9080f2012-08-02 21:26:03 +100052 The fullname is a str and the path is a str or None.
53 Returns a Loader object.
54 """
55 raise NotImplementedError
56
Brett Cannonf4dc9202012-08-10 12:21:12 -040057 def invalidate_caches(self):
58 """An optional method for clearing the finder's cache, if any.
59 This method is used by importlib.invalidate_caches().
60 """
61 return NotImplemented
62
Nick Coghlan8a9080f2012-08-02 21:26:03 +100063_register(MetaPathFinder, machinery.BuiltinImporter, machinery.FrozenImporter,
Nick Coghlanff794862012-08-02 21:45:24 +100064 machinery.PathFinder, machinery.WindowsRegistryFinder)
Nick Coghlan8a9080f2012-08-02 21:26:03 +100065
66
67class PathEntryFinder(Finder):
68
69 """Abstract base class for path entry finders used by PathFinder."""
70
71 @abc.abstractmethod
72 def find_loader(self, fullname):
Brett Cannonf4dc9202012-08-10 12:21:12 -040073 """Abstract method which, when implemented, returns a module loader.
Nick Coghlan8a9080f2012-08-02 21:26:03 +100074 The fullname is a str. Returns a 2-tuple of (Loader, portion) where
75 portion is a sequence of file system locations contributing to part of
Brett Cannonf4dc9202012-08-10 12:21:12 -040076 a namespace package. The sequence may be empty and the loader may be
77 None.
Nick Coghlan8a9080f2012-08-02 21:26:03 +100078 """
79 raise NotImplementedError
80
Brett Cannonf410ce82012-08-10 17:41:23 -040081 find_module = _bootstrap._find_module_shim
Brett Cannonf4dc9202012-08-10 12:21:12 -040082
83 def invalidate_caches(self):
84 """An optional method for clearing the finder's cache, if any.
85 This method is used by PathFinder.invalidate_caches().
86 """
87 return NotImplemented
88
Nick Coghlan8a9080f2012-08-02 21:26:03 +100089_register(PathEntryFinder, machinery.FileFinder)
90
91
Brett Cannon2a922ed2009-03-09 03:35:50 +000092class Loader(metaclass=abc.ABCMeta):
93
Brett Cannon7aa21f72009-03-15 00:53:05 +000094 """Abstract base class for import loaders."""
Brett Cannon2a922ed2009-03-09 03:35:50 +000095
Brett Cannon7aa21f72009-03-15 00:53:05 +000096 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +000097 def load_module(self, fullname):
Raymond Hettingerd958ea72011-01-13 19:08:04 +000098 """Abstract method which when implemented should load a module.
99 The fullname is a str."""
Brett Cannon2a922ed2009-03-09 03:35:50 +0000100 raise NotImplementedError
101
Barry Warsaw38f75cb2012-07-31 16:39:43 -0400102 @abc.abstractmethod
Barry Warsawd7d21942012-07-29 16:36:17 -0400103 def module_repr(self, module):
104 """Abstract method which when implemented calculates and returns the
105 given module's repr."""
106 raise NotImplementedError
107
Brett Cannon2a922ed2009-03-09 03:35:50 +0000108
Brett Cannon2a922ed2009-03-09 03:35:50 +0000109class ResourceLoader(Loader):
110
Brett Cannon7aa21f72009-03-15 00:53:05 +0000111 """Abstract base class for loaders which can return data from their
112 back-end storage.
Brett Cannon2a922ed2009-03-09 03:35:50 +0000113
114 This ABC represents one of the optional protocols specified by PEP 302.
115
116 """
117
118 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000119 def get_data(self, path):
Brett Cannon7aa21f72009-03-15 00:53:05 +0000120 """Abstract method which when implemented should return the bytes for
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000121 the specified path. The path must be a str."""
Brett Cannon2a922ed2009-03-09 03:35:50 +0000122 raise NotImplementedError
123
124
125class InspectLoader(Loader):
126
Brett Cannon7aa21f72009-03-15 00:53:05 +0000127 """Abstract base class for loaders which support inspection about the
128 modules they can load.
Brett Cannon2a922ed2009-03-09 03:35:50 +0000129
130 This ABC represents one of the optional protocols specified by PEP 302.
131
132 """
133
134 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000135 def is_package(self, fullname):
Brett Cannon7aa21f72009-03-15 00:53:05 +0000136 """Abstract method which when implemented should return whether the
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000137 module is a package. The fullname is a str. Returns a bool."""
Brett Cannonf23e3742010-06-27 23:57:46 +0000138 raise NotImplementedError
Brett Cannon2a922ed2009-03-09 03:35:50 +0000139
140 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000141 def get_code(self, fullname):
Brett Cannon7aa21f72009-03-15 00:53:05 +0000142 """Abstract method which when implemented should return the code object
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000143 for the module. The fullname is a str. Returns a types.CodeType."""
Brett Cannonf23e3742010-06-27 23:57:46 +0000144 raise NotImplementedError
Brett Cannon2a922ed2009-03-09 03:35:50 +0000145
146 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000147 def get_source(self, fullname):
Brett Cannon7aa21f72009-03-15 00:53:05 +0000148 """Abstract method which should return the source code for the
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000149 module. The fullname is a str. Returns a str."""
Brett Cannonf23e3742010-06-27 23:57:46 +0000150 raise NotImplementedError
Brett Cannon2a922ed2009-03-09 03:35:50 +0000151
Brett Cannon938d44d2012-04-22 19:58:33 -0400152_register(InspectLoader, machinery.BuiltinImporter, machinery.FrozenImporter,
153 machinery.ExtensionFileLoader)
Brett Cannona113ac52009-03-15 01:41:33 +0000154
Brett Cannon2a922ed2009-03-09 03:35:50 +0000155
Brett Cannon69194272009-07-20 04:23:48 +0000156class ExecutionLoader(InspectLoader):
157
158 """Abstract base class for loaders that wish to support the execution of
159 modules as scripts.
160
161 This ABC represents one of the optional protocols specified in PEP 302.
162
163 """
164
165 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000166 def get_filename(self, fullname):
Brett Cannon69194272009-07-20 04:23:48 +0000167 """Abstract method which should return the value that __file__ is to be
168 set to."""
169 raise NotImplementedError
170
171
Brett Cannon938d44d2012-04-22 19:58:33 -0400172class FileLoader(_bootstrap.FileLoader, ResourceLoader, ExecutionLoader):
173
174 """Abstract base class partially implementing the ResourceLoader and
175 ExecutionLoader ABCs."""
176
177_register(FileLoader, machinery.SourceFileLoader,
Marc-Andre Lemburg4fe29c92012-04-25 02:31:37 +0200178 machinery.SourcelessFileLoader)
Brett Cannon938d44d2012-04-22 19:58:33 -0400179
180
Brett Cannon0cf9e6a2010-06-28 04:57:24 +0000181class SourceLoader(_bootstrap.SourceLoader, ResourceLoader, ExecutionLoader):
Brett Cannon2a922ed2009-03-09 03:35:50 +0000182
Brett Cannonf23e3742010-06-27 23:57:46 +0000183 """Abstract base class for loading source code (and optionally any
184 corresponding bytecode).
Brett Cannon2a922ed2009-03-09 03:35:50 +0000185
Brett Cannonf23e3742010-06-27 23:57:46 +0000186 To support loading from source code, the abstractmethods inherited from
187 ResourceLoader and ExecutionLoader need to be implemented. To also support
188 loading from bytecode, the optional methods specified directly by this ABC
189 is required.
190
191 Inherited abstractmethods not implemented in this ABC:
192
193 * ResourceLoader.get_data
194 * ExecutionLoader.get_filename
195
196 """
197
Raymond Hettingercd92f372011-01-13 02:31:25 +0000198 def path_mtime(self, path):
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000199 """Return the (int) modification time for the path (str)."""
Antoine Pitrou5136ac02012-01-13 18:52:16 +0100200 if self.path_stats.__func__ is SourceLoader.path_stats:
201 raise NotImplementedError
202 return int(self.path_stats(path)['mtime'])
203
204 def path_stats(self, path):
205 """Return a metadata dict for the source pointed to by the path (str).
206 Possible keys:
207 - 'mtime' (mandatory) is the numeric timestamp of last source
208 code modification;
209 - 'size' (optional) is the size in bytes of the source code.
210 """
211 if self.path_mtime.__func__ is SourceLoader.path_mtime:
212 raise NotImplementedError
213 return {'mtime': self.path_mtime(path)}
Brett Cannon8d189072010-08-22 20:38:47 +0000214
Raymond Hettingercd92f372011-01-13 02:31:25 +0000215 def set_data(self, path, data):
Brett Cannon8d189072010-08-22 20:38:47 +0000216 """Write the bytes to the path (if possible).
217
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000218 Accepts a str path and data as bytes.
219
Brett Cannon8d189072010-08-22 20:38:47 +0000220 Any needed intermediary directories are to be created. If for some
221 reason the file cannot be written because of permissions, fail
222 silently.
223
224 """
225 raise NotImplementedError
226
Brett Cannon938d44d2012-04-22 19:58:33 -0400227_register(SourceLoader, machinery.SourceFileLoader)
Brett Cannonf23e3742010-06-27 23:57:46 +0000228
229class PyLoader(SourceLoader):
230
231 """Implement the deprecated PyLoader ABC in terms of SourceLoader.
232
233 This class has been deprecated! It is slated for removal in Python 3.4.
234 If compatibility with Python 3.1 is not needed then implement the
235 SourceLoader ABC instead of this class. If Python 3.1 compatibility is
236 needed, then use the following idiom to have a single class that is
237 compatible with Python 3.1 onwards::
238
239 try:
240 from importlib.abc import SourceLoader
241 except ImportError:
242 from importlib.abc import PyLoader as SourceLoader
243
244
245 class CustomLoader(SourceLoader):
246 def get_filename(self, fullname):
247 # Implement ...
248
249 def source_path(self, fullname):
250 '''Implement source_path in terms of get_filename.'''
251 try:
252 return self.get_filename(fullname)
253 except ImportError:
254 return None
255
256 def is_package(self, fullname):
257 filename = os.path.basename(self.get_filename(fullname))
258 return os.path.splitext(filename)[0] == '__init__'
Brett Cannon7aa21f72009-03-15 00:53:05 +0000259
260 """
Brett Cannon2a922ed2009-03-09 03:35:50 +0000261
262 @abc.abstractmethod
Brett Cannonf23e3742010-06-27 23:57:46 +0000263 def is_package(self, fullname):
Brett Cannon2a922ed2009-03-09 03:35:50 +0000264 raise NotImplementedError
265
Brett Cannonf23e3742010-06-27 23:57:46 +0000266 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000267 def source_path(self, fullname):
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000268 """Abstract method. Accepts a str module name and returns the path to
269 the source code for the module."""
Brett Cannonf23e3742010-06-27 23:57:46 +0000270 raise NotImplementedError
Brett Cannon2a922ed2009-03-09 03:35:50 +0000271
Brett Cannonf23e3742010-06-27 23:57:46 +0000272 def get_filename(self, fullname):
273 """Implement get_filename in terms of source_path.
274
275 As get_filename should only return a source file path there is no
276 chance of the path not existing but loading still being possible, so
277 ImportError should propagate instead of being turned into returning
278 None.
279
280 """
281 warnings.warn("importlib.abc.PyLoader is deprecated and is "
282 "slated for removal in Python 3.4; "
283 "use SourceLoader instead. "
284 "See the importlib documentation on how to be "
285 "compatible with Python 3.1 onwards.",
Florent Xicluna67317752011-12-10 11:07:42 +0100286 DeprecationWarning)
Brett Cannonf23e3742010-06-27 23:57:46 +0000287 path = self.source_path(fullname)
288 if path is None:
Brett Cannonbbb66802012-04-12 21:09:01 -0400289 raise ImportError(name=fullname)
Brett Cannonf23e3742010-06-27 23:57:46 +0000290 else:
291 return path
292
Brett Cannonf23e3742010-06-27 23:57:46 +0000293
294class PyPycLoader(PyLoader):
Brett Cannon2a922ed2009-03-09 03:35:50 +0000295
Brett Cannon7aa21f72009-03-15 00:53:05 +0000296 """Abstract base class to assist in loading source and bytecode by
297 requiring only back-end storage methods to be implemented.
Brett Cannon2a922ed2009-03-09 03:35:50 +0000298
Brett Cannonf23e3742010-06-27 23:57:46 +0000299 This class has been deprecated! Removal is slated for Python 3.4. Implement
300 the SourceLoader ABC instead. If Python 3.1 compatibility is needed, see
301 PyLoader.
302
Brett Cannon7aa21f72009-03-15 00:53:05 +0000303 The methods get_code, get_source, and load_module are implemented for the
304 user.
305
306 """
Brett Cannon2a922ed2009-03-09 03:35:50 +0000307
Brett Cannonf23e3742010-06-27 23:57:46 +0000308 def get_filename(self, fullname):
309 """Return the source or bytecode file path."""
310 path = self.source_path(fullname)
311 if path is not None:
312 return path
313 path = self.bytecode_path(fullname)
314 if path is not None:
315 return path
316 raise ImportError("no source or bytecode path available for "
Brett Cannonbbb66802012-04-12 21:09:01 -0400317 "{0!r}".format(fullname), name=fullname)
Brett Cannonf23e3742010-06-27 23:57:46 +0000318
319 def get_code(self, fullname):
320 """Get a code object from source or bytecode."""
321 warnings.warn("importlib.abc.PyPycLoader is deprecated and slated for "
322 "removal in Python 3.4; use SourceLoader instead. "
323 "If Python 3.1 compatibility is required, see the "
324 "latest documentation for PyLoader.",
Florent Xicluna67317752011-12-10 11:07:42 +0100325 DeprecationWarning)
Brett Cannonf23e3742010-06-27 23:57:46 +0000326 source_timestamp = self.source_mtime(fullname)
327 # Try to use bytecode if it is available.
328 bytecode_path = self.bytecode_path(fullname)
329 if bytecode_path:
330 data = self.get_data(bytecode_path)
331 try:
332 magic = data[:4]
333 if len(magic) < 4:
Philip Jenvey4b42ff62012-02-24 21:48:17 -0800334 raise ImportError(
Brett Cannonbbb66802012-04-12 21:09:01 -0400335 "bad magic number in {}".format(fullname),
336 name=fullname, path=bytecode_path)
Brett Cannonf23e3742010-06-27 23:57:46 +0000337 raw_timestamp = data[4:8]
338 if len(raw_timestamp) < 4:
339 raise EOFError("bad timestamp in {}".format(fullname))
Brett Cannonc264e3e2012-01-25 18:58:03 -0500340 pyc_timestamp = _bootstrap._r_long(raw_timestamp)
Brett Cannon1e331562012-07-02 14:35:34 -0400341 raw_source_size = data[8:12]
342 if len(raw_source_size) != 4:
343 raise EOFError("bad file size in {}".format(fullname))
344 # Source size is unused as the ABC does not provide a way to
345 # get the size of the source ahead of reading it.
346 bytecode = data[12:]
Brett Cannonf23e3742010-06-27 23:57:46 +0000347 # Verify that the magic number is valid.
348 if imp.get_magic() != magic:
Philip Jenvey4b42ff62012-02-24 21:48:17 -0800349 raise ImportError(
Brett Cannonbbb66802012-04-12 21:09:01 -0400350 "bad magic number in {}".format(fullname),
351 name=fullname, path=bytecode_path)
Brett Cannonf23e3742010-06-27 23:57:46 +0000352 # Verify that the bytecode is not stale (only matters when
353 # there is source to fall back on.
354 if source_timestamp:
355 if pyc_timestamp < source_timestamp:
Brett Cannonbbb66802012-04-12 21:09:01 -0400356 raise ImportError("bytecode is stale", name=fullname,
357 path=bytecode_path)
Brett Cannonf23e3742010-06-27 23:57:46 +0000358 except (ImportError, EOFError):
359 # If source is available give it a shot.
360 if source_timestamp is not None:
361 pass
362 else:
363 raise
364 else:
365 # Bytecode seems fine, so try to use it.
366 return marshal.loads(bytecode)
367 elif source_timestamp is None:
368 raise ImportError("no source or bytecode available to create code "
Brett Cannonbbb66802012-04-12 21:09:01 -0400369 "object for {0!r}".format(fullname),
370 name=fullname)
Brett Cannonf23e3742010-06-27 23:57:46 +0000371 # Use the source.
372 source_path = self.source_path(fullname)
373 if source_path is None:
374 message = "a source path must exist to load {0}".format(fullname)
Brett Cannonbbb66802012-04-12 21:09:01 -0400375 raise ImportError(message, name=fullname)
Brett Cannonf23e3742010-06-27 23:57:46 +0000376 source = self.get_data(source_path)
377 code_object = compile(source, source_path, 'exec', dont_inherit=True)
378 # Generate bytecode and write it out.
379 if not sys.dont_write_bytecode:
380 data = bytearray(imp.get_magic())
Brett Cannonc264e3e2012-01-25 18:58:03 -0500381 data.extend(_bootstrap._w_long(source_timestamp))
Brett Cannon1e331562012-07-02 14:35:34 -0400382 data.extend(_bootstrap._w_long(len(source) & 0xFFFFFFFF))
Brett Cannonf23e3742010-06-27 23:57:46 +0000383 data.extend(marshal.dumps(code_object))
384 self.write_bytecode(fullname, data)
385 return code_object
386
Brett Cannon2a922ed2009-03-09 03:35:50 +0000387 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000388 def source_mtime(self, fullname):
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000389 """Abstract method. Accepts a str filename and returns an int
Brett Cannon7aa21f72009-03-15 00:53:05 +0000390 modification time for the source of the module."""
Brett Cannon2a922ed2009-03-09 03:35:50 +0000391 raise NotImplementedError
392
393 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000394 def bytecode_path(self, fullname):
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000395 """Abstract method. Accepts a str filename and returns the str pathname
396 to the bytecode for the module."""
Brett Cannon2a922ed2009-03-09 03:35:50 +0000397 raise NotImplementedError
398
399 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000400 def write_bytecode(self, fullname, bytecode):
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000401 """Abstract method. Accepts a str filename and bytes object
402 representing the bytecode for the module. Returns a boolean
403 representing whether the bytecode was written or not."""
Brett Cannon2a922ed2009-03-09 03:35:50 +0000404 raise NotImplementedError