blob: 7fcf2de438fc38c313f2100bccd88807836525b7 [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
Brett Cannon2a922ed2009-03-09 03:35:50 +000026class Loader(metaclass=abc.ABCMeta):
27
Brett Cannon7aa21f72009-03-15 00:53:05 +000028 """Abstract base class for import loaders."""
Brett Cannon2a922ed2009-03-09 03:35:50 +000029
Brett Cannon7aa21f72009-03-15 00:53:05 +000030 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +000031 def load_module(self, fullname):
Raymond Hettingerd958ea72011-01-13 19:08:04 +000032 """Abstract method which when implemented should load a module.
33 The fullname is a str."""
Brett Cannon2a922ed2009-03-09 03:35:50 +000034 raise NotImplementedError
35
Barry Warsaw38f75cb2012-07-31 16:39:43 -040036 @abc.abstractmethod
Barry Warsawd7d21942012-07-29 16:36:17 -040037 def module_repr(self, module):
38 """Abstract method which when implemented calculates and returns the
39 given module's repr."""
40 raise NotImplementedError
41
Brett Cannon2a922ed2009-03-09 03:35:50 +000042
43class Finder(metaclass=abc.ABCMeta):
44
Brett Cannon7aa21f72009-03-15 00:53:05 +000045 """Abstract base class for import finders."""
Brett Cannon2a922ed2009-03-09 03:35:50 +000046
Barry Warsaw38f75cb2012-07-31 16:39:43 -040047 @abc.abstractmethod
Barry Warsawd7d21942012-07-29 16:36:17 -040048 def find_loader(self, fullname):
49 """Abstract method which when implemented returns a module loader.
50 The fullname is a str. Returns a 2-tuple of (Loader, portion) where
51 portion is a sequence of file system locations contributing to part of
52 a namespace package. The sequence may be empty. When present,
53 `find_loader()` is preferred over `find_module()`.
54 """
55 raise NotImplementedError
56
Brett Cannon2a922ed2009-03-09 03:35:50 +000057 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +000058 def find_module(self, fullname, path=None):
Raymond Hettingerd958ea72011-01-13 19:08:04 +000059 """Abstract method which when implemented should find a module.
60 The fullname is a str and the optional path is a str or None.
Barry Warsawd7d21942012-07-29 16:36:17 -040061 Returns a Loader object. This method is only called if
62 `find_loader()` is not present.
Raymond Hettingerd958ea72011-01-13 19:08:04 +000063 """
Brett Cannon2a922ed2009-03-09 03:35:50 +000064 raise NotImplementedError
65
Brett Cannon938d44d2012-04-22 19:58:33 -040066_register(Finder, machinery.BuiltinImporter, machinery.FrozenImporter,
67 machinery.PathFinder, machinery.FileFinder)
Brett Cannon2a922ed2009-03-09 03:35:50 +000068
69
Brett Cannon2a922ed2009-03-09 03:35:50 +000070class ResourceLoader(Loader):
71
Brett Cannon7aa21f72009-03-15 00:53:05 +000072 """Abstract base class for loaders which can return data from their
73 back-end storage.
Brett Cannon2a922ed2009-03-09 03:35:50 +000074
75 This ABC represents one of the optional protocols specified by PEP 302.
76
77 """
78
79 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +000080 def get_data(self, path):
Brett Cannon7aa21f72009-03-15 00:53:05 +000081 """Abstract method which when implemented should return the bytes for
Raymond Hettingerd958ea72011-01-13 19:08:04 +000082 the specified path. The path must be a str."""
Brett Cannon2a922ed2009-03-09 03:35:50 +000083 raise NotImplementedError
84
85
86class InspectLoader(Loader):
87
Brett Cannon7aa21f72009-03-15 00:53:05 +000088 """Abstract base class for loaders which support inspection about the
89 modules they can load.
Brett Cannon2a922ed2009-03-09 03:35:50 +000090
91 This ABC represents one of the optional protocols specified by PEP 302.
92
93 """
94
95 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +000096 def is_package(self, fullname):
Brett Cannon7aa21f72009-03-15 00:53:05 +000097 """Abstract method which when implemented should return whether the
Raymond Hettingerd958ea72011-01-13 19:08:04 +000098 module is a package. The fullname is a str. Returns a bool."""
Brett Cannonf23e3742010-06-27 23:57:46 +000099 raise NotImplementedError
Brett Cannon2a922ed2009-03-09 03:35:50 +0000100
101 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000102 def get_code(self, fullname):
Brett Cannon7aa21f72009-03-15 00:53:05 +0000103 """Abstract method which when implemented should return the code object
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000104 for the module. The fullname is a str. Returns a types.CodeType."""
Brett Cannonf23e3742010-06-27 23:57:46 +0000105 raise NotImplementedError
Brett Cannon2a922ed2009-03-09 03:35:50 +0000106
107 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000108 def get_source(self, fullname):
Brett Cannon7aa21f72009-03-15 00:53:05 +0000109 """Abstract method which should return the source code for the
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000110 module. The fullname is a str. Returns a str."""
Brett Cannonf23e3742010-06-27 23:57:46 +0000111 raise NotImplementedError
Brett Cannon2a922ed2009-03-09 03:35:50 +0000112
Brett Cannon938d44d2012-04-22 19:58:33 -0400113_register(InspectLoader, machinery.BuiltinImporter, machinery.FrozenImporter,
114 machinery.ExtensionFileLoader)
Brett Cannona113ac52009-03-15 01:41:33 +0000115
Brett Cannon2a922ed2009-03-09 03:35:50 +0000116
Brett Cannon69194272009-07-20 04:23:48 +0000117class ExecutionLoader(InspectLoader):
118
119 """Abstract base class for loaders that wish to support the execution of
120 modules as scripts.
121
122 This ABC represents one of the optional protocols specified in PEP 302.
123
124 """
125
126 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000127 def get_filename(self, fullname):
Brett Cannon69194272009-07-20 04:23:48 +0000128 """Abstract method which should return the value that __file__ is to be
129 set to."""
130 raise NotImplementedError
131
132
Brett Cannon938d44d2012-04-22 19:58:33 -0400133class FileLoader(_bootstrap.FileLoader, ResourceLoader, ExecutionLoader):
134
135 """Abstract base class partially implementing the ResourceLoader and
136 ExecutionLoader ABCs."""
137
138_register(FileLoader, machinery.SourceFileLoader,
Marc-Andre Lemburg4fe29c92012-04-25 02:31:37 +0200139 machinery.SourcelessFileLoader)
Brett Cannon938d44d2012-04-22 19:58:33 -0400140
141
Brett Cannon0cf9e6a2010-06-28 04:57:24 +0000142class SourceLoader(_bootstrap.SourceLoader, ResourceLoader, ExecutionLoader):
Brett Cannon2a922ed2009-03-09 03:35:50 +0000143
Brett Cannonf23e3742010-06-27 23:57:46 +0000144 """Abstract base class for loading source code (and optionally any
145 corresponding bytecode).
Brett Cannon2a922ed2009-03-09 03:35:50 +0000146
Brett Cannonf23e3742010-06-27 23:57:46 +0000147 To support loading from source code, the abstractmethods inherited from
148 ResourceLoader and ExecutionLoader need to be implemented. To also support
149 loading from bytecode, the optional methods specified directly by this ABC
150 is required.
151
152 Inherited abstractmethods not implemented in this ABC:
153
154 * ResourceLoader.get_data
155 * ExecutionLoader.get_filename
156
157 """
158
Raymond Hettingercd92f372011-01-13 02:31:25 +0000159 def path_mtime(self, path):
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000160 """Return the (int) modification time for the path (str)."""
Antoine Pitrou5136ac02012-01-13 18:52:16 +0100161 if self.path_stats.__func__ is SourceLoader.path_stats:
162 raise NotImplementedError
163 return int(self.path_stats(path)['mtime'])
164
165 def path_stats(self, path):
166 """Return a metadata dict for the source pointed to by the path (str).
167 Possible keys:
168 - 'mtime' (mandatory) is the numeric timestamp of last source
169 code modification;
170 - 'size' (optional) is the size in bytes of the source code.
171 """
172 if self.path_mtime.__func__ is SourceLoader.path_mtime:
173 raise NotImplementedError
174 return {'mtime': self.path_mtime(path)}
Brett Cannon8d189072010-08-22 20:38:47 +0000175
Raymond Hettingercd92f372011-01-13 02:31:25 +0000176 def set_data(self, path, data):
Brett Cannon8d189072010-08-22 20:38:47 +0000177 """Write the bytes to the path (if possible).
178
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000179 Accepts a str path and data as bytes.
180
Brett Cannon8d189072010-08-22 20:38:47 +0000181 Any needed intermediary directories are to be created. If for some
182 reason the file cannot be written because of permissions, fail
183 silently.
184
185 """
186 raise NotImplementedError
187
Brett Cannon938d44d2012-04-22 19:58:33 -0400188_register(SourceLoader, machinery.SourceFileLoader)
Brett Cannonf23e3742010-06-27 23:57:46 +0000189
190class PyLoader(SourceLoader):
191
192 """Implement the deprecated PyLoader ABC in terms of SourceLoader.
193
194 This class has been deprecated! It is slated for removal in Python 3.4.
195 If compatibility with Python 3.1 is not needed then implement the
196 SourceLoader ABC instead of this class. If Python 3.1 compatibility is
197 needed, then use the following idiom to have a single class that is
198 compatible with Python 3.1 onwards::
199
200 try:
201 from importlib.abc import SourceLoader
202 except ImportError:
203 from importlib.abc import PyLoader as SourceLoader
204
205
206 class CustomLoader(SourceLoader):
207 def get_filename(self, fullname):
208 # Implement ...
209
210 def source_path(self, fullname):
211 '''Implement source_path in terms of get_filename.'''
212 try:
213 return self.get_filename(fullname)
214 except ImportError:
215 return None
216
217 def is_package(self, fullname):
218 filename = os.path.basename(self.get_filename(fullname))
219 return os.path.splitext(filename)[0] == '__init__'
Brett Cannon7aa21f72009-03-15 00:53:05 +0000220
221 """
Brett Cannon2a922ed2009-03-09 03:35:50 +0000222
223 @abc.abstractmethod
Brett Cannonf23e3742010-06-27 23:57:46 +0000224 def is_package(self, fullname):
Brett Cannon2a922ed2009-03-09 03:35:50 +0000225 raise NotImplementedError
226
Brett Cannonf23e3742010-06-27 23:57:46 +0000227 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000228 def source_path(self, fullname):
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000229 """Abstract method. Accepts a str module name and returns the path to
230 the source code for the module."""
Brett Cannonf23e3742010-06-27 23:57:46 +0000231 raise NotImplementedError
Brett Cannon2a922ed2009-03-09 03:35:50 +0000232
Brett Cannonf23e3742010-06-27 23:57:46 +0000233 def get_filename(self, fullname):
234 """Implement get_filename in terms of source_path.
235
236 As get_filename should only return a source file path there is no
237 chance of the path not existing but loading still being possible, so
238 ImportError should propagate instead of being turned into returning
239 None.
240
241 """
242 warnings.warn("importlib.abc.PyLoader is deprecated and is "
243 "slated for removal in Python 3.4; "
244 "use SourceLoader instead. "
245 "See the importlib documentation on how to be "
246 "compatible with Python 3.1 onwards.",
Florent Xicluna67317752011-12-10 11:07:42 +0100247 DeprecationWarning)
Brett Cannonf23e3742010-06-27 23:57:46 +0000248 path = self.source_path(fullname)
249 if path is None:
Brett Cannonbbb66802012-04-12 21:09:01 -0400250 raise ImportError(name=fullname)
Brett Cannonf23e3742010-06-27 23:57:46 +0000251 else:
252 return path
253
Brett Cannonf23e3742010-06-27 23:57:46 +0000254
255class PyPycLoader(PyLoader):
Brett Cannon2a922ed2009-03-09 03:35:50 +0000256
Brett Cannon7aa21f72009-03-15 00:53:05 +0000257 """Abstract base class to assist in loading source and bytecode by
258 requiring only back-end storage methods to be implemented.
Brett Cannon2a922ed2009-03-09 03:35:50 +0000259
Brett Cannonf23e3742010-06-27 23:57:46 +0000260 This class has been deprecated! Removal is slated for Python 3.4. Implement
261 the SourceLoader ABC instead. If Python 3.1 compatibility is needed, see
262 PyLoader.
263
Brett Cannon7aa21f72009-03-15 00:53:05 +0000264 The methods get_code, get_source, and load_module are implemented for the
265 user.
266
267 """
Brett Cannon2a922ed2009-03-09 03:35:50 +0000268
Brett Cannonf23e3742010-06-27 23:57:46 +0000269 def get_filename(self, fullname):
270 """Return the source or bytecode file path."""
271 path = self.source_path(fullname)
272 if path is not None:
273 return path
274 path = self.bytecode_path(fullname)
275 if path is not None:
276 return path
277 raise ImportError("no source or bytecode path available for "
Brett Cannonbbb66802012-04-12 21:09:01 -0400278 "{0!r}".format(fullname), name=fullname)
Brett Cannonf23e3742010-06-27 23:57:46 +0000279
280 def get_code(self, fullname):
281 """Get a code object from source or bytecode."""
282 warnings.warn("importlib.abc.PyPycLoader is deprecated and slated for "
283 "removal in Python 3.4; use SourceLoader instead. "
284 "If Python 3.1 compatibility is required, see the "
285 "latest documentation for PyLoader.",
Florent Xicluna67317752011-12-10 11:07:42 +0100286 DeprecationWarning)
Brett Cannonf23e3742010-06-27 23:57:46 +0000287 source_timestamp = self.source_mtime(fullname)
288 # Try to use bytecode if it is available.
289 bytecode_path = self.bytecode_path(fullname)
290 if bytecode_path:
291 data = self.get_data(bytecode_path)
292 try:
293 magic = data[:4]
294 if len(magic) < 4:
Philip Jenvey4b42ff62012-02-24 21:48:17 -0800295 raise ImportError(
Brett Cannonbbb66802012-04-12 21:09:01 -0400296 "bad magic number in {}".format(fullname),
297 name=fullname, path=bytecode_path)
Brett Cannonf23e3742010-06-27 23:57:46 +0000298 raw_timestamp = data[4:8]
299 if len(raw_timestamp) < 4:
300 raise EOFError("bad timestamp in {}".format(fullname))
Brett Cannonc264e3e2012-01-25 18:58:03 -0500301 pyc_timestamp = _bootstrap._r_long(raw_timestamp)
Brett Cannon1e331562012-07-02 14:35:34 -0400302 raw_source_size = data[8:12]
303 if len(raw_source_size) != 4:
304 raise EOFError("bad file size in {}".format(fullname))
305 # Source size is unused as the ABC does not provide a way to
306 # get the size of the source ahead of reading it.
307 bytecode = data[12:]
Brett Cannonf23e3742010-06-27 23:57:46 +0000308 # Verify that the magic number is valid.
309 if imp.get_magic() != magic:
Philip Jenvey4b42ff62012-02-24 21:48:17 -0800310 raise ImportError(
Brett Cannonbbb66802012-04-12 21:09:01 -0400311 "bad magic number in {}".format(fullname),
312 name=fullname, path=bytecode_path)
Brett Cannonf23e3742010-06-27 23:57:46 +0000313 # Verify that the bytecode is not stale (only matters when
314 # there is source to fall back on.
315 if source_timestamp:
316 if pyc_timestamp < source_timestamp:
Brett Cannonbbb66802012-04-12 21:09:01 -0400317 raise ImportError("bytecode is stale", name=fullname,
318 path=bytecode_path)
Brett Cannonf23e3742010-06-27 23:57:46 +0000319 except (ImportError, EOFError):
320 # If source is available give it a shot.
321 if source_timestamp is not None:
322 pass
323 else:
324 raise
325 else:
326 # Bytecode seems fine, so try to use it.
327 return marshal.loads(bytecode)
328 elif source_timestamp is None:
329 raise ImportError("no source or bytecode available to create code "
Brett Cannonbbb66802012-04-12 21:09:01 -0400330 "object for {0!r}".format(fullname),
331 name=fullname)
Brett Cannonf23e3742010-06-27 23:57:46 +0000332 # Use the source.
333 source_path = self.source_path(fullname)
334 if source_path is None:
335 message = "a source path must exist to load {0}".format(fullname)
Brett Cannonbbb66802012-04-12 21:09:01 -0400336 raise ImportError(message, name=fullname)
Brett Cannonf23e3742010-06-27 23:57:46 +0000337 source = self.get_data(source_path)
338 code_object = compile(source, source_path, 'exec', dont_inherit=True)
339 # Generate bytecode and write it out.
340 if not sys.dont_write_bytecode:
341 data = bytearray(imp.get_magic())
Brett Cannonc264e3e2012-01-25 18:58:03 -0500342 data.extend(_bootstrap._w_long(source_timestamp))
Brett Cannon1e331562012-07-02 14:35:34 -0400343 data.extend(_bootstrap._w_long(len(source) & 0xFFFFFFFF))
Brett Cannonf23e3742010-06-27 23:57:46 +0000344 data.extend(marshal.dumps(code_object))
345 self.write_bytecode(fullname, data)
346 return code_object
347
Brett Cannon2a922ed2009-03-09 03:35:50 +0000348 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000349 def source_mtime(self, fullname):
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000350 """Abstract method. Accepts a str filename and returns an int
Brett Cannon7aa21f72009-03-15 00:53:05 +0000351 modification time for the source of the module."""
Brett Cannon2a922ed2009-03-09 03:35:50 +0000352 raise NotImplementedError
353
354 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000355 def bytecode_path(self, fullname):
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000356 """Abstract method. Accepts a str filename and returns the str pathname
357 to the bytecode for the module."""
Brett Cannon2a922ed2009-03-09 03:35:50 +0000358 raise NotImplementedError
359
360 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000361 def write_bytecode(self, fullname, bytecode):
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000362 """Abstract method. Accepts a str filename and bytes object
363 representing the bytecode for the module. Returns a boolean
364 representing whether the bytecode was written or not."""
Brett Cannon2a922ed2009-03-09 03:35:50 +0000365 raise NotImplementedError