blob: cf20e9fe1af8e0a921797f150c244fbd83b77af7 [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
Brett Cannon0a140662013-06-13 20:57:26 -04006except ModuleNotFoundError as exc:
Brett Cannon938d44d2012-04-22 19:58:33 -04007 if exc.name != '_frozen_importlib':
8 raise
9 _frozen_importlib = None
Brett Cannon2a922ed2009-03-09 03:35:50 +000010import abc
Brett Cannon2a922ed2009-03-09 03:35:50 +000011
12
Brett Cannon938d44d2012-04-22 19:58:33 -040013def _register(abstract_cls, *classes):
14 for cls in classes:
15 abstract_cls.register(cls)
16 if _frozen_importlib is not None:
17 frozen_cls = getattr(_frozen_importlib, cls.__name__)
18 abstract_cls.register(frozen_cls)
19
20
Nick Coghlan8a9080f2012-08-02 21:26:03 +100021class Finder(metaclass=abc.ABCMeta):
22
Brett Cannonf4dc9202012-08-10 12:21:12 -040023 """Legacy abstract base class for import finders.
Nick Coghlan8a9080f2012-08-02 21:26:03 +100024
Brett Cannonf4dc9202012-08-10 12:21:12 -040025 It may be subclassed for compatibility with legacy third party
26 reimplementations of the import system. Otherwise, finder
27 implementations should derive from the more specific MetaPathFinder
28 or PathEntryFinder ABCs.
Nick Coghlan8a9080f2012-08-02 21:26:03 +100029 """
30
Brett Cannonf4dc9202012-08-10 12:21:12 -040031 @abc.abstractmethod
Nick Coghlan8a9080f2012-08-02 21:26:03 +100032 def find_module(self, fullname, path=None):
Brett Cannonf4dc9202012-08-10 12:21:12 -040033 """An abstract method that should find a module.
Nick Coghlan8a9080f2012-08-02 21:26:03 +100034 The fullname is a str and the optional path is a str or None.
Brett Cannon100883f2013-04-09 16:59:39 -040035 Returns a Loader object or None.
Nick Coghlan8a9080f2012-08-02 21:26:03 +100036 """
Nick Coghlan8a9080f2012-08-02 21:26:03 +100037
Nick Coghlan8a9080f2012-08-02 21:26:03 +100038
39class MetaPathFinder(Finder):
40
41 """Abstract base class for import finders on sys.meta_path."""
42
43 @abc.abstractmethod
44 def find_module(self, fullname, path):
Brett Cannonf4dc9202012-08-10 12:21:12 -040045 """Abstract method which, when implemented, should find a module.
Brett Cannon100883f2013-04-09 16:59:39 -040046 The fullname is a str and the path is a list of strings or None.
47 Returns a Loader object or None.
Nick Coghlan8a9080f2012-08-02 21:26:03 +100048 """
Nick Coghlan8a9080f2012-08-02 21:26:03 +100049
Brett Cannonf4dc9202012-08-10 12:21:12 -040050 def invalidate_caches(self):
51 """An optional method for clearing the finder's cache, if any.
52 This method is used by importlib.invalidate_caches().
53 """
Brett Cannonf4dc9202012-08-10 12:21:12 -040054
Nick Coghlan8a9080f2012-08-02 21:26:03 +100055_register(MetaPathFinder, machinery.BuiltinImporter, machinery.FrozenImporter,
Nick Coghlanff794862012-08-02 21:45:24 +100056 machinery.PathFinder, machinery.WindowsRegistryFinder)
Nick Coghlan8a9080f2012-08-02 21:26:03 +100057
58
59class PathEntryFinder(Finder):
60
61 """Abstract base class for path entry finders used by PathFinder."""
62
63 @abc.abstractmethod
64 def find_loader(self, fullname):
Brett Cannon100883f2013-04-09 16:59:39 -040065 """Abstract method which, when implemented, returns a module loader or
66 a possible part of a namespace.
Nick Coghlan8a9080f2012-08-02 21:26:03 +100067 The fullname is a str. Returns a 2-tuple of (Loader, portion) where
68 portion is a sequence of file system locations contributing to part of
Brett Cannonf1d7b112013-05-31 18:39:07 -040069 a namespace package. The sequence may be empty and the loader may be
Brett Cannonf4dc9202012-08-10 12:21:12 -040070 None.
Nick Coghlan8a9080f2012-08-02 21:26:03 +100071 """
Brett Cannon100883f2013-04-09 16:59:39 -040072 return None, []
Nick Coghlan8a9080f2012-08-02 21:26:03 +100073
Brett Cannonf410ce82012-08-10 17:41:23 -040074 find_module = _bootstrap._find_module_shim
Brett Cannonf4dc9202012-08-10 12:21:12 -040075
76 def invalidate_caches(self):
77 """An optional method for clearing the finder's cache, if any.
78 This method is used by PathFinder.invalidate_caches().
79 """
Brett Cannonf4dc9202012-08-10 12:21:12 -040080
Nick Coghlan8a9080f2012-08-02 21:26:03 +100081_register(PathEntryFinder, machinery.FileFinder)
82
83
Brett Cannon2a922ed2009-03-09 03:35:50 +000084class Loader(metaclass=abc.ABCMeta):
85
Brett Cannon100883f2013-04-09 16:59:39 -040086 """Abstract base class for import loaders.
87
88 The optional method module_repr(module) may be defined to provide a
89 repr for a module when appropriate (see PEP 420). The __repr__() method on
90 the module type will use the method as appropriate.
91
92 """
Brett Cannon2a922ed2009-03-09 03:35:50 +000093
Brett Cannon7aa21f72009-03-15 00:53:05 +000094 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +000095 def load_module(self, fullname):
Raymond Hettingerd958ea72011-01-13 19:08:04 +000096 """Abstract method which when implemented should load a module.
Brett Cannon100883f2013-04-09 16:59:39 -040097 The fullname is a str.
Brett Cannon2a922ed2009-03-09 03:35:50 +000098
Brett Cannon100883f2013-04-09 16:59:39 -040099 ImportError is raised on failure.
100 """
101 raise ImportError
102
Barry Warsawd7d21942012-07-29 16:36:17 -0400103 def module_repr(self, module):
Brett Cannon100883f2013-04-09 16:59:39 -0400104 """Return a module's repr.
105
Brett Cannonf1d7b112013-05-31 18:39:07 -0400106 Used by the module type when the method does not raise
107 NotImplementedError.
Brett Cannon100883f2013-04-09 16:59:39 -0400108 """
Barry Warsawd7d21942012-07-29 16:36:17 -0400109 raise NotImplementedError
110
Brett Cannon0dbb4c72013-05-31 18:56:47 -0400111 def init_module_attrs(self, module):
112 """Set the module's __loader__ attribute."""
113 module.__loader__ = self
114
Brett Cannon2a922ed2009-03-09 03:35:50 +0000115
Brett Cannon2a922ed2009-03-09 03:35:50 +0000116class ResourceLoader(Loader):
117
Brett Cannon7aa21f72009-03-15 00:53:05 +0000118 """Abstract base class for loaders which can return data from their
119 back-end storage.
Brett Cannon2a922ed2009-03-09 03:35:50 +0000120
121 This ABC represents one of the optional protocols specified by PEP 302.
122
123 """
124
125 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000126 def get_data(self, path):
Brett Cannon7aa21f72009-03-15 00:53:05 +0000127 """Abstract method which when implemented should return the bytes for
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000128 the specified path. The path must be a str."""
Brett Cannon100883f2013-04-09 16:59:39 -0400129 raise IOError
Brett Cannon2a922ed2009-03-09 03:35:50 +0000130
131
132class InspectLoader(Loader):
133
Brett Cannon7aa21f72009-03-15 00:53:05 +0000134 """Abstract base class for loaders which support inspection about the
135 modules they can load.
Brett Cannon2a922ed2009-03-09 03:35:50 +0000136
137 This ABC represents one of the optional protocols specified by PEP 302.
138
139 """
140
141 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000142 def is_package(self, fullname):
Brett Cannon7aa21f72009-03-15 00:53:05 +0000143 """Abstract method which when implemented should return whether the
Brett Cannon100883f2013-04-09 16:59:39 -0400144 module is a package. The fullname is a str. Returns a bool.
145
146 Raises ImportError is the module cannot be found.
147 """
148 raise ImportError
Brett Cannon2a922ed2009-03-09 03:35:50 +0000149
Raymond Hettingercd92f372011-01-13 02:31:25 +0000150 def get_code(self, fullname):
Brett Cannon3b62ca82013-05-27 21:11:04 -0400151 """Method which returns the code object for the module.
Brett Cannon100883f2013-04-09 16:59:39 -0400152
Brett Cannon3b62ca82013-05-27 21:11:04 -0400153 The fullname is a str. Returns a types.CodeType if possible, else
154 returns None if a code object does not make sense
155 (e.g. built-in module). Raises ImportError if the module cannot be
156 found.
Brett Cannon100883f2013-04-09 16:59:39 -0400157 """
Brett Cannon3b62ca82013-05-27 21:11:04 -0400158 source = self.get_source(fullname)
159 if source is None:
160 return None
161 return self.source_to_code(source)
Brett Cannon2a922ed2009-03-09 03:35:50 +0000162
163 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000164 def get_source(self, fullname):
Brett Cannon7aa21f72009-03-15 00:53:05 +0000165 """Abstract method which should return the source code for the
Brett Cannon100883f2013-04-09 16:59:39 -0400166 module. The fullname is a str. Returns a str.
167
168 Raises ImportError if the module cannot be found.
169 """
170 raise ImportError
Brett Cannon2a922ed2009-03-09 03:35:50 +0000171
Brett Cannon9ffe85e2013-05-26 16:45:10 -0400172 def source_to_code(self, data, path='<string>'):
173 """Compile 'data' into a code object.
174
175 The 'data' argument can be anything that compile() can handle. The'path'
176 argument should be where the data was retrieved (when applicable)."""
177 return compile(data, path, 'exec', dont_inherit=True)
178
Brett Cannon0dbb4c72013-05-31 18:56:47 -0400179 def init_module_attrs(self, module):
180 """Initialize the __loader__ and __package__ attributes of the module.
181
182 The name of the module is gleaned from module.__name__. The __package__
183 attribute is set based on self.is_package().
184 """
185 super().init_module_attrs(module)
186 _bootstrap._init_package_attrs(self, module)
187
188 load_module = _bootstrap._LoaderBasics.load_module
189
Brett Cannon938d44d2012-04-22 19:58:33 -0400190_register(InspectLoader, machinery.BuiltinImporter, machinery.FrozenImporter,
191 machinery.ExtensionFileLoader)
Brett Cannona113ac52009-03-15 01:41:33 +0000192
Brett Cannon2a922ed2009-03-09 03:35:50 +0000193
Brett Cannon69194272009-07-20 04:23:48 +0000194class ExecutionLoader(InspectLoader):
195
196 """Abstract base class for loaders that wish to support the execution of
197 modules as scripts.
198
199 This ABC represents one of the optional protocols specified in PEP 302.
200
201 """
202
203 @abc.abstractmethod
Raymond Hettingercd92f372011-01-13 02:31:25 +0000204 def get_filename(self, fullname):
Brett Cannon69194272009-07-20 04:23:48 +0000205 """Abstract method which should return the value that __file__ is to be
Brett Cannon100883f2013-04-09 16:59:39 -0400206 set to.
207
208 Raises ImportError if the module cannot be found.
209 """
210 raise ImportError
Brett Cannon69194272009-07-20 04:23:48 +0000211
Brett Cannon3b62ca82013-05-27 21:11:04 -0400212 def get_code(self, fullname):
213 """Method to return the code object for fullname.
214
215 Should return None if not applicable (e.g. built-in module).
216 Raise ImportError if the module cannot be found.
217 """
218 source = self.get_source(fullname)
219 if source is None:
220 return None
221 try:
222 path = self.get_filename(fullname)
223 except ImportError:
224 return self.source_to_code(source)
225 else:
226 return self.source_to_code(source, path)
227
Brett Cannon0dbb4c72013-05-31 18:56:47 -0400228 def init_module_attrs(self, module):
229 """Initialize the module's attributes.
230
231 It is assumed that the module's name has been set on module.__name__.
232 It is also assumed that any path returned by self.get_filename() uses
233 (one of) the operating system's path separator(s) to separate filenames
234 from directories in order to set __path__ intelligently.
235 InspectLoader.init_module_attrs() sets __loader__ and __package__.
236 """
237 super().init_module_attrs(module)
238 _bootstrap._init_file_attrs(self, module)
239
Brett Cannon69194272009-07-20 04:23:48 +0000240
Brett Cannon938d44d2012-04-22 19:58:33 -0400241class FileLoader(_bootstrap.FileLoader, ResourceLoader, ExecutionLoader):
242
243 """Abstract base class partially implementing the ResourceLoader and
244 ExecutionLoader ABCs."""
245
246_register(FileLoader, machinery.SourceFileLoader,
Marc-Andre Lemburg4fe29c92012-04-25 02:31:37 +0200247 machinery.SourcelessFileLoader)
Brett Cannon938d44d2012-04-22 19:58:33 -0400248
249
Brett Cannon0cf9e6a2010-06-28 04:57:24 +0000250class SourceLoader(_bootstrap.SourceLoader, ResourceLoader, ExecutionLoader):
Brett Cannon2a922ed2009-03-09 03:35:50 +0000251
Brett Cannonf23e3742010-06-27 23:57:46 +0000252 """Abstract base class for loading source code (and optionally any
253 corresponding bytecode).
Brett Cannon2a922ed2009-03-09 03:35:50 +0000254
Brett Cannonf23e3742010-06-27 23:57:46 +0000255 To support loading from source code, the abstractmethods inherited from
256 ResourceLoader and ExecutionLoader need to be implemented. To also support
257 loading from bytecode, the optional methods specified directly by this ABC
258 is required.
259
260 Inherited abstractmethods not implemented in this ABC:
261
262 * ResourceLoader.get_data
263 * ExecutionLoader.get_filename
264
265 """
266
Raymond Hettingercd92f372011-01-13 02:31:25 +0000267 def path_mtime(self, path):
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000268 """Return the (int) modification time for the path (str)."""
Antoine Pitrou5136ac02012-01-13 18:52:16 +0100269 if self.path_stats.__func__ is SourceLoader.path_stats:
Brett Cannon100883f2013-04-09 16:59:39 -0400270 raise IOError
Antoine Pitrou5136ac02012-01-13 18:52:16 +0100271 return int(self.path_stats(path)['mtime'])
272
273 def path_stats(self, path):
274 """Return a metadata dict for the source pointed to by the path (str).
275 Possible keys:
276 - 'mtime' (mandatory) is the numeric timestamp of last source
277 code modification;
278 - 'size' (optional) is the size in bytes of the source code.
279 """
280 if self.path_mtime.__func__ is SourceLoader.path_mtime:
Brett Cannon100883f2013-04-09 16:59:39 -0400281 raise IOError
Antoine Pitrou5136ac02012-01-13 18:52:16 +0100282 return {'mtime': self.path_mtime(path)}
Brett Cannon8d189072010-08-22 20:38:47 +0000283
Raymond Hettingercd92f372011-01-13 02:31:25 +0000284 def set_data(self, path, data):
Brett Cannon8d189072010-08-22 20:38:47 +0000285 """Write the bytes to the path (if possible).
286
Raymond Hettingerd958ea72011-01-13 19:08:04 +0000287 Accepts a str path and data as bytes.
288
Brett Cannon8d189072010-08-22 20:38:47 +0000289 Any needed intermediary directories are to be created. If for some
290 reason the file cannot be written because of permissions, fail
291 silently.
Brett Cannon8d189072010-08-22 20:38:47 +0000292 """
Brett Cannon8d189072010-08-22 20:38:47 +0000293
Brett Cannon938d44d2012-04-22 19:58:33 -0400294_register(SourceLoader, machinery.SourceFileLoader)