blob: cd687e8f446a1e69547d206b7a45e2965455dfcd [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 Cannonf4dc9202012-08-10 12:21:12 -040081 def find_module(self, fullname):
82 """Compatibility function which is the equivalent of
83 self.find_loader(fullname)[0]."""
84 return self.find_loader(fullname)[0]
85
86 def invalidate_caches(self):
87 """An optional method for clearing the finder's cache, if any.
88 This method is used by PathFinder.invalidate_caches().
89 """
90 return NotImplemented
91
Nick Coghlan8a9080f2012-08-02 21:26:03 +100092_register(PathEntryFinder, machinery.FileFinder)
93
94
Brett Cannon2a922ed2009-03-09 03:35:50 +000095class Loader(metaclass=abc.ABCMeta):
96
Brett Cannon7aa21f72009-03-15 00:53:05 +000097 """Abstract base class for import loaders."""
Brett Cannon2a922ed2009-03-09 03:35:50 +000098
Brett Cannon7aa21f72009-03-15 00:53:05 +000099 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000100 def load_module(self, fullname):
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000101 """Abstract method which when implemented should load a module.
102 The fullname is a str."""
Brett Cannon2a922ed2009-03-09 03:35:50 +0000103 raise NotImplementedError
104
Barry Warsaw38f75cb2012-07-31 16:39:43 -0400105 @abc.abstractmethod
Barry Warsawd7d21942012-07-29 16:36:17 -0400106 def module_repr(self, module):
107 """Abstract method which when implemented calculates and returns the
108 given module's repr."""
109 raise NotImplementedError
110
Brett Cannon2a922ed2009-03-09 03:35:50 +0000111
Brett Cannon2a922ed2009-03-09 03:35:50 +0000112class ResourceLoader(Loader):
113
Brett Cannon7aa21f72009-03-15 00:53:05 +0000114 """Abstract base class for loaders which can return data from their
115 back-end storage.
Brett Cannon2a922ed2009-03-09 03:35:50 +0000116
117 This ABC represents one of the optional protocols specified by PEP 302.
118
119 """
120
121 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000122 def get_data(self, path):
Brett Cannon7aa21f72009-03-15 00:53:05 +0000123 """Abstract method which when implemented should return the bytes for
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000124 the specified path. The path must be a str."""
Brett Cannon2a922ed2009-03-09 03:35:50 +0000125 raise NotImplementedError
126
127
128class InspectLoader(Loader):
129
Brett Cannon7aa21f72009-03-15 00:53:05 +0000130 """Abstract base class for loaders which support inspection about the
131 modules they can load.
Brett Cannon2a922ed2009-03-09 03:35:50 +0000132
133 This ABC represents one of the optional protocols specified by PEP 302.
134
135 """
136
137 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000138 def is_package(self, fullname):
Brett Cannon7aa21f72009-03-15 00:53:05 +0000139 """Abstract method which when implemented should return whether the
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000140 module is a package. The fullname is a str. Returns a bool."""
Brett Cannonf23e3742010-06-27 23:57:46 +0000141 raise NotImplementedError
Brett Cannon2a922ed2009-03-09 03:35:50 +0000142
143 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000144 def get_code(self, fullname):
Brett Cannon7aa21f72009-03-15 00:53:05 +0000145 """Abstract method which when implemented should return the code object
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000146 for the module. The fullname is a str. Returns a types.CodeType."""
Brett Cannonf23e3742010-06-27 23:57:46 +0000147 raise NotImplementedError
Brett Cannon2a922ed2009-03-09 03:35:50 +0000148
149 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000150 def get_source(self, fullname):
Brett Cannon7aa21f72009-03-15 00:53:05 +0000151 """Abstract method which should return the source code for the
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000152 module. The fullname is a str. Returns a str."""
Brett Cannonf23e3742010-06-27 23:57:46 +0000153 raise NotImplementedError
Brett Cannon2a922ed2009-03-09 03:35:50 +0000154
Brett Cannon938d44d2012-04-22 19:58:33 -0400155_register(InspectLoader, machinery.BuiltinImporter, machinery.FrozenImporter,
156 machinery.ExtensionFileLoader)
Brett Cannona113ac52009-03-15 01:41:33 +0000157
Brett Cannon2a922ed2009-03-09 03:35:50 +0000158
Brett Cannon69194272009-07-20 04:23:48 +0000159class ExecutionLoader(InspectLoader):
160
161 """Abstract base class for loaders that wish to support the execution of
162 modules as scripts.
163
164 This ABC represents one of the optional protocols specified in PEP 302.
165
166 """
167
168 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000169 def get_filename(self, fullname):
Brett Cannon69194272009-07-20 04:23:48 +0000170 """Abstract method which should return the value that __file__ is to be
171 set to."""
172 raise NotImplementedError
173
174
Brett Cannon938d44d2012-04-22 19:58:33 -0400175class FileLoader(_bootstrap.FileLoader, ResourceLoader, ExecutionLoader):
176
177 """Abstract base class partially implementing the ResourceLoader and
178 ExecutionLoader ABCs."""
179
180_register(FileLoader, machinery.SourceFileLoader,
Marc-Andre Lemburg4fe29c92012-04-25 02:31:37 +0200181 machinery.SourcelessFileLoader)
Brett Cannon938d44d2012-04-22 19:58:33 -0400182
183
Brett Cannon0cf9e6a2010-06-28 04:57:24 +0000184class SourceLoader(_bootstrap.SourceLoader, ResourceLoader, ExecutionLoader):
Brett Cannon2a922ed2009-03-09 03:35:50 +0000185
Brett Cannonf23e3742010-06-27 23:57:46 +0000186 """Abstract base class for loading source code (and optionally any
187 corresponding bytecode).
Brett Cannon2a922ed2009-03-09 03:35:50 +0000188
Brett Cannonf23e3742010-06-27 23:57:46 +0000189 To support loading from source code, the abstractmethods inherited from
190 ResourceLoader and ExecutionLoader need to be implemented. To also support
191 loading from bytecode, the optional methods specified directly by this ABC
192 is required.
193
194 Inherited abstractmethods not implemented in this ABC:
195
196 * ResourceLoader.get_data
197 * ExecutionLoader.get_filename
198
199 """
200
Raymond Hettingercd92f372011-01-13 02:31:25 +0000201 def path_mtime(self, path):
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000202 """Return the (int) modification time for the path (str)."""
Antoine Pitrou5136ac02012-01-13 18:52:16 +0100203 if self.path_stats.__func__ is SourceLoader.path_stats:
204 raise NotImplementedError
205 return int(self.path_stats(path)['mtime'])
206
207 def path_stats(self, path):
208 """Return a metadata dict for the source pointed to by the path (str).
209 Possible keys:
210 - 'mtime' (mandatory) is the numeric timestamp of last source
211 code modification;
212 - 'size' (optional) is the size in bytes of the source code.
213 """
214 if self.path_mtime.__func__ is SourceLoader.path_mtime:
215 raise NotImplementedError
216 return {'mtime': self.path_mtime(path)}
Brett Cannon8d189072010-08-22 20:38:47 +0000217
Raymond Hettingercd92f372011-01-13 02:31:25 +0000218 def set_data(self, path, data):
Brett Cannon8d189072010-08-22 20:38:47 +0000219 """Write the bytes to the path (if possible).
220
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000221 Accepts a str path and data as bytes.
222
Brett Cannon8d189072010-08-22 20:38:47 +0000223 Any needed intermediary directories are to be created. If for some
224 reason the file cannot be written because of permissions, fail
225 silently.
226
227 """
228 raise NotImplementedError
229
Brett Cannon938d44d2012-04-22 19:58:33 -0400230_register(SourceLoader, machinery.SourceFileLoader)
Brett Cannonf23e3742010-06-27 23:57:46 +0000231
232class PyLoader(SourceLoader):
233
234 """Implement the deprecated PyLoader ABC in terms of SourceLoader.
235
236 This class has been deprecated! It is slated for removal in Python 3.4.
237 If compatibility with Python 3.1 is not needed then implement the
238 SourceLoader ABC instead of this class. If Python 3.1 compatibility is
239 needed, then use the following idiom to have a single class that is
240 compatible with Python 3.1 onwards::
241
242 try:
243 from importlib.abc import SourceLoader
244 except ImportError:
245 from importlib.abc import PyLoader as SourceLoader
246
247
248 class CustomLoader(SourceLoader):
249 def get_filename(self, fullname):
250 # Implement ...
251
252 def source_path(self, fullname):
253 '''Implement source_path in terms of get_filename.'''
254 try:
255 return self.get_filename(fullname)
256 except ImportError:
257 return None
258
259 def is_package(self, fullname):
260 filename = os.path.basename(self.get_filename(fullname))
261 return os.path.splitext(filename)[0] == '__init__'
Brett Cannon7aa21f72009-03-15 00:53:05 +0000262
263 """
Brett Cannon2a922ed2009-03-09 03:35:50 +0000264
265 @abc.abstractmethod
Brett Cannonf23e3742010-06-27 23:57:46 +0000266 def is_package(self, fullname):
Brett Cannon2a922ed2009-03-09 03:35:50 +0000267 raise NotImplementedError
268
Brett Cannonf23e3742010-06-27 23:57:46 +0000269 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000270 def source_path(self, fullname):
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000271 """Abstract method. Accepts a str module name and returns the path to
272 the source code for the module."""
Brett Cannonf23e3742010-06-27 23:57:46 +0000273 raise NotImplementedError
Brett Cannon2a922ed2009-03-09 03:35:50 +0000274
Brett Cannonf23e3742010-06-27 23:57:46 +0000275 def get_filename(self, fullname):
276 """Implement get_filename in terms of source_path.
277
278 As get_filename should only return a source file path there is no
279 chance of the path not existing but loading still being possible, so
280 ImportError should propagate instead of being turned into returning
281 None.
282
283 """
284 warnings.warn("importlib.abc.PyLoader is deprecated and is "
285 "slated for removal in Python 3.4; "
286 "use SourceLoader instead. "
287 "See the importlib documentation on how to be "
288 "compatible with Python 3.1 onwards.",
Florent Xicluna67317752011-12-10 11:07:42 +0100289 DeprecationWarning)
Brett Cannonf23e3742010-06-27 23:57:46 +0000290 path = self.source_path(fullname)
291 if path is None:
Brett Cannonbbb66802012-04-12 21:09:01 -0400292 raise ImportError(name=fullname)
Brett Cannonf23e3742010-06-27 23:57:46 +0000293 else:
294 return path
295
Brett Cannonf23e3742010-06-27 23:57:46 +0000296
297class PyPycLoader(PyLoader):
Brett Cannon2a922ed2009-03-09 03:35:50 +0000298
Brett Cannon7aa21f72009-03-15 00:53:05 +0000299 """Abstract base class to assist in loading source and bytecode by
300 requiring only back-end storage methods to be implemented.
Brett Cannon2a922ed2009-03-09 03:35:50 +0000301
Brett Cannonf23e3742010-06-27 23:57:46 +0000302 This class has been deprecated! Removal is slated for Python 3.4. Implement
303 the SourceLoader ABC instead. If Python 3.1 compatibility is needed, see
304 PyLoader.
305
Brett Cannon7aa21f72009-03-15 00:53:05 +0000306 The methods get_code, get_source, and load_module are implemented for the
307 user.
308
309 """
Brett Cannon2a922ed2009-03-09 03:35:50 +0000310
Brett Cannonf23e3742010-06-27 23:57:46 +0000311 def get_filename(self, fullname):
312 """Return the source or bytecode file path."""
313 path = self.source_path(fullname)
314 if path is not None:
315 return path
316 path = self.bytecode_path(fullname)
317 if path is not None:
318 return path
319 raise ImportError("no source or bytecode path available for "
Brett Cannonbbb66802012-04-12 21:09:01 -0400320 "{0!r}".format(fullname), name=fullname)
Brett Cannonf23e3742010-06-27 23:57:46 +0000321
322 def get_code(self, fullname):
323 """Get a code object from source or bytecode."""
324 warnings.warn("importlib.abc.PyPycLoader is deprecated and slated for "
325 "removal in Python 3.4; use SourceLoader instead. "
326 "If Python 3.1 compatibility is required, see the "
327 "latest documentation for PyLoader.",
Florent Xicluna67317752011-12-10 11:07:42 +0100328 DeprecationWarning)
Brett Cannonf23e3742010-06-27 23:57:46 +0000329 source_timestamp = self.source_mtime(fullname)
330 # Try to use bytecode if it is available.
331 bytecode_path = self.bytecode_path(fullname)
332 if bytecode_path:
333 data = self.get_data(bytecode_path)
334 try:
335 magic = data[:4]
336 if len(magic) < 4:
Philip Jenvey4b42ff62012-02-24 21:48:17 -0800337 raise ImportError(
Brett Cannonbbb66802012-04-12 21:09:01 -0400338 "bad magic number in {}".format(fullname),
339 name=fullname, path=bytecode_path)
Brett Cannonf23e3742010-06-27 23:57:46 +0000340 raw_timestamp = data[4:8]
341 if len(raw_timestamp) < 4:
342 raise EOFError("bad timestamp in {}".format(fullname))
Brett Cannonc264e3e2012-01-25 18:58:03 -0500343 pyc_timestamp = _bootstrap._r_long(raw_timestamp)
Brett Cannon1e331562012-07-02 14:35:34 -0400344 raw_source_size = data[8:12]
345 if len(raw_source_size) != 4:
346 raise EOFError("bad file size in {}".format(fullname))
347 # Source size is unused as the ABC does not provide a way to
348 # get the size of the source ahead of reading it.
349 bytecode = data[12:]
Brett Cannonf23e3742010-06-27 23:57:46 +0000350 # Verify that the magic number is valid.
351 if imp.get_magic() != magic:
Philip Jenvey4b42ff62012-02-24 21:48:17 -0800352 raise ImportError(
Brett Cannonbbb66802012-04-12 21:09:01 -0400353 "bad magic number in {}".format(fullname),
354 name=fullname, path=bytecode_path)
Brett Cannonf23e3742010-06-27 23:57:46 +0000355 # Verify that the bytecode is not stale (only matters when
356 # there is source to fall back on.
357 if source_timestamp:
358 if pyc_timestamp < source_timestamp:
Brett Cannonbbb66802012-04-12 21:09:01 -0400359 raise ImportError("bytecode is stale", name=fullname,
360 path=bytecode_path)
Brett Cannonf23e3742010-06-27 23:57:46 +0000361 except (ImportError, EOFError):
362 # If source is available give it a shot.
363 if source_timestamp is not None:
364 pass
365 else:
366 raise
367 else:
368 # Bytecode seems fine, so try to use it.
369 return marshal.loads(bytecode)
370 elif source_timestamp is None:
371 raise ImportError("no source or bytecode available to create code "
Brett Cannonbbb66802012-04-12 21:09:01 -0400372 "object for {0!r}".format(fullname),
373 name=fullname)
Brett Cannonf23e3742010-06-27 23:57:46 +0000374 # Use the source.
375 source_path = self.source_path(fullname)
376 if source_path is None:
377 message = "a source path must exist to load {0}".format(fullname)
Brett Cannonbbb66802012-04-12 21:09:01 -0400378 raise ImportError(message, name=fullname)
Brett Cannonf23e3742010-06-27 23:57:46 +0000379 source = self.get_data(source_path)
380 code_object = compile(source, source_path, 'exec', dont_inherit=True)
381 # Generate bytecode and write it out.
382 if not sys.dont_write_bytecode:
383 data = bytearray(imp.get_magic())
Brett Cannonc264e3e2012-01-25 18:58:03 -0500384 data.extend(_bootstrap._w_long(source_timestamp))
Brett Cannon1e331562012-07-02 14:35:34 -0400385 data.extend(_bootstrap._w_long(len(source) & 0xFFFFFFFF))
Brett Cannonf23e3742010-06-27 23:57:46 +0000386 data.extend(marshal.dumps(code_object))
387 self.write_bytecode(fullname, data)
388 return code_object
389
Brett Cannon2a922ed2009-03-09 03:35:50 +0000390 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000391 def source_mtime(self, fullname):
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000392 """Abstract method. Accepts a str filename and returns an int
Brett Cannon7aa21f72009-03-15 00:53:05 +0000393 modification time for the source of the module."""
Brett Cannon2a922ed2009-03-09 03:35:50 +0000394 raise NotImplementedError
395
396 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000397 def bytecode_path(self, fullname):
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000398 """Abstract method. Accepts a str filename and returns the str pathname
399 to the bytecode for the module."""
Brett Cannon2a922ed2009-03-09 03:35:50 +0000400 raise NotImplementedError
401
402 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000403 def write_bytecode(self, fullname, bytecode):
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000404 """Abstract method. Accepts a str filename and bytes object
405 representing the bytecode for the module. Returns a boolean
406 representing whether the bytecode was written or not."""
Brett Cannon2a922ed2009-03-09 03:35:50 +0000407 raise NotImplementedError