blob: e8a0541dc3fd3ea512306a9e756f8fed43333629 [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
28 """Common abstract base class for import finders.
29
30 Finder implementations should derive from the more specific
31 MetaPathFinder or PathEntryFinder ABCs rather than directly from Finder.
32 """
33
34 def find_module(self, fullname, path=None):
35 """An optional legacy method that should find a module.
36 The fullname is a str and the optional path is a str or None.
37 Returns a Loader object.
38
39 The path finder will use this method only if find_loader() does
40 not exist. It may optionally be implemented for compatibility
41 with legacy third party reimplementations of the import system.
42 """
43 raise NotImplementedError
44
45 # invalidate_caches() is a completely optional method, so no default
46 # implementation is provided. See the docs for details.
47
48
49class MetaPathFinder(Finder):
50
51 """Abstract base class for import finders on sys.meta_path."""
52
53 @abc.abstractmethod
54 def find_module(self, fullname, path):
55 """Abstract method which when implemented should find a module.
56 The fullname is a str and the path is a str or None.
57 Returns a Loader object.
58 """
59 raise NotImplementedError
60
61_register(MetaPathFinder, machinery.BuiltinImporter, machinery.FrozenImporter,
Nick Coghlanff794862012-08-02 21:45:24 +100062 machinery.PathFinder, machinery.WindowsRegistryFinder)
Nick Coghlan8a9080f2012-08-02 21:26:03 +100063
64
65class PathEntryFinder(Finder):
66
67 """Abstract base class for path entry finders used by PathFinder."""
68
69 @abc.abstractmethod
70 def find_loader(self, fullname):
71 """Abstract method which when implemented returns a module loader.
72 The fullname is a str. Returns a 2-tuple of (Loader, portion) where
73 portion is a sequence of file system locations contributing to part of
74 a namespace package. The sequence may be empty.
75 """
76 raise NotImplementedError
77
78_register(PathEntryFinder, machinery.FileFinder)
79
80
Brett Cannon2a922ed2009-03-09 03:35:50 +000081class Loader(metaclass=abc.ABCMeta):
82
Brett Cannon7aa21f72009-03-15 00:53:05 +000083 """Abstract base class for import loaders."""
Brett Cannon2a922ed2009-03-09 03:35:50 +000084
Brett Cannon7aa21f72009-03-15 00:53:05 +000085 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +000086 def load_module(self, fullname):
Raymond Hettingerd958ea72011-01-13 19:08:04 +000087 """Abstract method which when implemented should load a module.
88 The fullname is a str."""
Brett Cannon2a922ed2009-03-09 03:35:50 +000089 raise NotImplementedError
90
Barry Warsaw38f75cb2012-07-31 16:39:43 -040091 @abc.abstractmethod
Barry Warsawd7d21942012-07-29 16:36:17 -040092 def module_repr(self, module):
93 """Abstract method which when implemented calculates and returns the
94 given module's repr."""
95 raise NotImplementedError
96
Brett Cannon2a922ed2009-03-09 03:35:50 +000097
Brett Cannon2a922ed2009-03-09 03:35:50 +000098class ResourceLoader(Loader):
99
Brett Cannon7aa21f72009-03-15 00:53:05 +0000100 """Abstract base class for loaders which can return data from their
101 back-end storage.
Brett Cannon2a922ed2009-03-09 03:35:50 +0000102
103 This ABC represents one of the optional protocols specified by PEP 302.
104
105 """
106
107 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000108 def get_data(self, path):
Brett Cannon7aa21f72009-03-15 00:53:05 +0000109 """Abstract method which when implemented should return the bytes for
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000110 the specified path. The path must be a str."""
Brett Cannon2a922ed2009-03-09 03:35:50 +0000111 raise NotImplementedError
112
113
114class InspectLoader(Loader):
115
Brett Cannon7aa21f72009-03-15 00:53:05 +0000116 """Abstract base class for loaders which support inspection about the
117 modules they can load.
Brett Cannon2a922ed2009-03-09 03:35:50 +0000118
119 This ABC represents one of the optional protocols specified by PEP 302.
120
121 """
122
123 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000124 def is_package(self, fullname):
Brett Cannon7aa21f72009-03-15 00:53:05 +0000125 """Abstract method which when implemented should return whether the
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000126 module is a package. The fullname is a str. Returns a bool."""
Brett Cannonf23e3742010-06-27 23:57:46 +0000127 raise NotImplementedError
Brett Cannon2a922ed2009-03-09 03:35:50 +0000128
129 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000130 def get_code(self, fullname):
Brett Cannon7aa21f72009-03-15 00:53:05 +0000131 """Abstract method which when implemented should return the code object
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000132 for the module. The fullname is a str. Returns a types.CodeType."""
Brett Cannonf23e3742010-06-27 23:57:46 +0000133 raise NotImplementedError
Brett Cannon2a922ed2009-03-09 03:35:50 +0000134
135 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000136 def get_source(self, fullname):
Brett Cannon7aa21f72009-03-15 00:53:05 +0000137 """Abstract method which should return the source code for the
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000138 module. The fullname is a str. Returns a str."""
Brett Cannonf23e3742010-06-27 23:57:46 +0000139 raise NotImplementedError
Brett Cannon2a922ed2009-03-09 03:35:50 +0000140
Brett Cannon938d44d2012-04-22 19:58:33 -0400141_register(InspectLoader, machinery.BuiltinImporter, machinery.FrozenImporter,
142 machinery.ExtensionFileLoader)
Brett Cannona113ac52009-03-15 01:41:33 +0000143
Brett Cannon2a922ed2009-03-09 03:35:50 +0000144
Brett Cannon69194272009-07-20 04:23:48 +0000145class ExecutionLoader(InspectLoader):
146
147 """Abstract base class for loaders that wish to support the execution of
148 modules as scripts.
149
150 This ABC represents one of the optional protocols specified in PEP 302.
151
152 """
153
154 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000155 def get_filename(self, fullname):
Brett Cannon69194272009-07-20 04:23:48 +0000156 """Abstract method which should return the value that __file__ is to be
157 set to."""
158 raise NotImplementedError
159
160
Brett Cannon938d44d2012-04-22 19:58:33 -0400161class FileLoader(_bootstrap.FileLoader, ResourceLoader, ExecutionLoader):
162
163 """Abstract base class partially implementing the ResourceLoader and
164 ExecutionLoader ABCs."""
165
166_register(FileLoader, machinery.SourceFileLoader,
Marc-Andre Lemburg4fe29c92012-04-25 02:31:37 +0200167 machinery.SourcelessFileLoader)
Brett Cannon938d44d2012-04-22 19:58:33 -0400168
169
Brett Cannon0cf9e6a2010-06-28 04:57:24 +0000170class SourceLoader(_bootstrap.SourceLoader, ResourceLoader, ExecutionLoader):
Brett Cannon2a922ed2009-03-09 03:35:50 +0000171
Brett Cannonf23e3742010-06-27 23:57:46 +0000172 """Abstract base class for loading source code (and optionally any
173 corresponding bytecode).
Brett Cannon2a922ed2009-03-09 03:35:50 +0000174
Brett Cannonf23e3742010-06-27 23:57:46 +0000175 To support loading from source code, the abstractmethods inherited from
176 ResourceLoader and ExecutionLoader need to be implemented. To also support
177 loading from bytecode, the optional methods specified directly by this ABC
178 is required.
179
180 Inherited abstractmethods not implemented in this ABC:
181
182 * ResourceLoader.get_data
183 * ExecutionLoader.get_filename
184
185 """
186
Raymond Hettingercd92f372011-01-13 02:31:25 +0000187 def path_mtime(self, path):
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000188 """Return the (int) modification time for the path (str)."""
Antoine Pitrou5136ac02012-01-13 18:52:16 +0100189 if self.path_stats.__func__ is SourceLoader.path_stats:
190 raise NotImplementedError
191 return int(self.path_stats(path)['mtime'])
192
193 def path_stats(self, path):
194 """Return a metadata dict for the source pointed to by the path (str).
195 Possible keys:
196 - 'mtime' (mandatory) is the numeric timestamp of last source
197 code modification;
198 - 'size' (optional) is the size in bytes of the source code.
199 """
200 if self.path_mtime.__func__ is SourceLoader.path_mtime:
201 raise NotImplementedError
202 return {'mtime': self.path_mtime(path)}
Brett Cannon8d189072010-08-22 20:38:47 +0000203
Raymond Hettingercd92f372011-01-13 02:31:25 +0000204 def set_data(self, path, data):
Brett Cannon8d189072010-08-22 20:38:47 +0000205 """Write the bytes to the path (if possible).
206
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000207 Accepts a str path and data as bytes.
208
Brett Cannon8d189072010-08-22 20:38:47 +0000209 Any needed intermediary directories are to be created. If for some
210 reason the file cannot be written because of permissions, fail
211 silently.
212
213 """
214 raise NotImplementedError
215
Brett Cannon938d44d2012-04-22 19:58:33 -0400216_register(SourceLoader, machinery.SourceFileLoader)
Brett Cannonf23e3742010-06-27 23:57:46 +0000217
218class PyLoader(SourceLoader):
219
220 """Implement the deprecated PyLoader ABC in terms of SourceLoader.
221
222 This class has been deprecated! It is slated for removal in Python 3.4.
223 If compatibility with Python 3.1 is not needed then implement the
224 SourceLoader ABC instead of this class. If Python 3.1 compatibility is
225 needed, then use the following idiom to have a single class that is
226 compatible with Python 3.1 onwards::
227
228 try:
229 from importlib.abc import SourceLoader
230 except ImportError:
231 from importlib.abc import PyLoader as SourceLoader
232
233
234 class CustomLoader(SourceLoader):
235 def get_filename(self, fullname):
236 # Implement ...
237
238 def source_path(self, fullname):
239 '''Implement source_path in terms of get_filename.'''
240 try:
241 return self.get_filename(fullname)
242 except ImportError:
243 return None
244
245 def is_package(self, fullname):
246 filename = os.path.basename(self.get_filename(fullname))
247 return os.path.splitext(filename)[0] == '__init__'
Brett Cannon7aa21f72009-03-15 00:53:05 +0000248
249 """
Brett Cannon2a922ed2009-03-09 03:35:50 +0000250
251 @abc.abstractmethod
Brett Cannonf23e3742010-06-27 23:57:46 +0000252 def is_package(self, fullname):
Brett Cannon2a922ed2009-03-09 03:35:50 +0000253 raise NotImplementedError
254
Brett Cannonf23e3742010-06-27 23:57:46 +0000255 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000256 def source_path(self, fullname):
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000257 """Abstract method. Accepts a str module name and returns the path to
258 the source code for the module."""
Brett Cannonf23e3742010-06-27 23:57:46 +0000259 raise NotImplementedError
Brett Cannon2a922ed2009-03-09 03:35:50 +0000260
Brett Cannonf23e3742010-06-27 23:57:46 +0000261 def get_filename(self, fullname):
262 """Implement get_filename in terms of source_path.
263
264 As get_filename should only return a source file path there is no
265 chance of the path not existing but loading still being possible, so
266 ImportError should propagate instead of being turned into returning
267 None.
268
269 """
270 warnings.warn("importlib.abc.PyLoader is deprecated and is "
271 "slated for removal in Python 3.4; "
272 "use SourceLoader instead. "
273 "See the importlib documentation on how to be "
274 "compatible with Python 3.1 onwards.",
Florent Xicluna67317752011-12-10 11:07:42 +0100275 DeprecationWarning)
Brett Cannonf23e3742010-06-27 23:57:46 +0000276 path = self.source_path(fullname)
277 if path is None:
Brett Cannonbbb66802012-04-12 21:09:01 -0400278 raise ImportError(name=fullname)
Brett Cannonf23e3742010-06-27 23:57:46 +0000279 else:
280 return path
281
Brett Cannonf23e3742010-06-27 23:57:46 +0000282
283class PyPycLoader(PyLoader):
Brett Cannon2a922ed2009-03-09 03:35:50 +0000284
Brett Cannon7aa21f72009-03-15 00:53:05 +0000285 """Abstract base class to assist in loading source and bytecode by
286 requiring only back-end storage methods to be implemented.
Brett Cannon2a922ed2009-03-09 03:35:50 +0000287
Brett Cannonf23e3742010-06-27 23:57:46 +0000288 This class has been deprecated! Removal is slated for Python 3.4. Implement
289 the SourceLoader ABC instead. If Python 3.1 compatibility is needed, see
290 PyLoader.
291
Brett Cannon7aa21f72009-03-15 00:53:05 +0000292 The methods get_code, get_source, and load_module are implemented for the
293 user.
294
295 """
Brett Cannon2a922ed2009-03-09 03:35:50 +0000296
Brett Cannonf23e3742010-06-27 23:57:46 +0000297 def get_filename(self, fullname):
298 """Return the source or bytecode file path."""
299 path = self.source_path(fullname)
300 if path is not None:
301 return path
302 path = self.bytecode_path(fullname)
303 if path is not None:
304 return path
305 raise ImportError("no source or bytecode path available for "
Brett Cannonbbb66802012-04-12 21:09:01 -0400306 "{0!r}".format(fullname), name=fullname)
Brett Cannonf23e3742010-06-27 23:57:46 +0000307
308 def get_code(self, fullname):
309 """Get a code object from source or bytecode."""
310 warnings.warn("importlib.abc.PyPycLoader is deprecated and slated for "
311 "removal in Python 3.4; use SourceLoader instead. "
312 "If Python 3.1 compatibility is required, see the "
313 "latest documentation for PyLoader.",
Florent Xicluna67317752011-12-10 11:07:42 +0100314 DeprecationWarning)
Brett Cannonf23e3742010-06-27 23:57:46 +0000315 source_timestamp = self.source_mtime(fullname)
316 # Try to use bytecode if it is available.
317 bytecode_path = self.bytecode_path(fullname)
318 if bytecode_path:
319 data = self.get_data(bytecode_path)
320 try:
321 magic = data[:4]
322 if len(magic) < 4:
Philip Jenvey4b42ff62012-02-24 21:48:17 -0800323 raise ImportError(
Brett Cannonbbb66802012-04-12 21:09:01 -0400324 "bad magic number in {}".format(fullname),
325 name=fullname, path=bytecode_path)
Brett Cannonf23e3742010-06-27 23:57:46 +0000326 raw_timestamp = data[4:8]
327 if len(raw_timestamp) < 4:
328 raise EOFError("bad timestamp in {}".format(fullname))
Brett Cannonc264e3e2012-01-25 18:58:03 -0500329 pyc_timestamp = _bootstrap._r_long(raw_timestamp)
Brett Cannon1e331562012-07-02 14:35:34 -0400330 raw_source_size = data[8:12]
331 if len(raw_source_size) != 4:
332 raise EOFError("bad file size in {}".format(fullname))
333 # Source size is unused as the ABC does not provide a way to
334 # get the size of the source ahead of reading it.
335 bytecode = data[12:]
Brett Cannonf23e3742010-06-27 23:57:46 +0000336 # Verify that the magic number is valid.
337 if imp.get_magic() != magic:
Philip Jenvey4b42ff62012-02-24 21:48:17 -0800338 raise ImportError(
Brett Cannonbbb66802012-04-12 21:09:01 -0400339 "bad magic number in {}".format(fullname),
340 name=fullname, path=bytecode_path)
Brett Cannonf23e3742010-06-27 23:57:46 +0000341 # Verify that the bytecode is not stale (only matters when
342 # there is source to fall back on.
343 if source_timestamp:
344 if pyc_timestamp < source_timestamp:
Brett Cannonbbb66802012-04-12 21:09:01 -0400345 raise ImportError("bytecode is stale", name=fullname,
346 path=bytecode_path)
Brett Cannonf23e3742010-06-27 23:57:46 +0000347 except (ImportError, EOFError):
348 # If source is available give it a shot.
349 if source_timestamp is not None:
350 pass
351 else:
352 raise
353 else:
354 # Bytecode seems fine, so try to use it.
355 return marshal.loads(bytecode)
356 elif source_timestamp is None:
357 raise ImportError("no source or bytecode available to create code "
Brett Cannonbbb66802012-04-12 21:09:01 -0400358 "object for {0!r}".format(fullname),
359 name=fullname)
Brett Cannonf23e3742010-06-27 23:57:46 +0000360 # Use the source.
361 source_path = self.source_path(fullname)
362 if source_path is None:
363 message = "a source path must exist to load {0}".format(fullname)
Brett Cannonbbb66802012-04-12 21:09:01 -0400364 raise ImportError(message, name=fullname)
Brett Cannonf23e3742010-06-27 23:57:46 +0000365 source = self.get_data(source_path)
366 code_object = compile(source, source_path, 'exec', dont_inherit=True)
367 # Generate bytecode and write it out.
368 if not sys.dont_write_bytecode:
369 data = bytearray(imp.get_magic())
Brett Cannonc264e3e2012-01-25 18:58:03 -0500370 data.extend(_bootstrap._w_long(source_timestamp))
Brett Cannon1e331562012-07-02 14:35:34 -0400371 data.extend(_bootstrap._w_long(len(source) & 0xFFFFFFFF))
Brett Cannonf23e3742010-06-27 23:57:46 +0000372 data.extend(marshal.dumps(code_object))
373 self.write_bytecode(fullname, data)
374 return code_object
375
Brett Cannon2a922ed2009-03-09 03:35:50 +0000376 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000377 def source_mtime(self, fullname):
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000378 """Abstract method. Accepts a str filename and returns an int
Brett Cannon7aa21f72009-03-15 00:53:05 +0000379 modification time for the source of the module."""
Brett Cannon2a922ed2009-03-09 03:35:50 +0000380 raise NotImplementedError
381
382 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000383 def bytecode_path(self, fullname):
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000384 """Abstract method. Accepts a str filename and returns the str pathname
385 to the bytecode for the module."""
Brett Cannon2a922ed2009-03-09 03:35:50 +0000386 raise NotImplementedError
387
388 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000389 def write_bytecode(self, fullname, bytecode):
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000390 """Abstract method. Accepts a str filename and bytes object
391 representing the bytecode for the module. Returns a boolean
392 representing whether the bytecode was written or not."""
Brett Cannon2a922ed2009-03-09 03:35:50 +0000393 raise NotImplementedError