|
| 1 | +.. class:: ResourceReader |
| 2 | + |
| 3 | + *Superseded by TraversableResources* |
| 4 | + |
| 5 | + An :term:`abstract base class` to provide the ability to read |
| 6 | + *resources*. |
| 7 | + |
| 8 | + From the perspective of this ABC, a *resource* is a binary |
| 9 | + artifact that is shipped within a package. Typically this is |
| 10 | + something like a data file that lives next to the ``__init__.py`` |
| 11 | + file of the package. The purpose of this class is to help abstract |
| 12 | + out the accessing of such data files so that it does not matter if |
| 13 | + the package and its data file(s) are stored in a e.g. zip file |
| 14 | + versus on the file system. |
| 15 | + |
| 16 | + For any of methods of this class, a *resource* argument is |
| 17 | + expected to be a :term:`path-like object` which represents |
| 18 | + conceptually just a file name. This means that no subdirectory |
| 19 | + paths should be included in the *resource* argument. This is |
| 20 | + because the location of the package the reader is for, acts as the |
| 21 | + "directory". Hence the metaphor for directories and file |
| 22 | + names is packages and resources, respectively. This is also why |
| 23 | + instances of this class are expected to directly correlate to |
| 24 | + a specific package (instead of potentially representing multiple |
| 25 | + packages or a module). |
| 26 | + |
| 27 | + Loaders that wish to support resource reading are expected to |
| 28 | + provide a method called ``get_resource_reader(fullname)`` which |
| 29 | + returns an object implementing this ABC's interface. If the module |
| 30 | + specified by fullname is not a package, this method should return |
| 31 | + :const:`None`. An object compatible with this ABC should only be |
| 32 | + returned when the specified module is a package. |
| 33 | + |
| 34 | + .. versionadded:: 3.7 |
| 35 | + |
| 36 | + .. abstractmethod:: open_resource(resource) |
| 37 | + |
| 38 | + Returns an opened, :term:`file-like object` for binary reading |
| 39 | + of the *resource*. |
| 40 | + |
| 41 | + If the resource cannot be found, :exc:`FileNotFoundError` is |
| 42 | + raised. |
| 43 | + |
| 44 | + .. abstractmethod:: resource_path(resource) |
| 45 | + |
| 46 | + Returns the file system path to the *resource*. |
| 47 | + |
| 48 | + If the resource does not concretely exist on the file system, |
| 49 | + raise :exc:`FileNotFoundError`. |
| 50 | + |
| 51 | + .. abstractmethod:: is_resource(name) |
| 52 | + |
| 53 | + Returns ``True`` if the named *name* is considered a resource. |
| 54 | + :exc:`FileNotFoundError` is raised if *name* does not exist. |
| 55 | + |
| 56 | + .. abstractmethod:: contents() |
| 57 | + |
| 58 | + Returns an :term:`iterable` of strings over the contents of |
| 59 | + the package. Do note that it is not required that all names |
| 60 | + returned by the iterator be actual resources, e.g. it is |
| 61 | + acceptable to return names for which :meth:`is_resource` would |
| 62 | + be false. |
| 63 | + |
| 64 | + Allowing non-resource names to be returned is to allow for |
| 65 | + situations where how a package and its resources are stored |
| 66 | + are known a priori and the non-resource names would be useful. |
| 67 | + For instance, returning subdirectory names is allowed so that |
| 68 | + when it is known that the package and resources are stored on |
| 69 | + the file system then those subdirectory names can be used |
| 70 | + directly. |
| 71 | + |
| 72 | + The abstract method returns an iterable of no items. |
| 73 | + |
| 74 | + |
| 75 | +.. class:: ResourceLoader |
| 76 | + |
| 77 | + An abstract base class for a :term:`loader` which implements the optional |
| 78 | + :pep:`302` protocol for loading arbitrary resources from the storage |
| 79 | + back-end. |
| 80 | + |
| 81 | + .. deprecated:: 3.7 |
| 82 | + This ABC is deprecated in favour of supporting resource loading |
| 83 | + through :class:`importlib.abc.ResourceReader`. |
| 84 | + |
| 85 | + .. abstractmethod:: get_data(path) |
| 86 | + |
| 87 | + An abstract method to return the bytes for the data located at *path*. |
| 88 | + Loaders that have a file-like storage back-end |
| 89 | + that allows storing arbitrary data |
| 90 | + can implement this abstract method to give direct access |
| 91 | + to the data stored. :exc:`OSError` is to be raised if the *path* cannot |
| 92 | + be found. The *path* is expected to be constructed using a module's |
| 93 | + :attr:`__file__` attribute or an item from a package's :attr:`__path__`. |
| 94 | + |
| 95 | + .. versionchanged:: 3.4 |
| 96 | + Raises :exc:`OSError` instead of :exc:`NotImplementedError`. |
| 97 | + |
| 98 | + |
| 99 | +.. class:: InspectLoader |
| 100 | + |
| 101 | + An abstract base class for a :term:`loader` which implements the optional |
| 102 | + :pep:`302` protocol for loaders that inspect modules. |
| 103 | + |
| 104 | + .. method:: get_code(fullname) |
| 105 | + |
| 106 | + Return the code object for a module, or ``None`` if the module does not |
| 107 | + have a code object (as would be the case, for example, for a built-in |
| 108 | + module). Raise an :exc:`ImportError` if loader cannot find the |
| 109 | + requested module. |
| 110 | + |
| 111 | + .. note:: |
| 112 | + While the method has a default implementation, it is suggested that |
| 113 | + it be overridden if possible for performance. |
| 114 | + |
| 115 | + .. index:: |
| 116 | + single: universal newlines; importlib.abc.InspectLoader.get_source method |
| 117 | + |
| 118 | + .. versionchanged:: 3.4 |
| 119 | + No longer abstract and a concrete implementation is provided. |
| 120 | + |
| 121 | + .. abstractmethod:: get_source(fullname) |
| 122 | + |
| 123 | + An abstract method to return the source of a module. It is returned as |
| 124 | + a text string using :term:`universal newlines`, translating all |
| 125 | + recognized line separators into ``'\n'`` characters. Returns ``None`` |
| 126 | + if no source is available (e.g. a built-in module). Raises |
| 127 | + :exc:`ImportError` if the loader cannot find the module specified. |
| 128 | + |
| 129 | + .. versionchanged:: 3.4 |
| 130 | + Raises :exc:`ImportError` instead of :exc:`NotImplementedError`. |
| 131 | + |
| 132 | + .. method:: is_package(fullname) |
| 133 | + |
| 134 | + An optional method to return a true value if the module is a package, a |
| 135 | + false value otherwise. :exc:`ImportError` is raised if the |
| 136 | + :term:`loader` cannot find the module. |
| 137 | + |
| 138 | + .. versionchanged:: 3.4 |
| 139 | + Raises :exc:`ImportError` instead of :exc:`NotImplementedError`. |
| 140 | + |
| 141 | + .. staticmethod:: source_to_code(data, path='<string>') |
| 142 | + |
| 143 | + Create a code object from Python source. |
| 144 | + |
| 145 | + The *data* argument can be whatever the :func:`compile` function |
| 146 | + supports (i.e. string or bytes). The *path* argument should be |
| 147 | + the "path" to where the source code originated from, which can be an |
| 148 | + abstract concept (e.g. location in a zip file). |
| 149 | + |
| 150 | + With the subsequent code object one can execute it in a module by |
| 151 | + running ``exec(code, module.__dict__)``. |
| 152 | + |
| 153 | + .. versionadded:: 3.4 |
| 154 | + |
| 155 | + .. versionchanged:: 3.5 |
| 156 | + Made the method static. |
| 157 | + |
| 158 | + .. method:: exec_module(module) |
| 159 | + |
| 160 | + Implementation of :meth:`Loader.exec_module`. |
| 161 | + |
| 162 | + .. versionadded:: 3.4 |
| 163 | + |
| 164 | + .. method:: load_module(fullname) |
| 165 | + |
| 166 | + Implementation of :meth:`Loader.load_module`. |
| 167 | + |
| 168 | + .. deprecated:: 3.4 |
| 169 | + use :meth:`exec_module` instead. |
| 170 | + |
| 171 | + |
| 172 | +.. class:: ExecutionLoader |
| 173 | + |
| 174 | + An abstract base class which inherits from :class:`InspectLoader` that, |
| 175 | + when implemented, helps a module to be executed as a script. The ABC |
| 176 | + represents an optional :pep:`302` protocol. |
| 177 | + |
| 178 | + .. abstractmethod:: get_filename(fullname) |
| 179 | + |
| 180 | + An abstract method that is to return the value of :attr:`__file__` for |
| 181 | + the specified module. If no path is available, :exc:`ImportError` is |
| 182 | + raised. |
| 183 | + |
| 184 | + If source code is available, then the method should return the path to |
| 185 | + the source file, regardless of whether a bytecode was used to load the |
| 186 | + module. |
| 187 | + |
| 188 | + .. versionchanged:: 3.4 |
| 189 | + Raises :exc:`ImportError` instead of :exc:`NotImplementedError`. |
| 190 | + |
| 191 | + |
| 192 | +.. class:: FileLoader(fullname, path) |
| 193 | + |
| 194 | + An abstract base class which inherits from :class:`ResourceLoader` and |
| 195 | + :class:`ExecutionLoader`, providing concrete implementations of |
| 196 | + :meth:`ResourceLoader.get_data` and :meth:`ExecutionLoader.get_filename`. |
| 197 | + |
| 198 | + The *fullname* argument is a fully resolved name of the module the loader is |
| 199 | + to handle. The *path* argument is the path to the file for the module. |
| 200 | + |
| 201 | + .. versionadded:: 3.3 |
| 202 | + |
| 203 | + .. attribute:: name |
| 204 | + |
| 205 | + The name of the module the loader can handle. |
| 206 | + |
| 207 | + .. attribute:: path |
| 208 | + |
| 209 | + Path to the file of the module. |
| 210 | + |
| 211 | + .. method:: load_module(fullname) |
| 212 | + |
| 213 | + Calls super's ``load_module()``. |
| 214 | + |
| 215 | + .. deprecated:: 3.4 |
| 216 | + Use :meth:`Loader.exec_module` instead. |
| 217 | + |
| 218 | + .. abstractmethod:: get_filename(fullname) |
| 219 | + |
| 220 | + Returns :attr:`path`. |
| 221 | + |
| 222 | + .. abstractmethod:: get_data(path) |
| 223 | + |
| 224 | + Reads *path* as a binary file and returns the bytes from it. |
| 225 | + |
| 226 | + |
| 227 | +.. class:: SourceLoader |
| 228 | + |
| 229 | + An abstract base class for implementing source (and optionally bytecode) |
| 230 | + file loading. The class inherits from both :class:`ResourceLoader` and |
| 231 | + :class:`ExecutionLoader`, requiring the implementation of: |
| 232 | + |
| 233 | + * :meth:`ResourceLoader.get_data` |
| 234 | + * :meth:`ExecutionLoader.get_filename` |
| 235 | + Should only return the path to the source file; sourceless |
| 236 | + loading is not supported. |
| 237 | + |
| 238 | + The abstract methods defined by this class are to add optional bytecode |
| 239 | + file support. Not implementing these optional methods (or causing them to |
| 240 | + raise :exc:`NotImplementedError`) causes the loader to |
| 241 | + only work with source code. Implementing the methods allows the loader to |
| 242 | + work with source *and* bytecode files; it does not allow for *sourceless* |
| 243 | + loading where only bytecode is provided. Bytecode files are an |
| 244 | + optimization to speed up loading by removing the parsing step of Python's |
| 245 | + compiler, and so no bytecode-specific API is exposed. |
| 246 | + |
| 247 | + .. method:: path_stats(path) |
| 248 | + |
| 249 | + Optional abstract method which returns a :class:`dict` containing |
| 250 | + metadata about the specified path. Supported dictionary keys are: |
| 251 | + |
| 252 | + - ``'mtime'`` (mandatory): an integer or floating-point number |
| 253 | + representing the modification time of the source code; |
| 254 | + - ``'size'`` (optional): the size in bytes of the source code. |
| 255 | + |
| 256 | + Any other keys in the dictionary are ignored, to allow for future |
| 257 | + extensions. If the path cannot be handled, :exc:`OSError` is raised. |
| 258 | + |
| 259 | + .. versionadded:: 3.3 |
| 260 | + |
| 261 | + .. versionchanged:: 3.4 |
| 262 | + Raise :exc:`OSError` instead of :exc:`NotImplementedError`. |
| 263 | + |
| 264 | + .. method:: path_mtime(path) |
| 265 | + |
| 266 | + Optional abstract method which returns the modification time for the |
| 267 | + specified path. |
| 268 | + |
| 269 | + .. deprecated:: 3.3 |
| 270 | + This method is deprecated in favour of :meth:`path_stats`. You don't |
| 271 | + have to implement it, but it is still available for compatibility |
| 272 | + purposes. Raise :exc:`OSError` if the path cannot be handled. |
| 273 | + |
| 274 | + .. versionchanged:: 3.4 |
| 275 | + Raise :exc:`OSError` instead of :exc:`NotImplementedError`. |
| 276 | + |
| 277 | + .. method:: set_data(path, data) |
| 278 | + |
| 279 | + Optional abstract method which writes the specified bytes to a file |
| 280 | + path. Any intermediate directories which do not exist are to be created |
| 281 | + automatically. |
| 282 | + |
| 283 | + When writing to the path fails because the path is read-only |
| 284 | + (:attr:`errno.EACCES`/:exc:`PermissionError`), do not propagate the |
| 285 | + exception. |
| 286 | + |
| 287 | + .. versionchanged:: 3.4 |
| 288 | + No longer raises :exc:`NotImplementedError` when called. |
| 289 | + |
| 290 | + .. method:: get_code(fullname) |
| 291 | + |
| 292 | + Concrete implementation of :meth:`InspectLoader.get_code`. |
| 293 | + |
| 294 | + .. method:: exec_module(module) |
| 295 | + |
| 296 | + Concrete implementation of :meth:`Loader.exec_module`. |
| 297 | + |
| 298 | + .. versionadded:: 3.4 |
| 299 | + |
| 300 | + .. method:: load_module(fullname) |
| 301 | + |
| 302 | + Concrete implementation of :meth:`Loader.load_module`. |
| 303 | + |
| 304 | + .. deprecated:: 3.4 |
| 305 | + Use :meth:`exec_module` instead. |
| 306 | + |
| 307 | + .. method:: get_source(fullname) |
| 308 | + |
| 309 | + Concrete implementation of :meth:`InspectLoader.get_source`. |
| 310 | + |
| 311 | + .. method:: is_package(fullname) |
| 312 | + |
| 313 | + Concrete implementation of :meth:`InspectLoader.is_package`. A module |
| 314 | + is determined to be a package if its file path (as provided by |
| 315 | + :meth:`ExecutionLoader.get_filename`) is a file named |
| 316 | + ``__init__`` when the file extension is removed **and** the module name |
| 317 | + itself does not end in ``__init__``. |
| 318 | + |
| 319 | + |
| 320 | +.. class:: Traversable |
| 321 | + |
| 322 | + An object with a subset of pathlib.Path methods suitable for |
| 323 | + traversing directories and opening files. |
| 324 | + |
| 325 | + .. versionadded:: 3.9 |
| 326 | + |
| 327 | + .. attribute:: name |
| 328 | + |
| 329 | + Abstract. The base name of this object without any parent references. |
| 330 | + |
| 331 | + .. abstractmethod:: iterdir() |
| 332 | + |
| 333 | + Yield Traversable objects in self. |
| 334 | + |
| 335 | + .. abstractmethod:: is_dir() |
| 336 | + |
| 337 | + Return True if self is a directory. |
| 338 | + |
| 339 | + .. abstractmethod:: is_file() |
| 340 | + |
| 341 | + Return True if self is a file. |
| 342 | + |
| 343 | + .. abstractmethod:: joinpath(child) |
| 344 | + |
| 345 | + Return Traversable child in self. |
| 346 | + |
| 347 | + .. abstractmethod:: __truediv__(child) |
| 348 | + |
| 349 | + Return Traversable child in self. |
| 350 | + |
| 351 | + .. abstractmethod:: open(mode='r', *args, **kwargs) |
| 352 | + |
| 353 | + *mode* may be 'r' or 'rb' to open as text or binary. Return a handle |
| 354 | + suitable for reading (same as :attr:`pathlib.Path.open`). |
| 355 | + |
| 356 | + When opening as text, accepts encoding parameters such as those |
| 357 | + accepted by :attr:`io.TextIOWrapper`. |
| 358 | + |
| 359 | + .. method:: read_bytes() |
| 360 | + |
| 361 | + Read contents of self as bytes. |
| 362 | + |
| 363 | + .. method:: read_text(encoding=None) |
| 364 | + |
| 365 | + Read contents of self as text. |
| 366 | + |
| 367 | + |
| 368 | +.. class:: TraversableResources |
| 369 | + |
| 370 | + An abstract base class for resource readers capable of serving |
| 371 | + the :meth:`importlib.resources.files` interface. Subclasses |
| 372 | + :class:`importlib.abc.ResourceReader` and provides |
| 373 | + concrete implementations of the :class:`importlib.abc.ResourceReader`'s |
| 374 | + abstract methods. Therefore, any loader supplying |
| 375 | + :class:`importlib.abc.TraversableReader` also supplies ResourceReader. |
| 376 | + |
| 377 | + Loaders that wish to support resource reading are expected to |
| 378 | + implement this interface. |
| 379 | + |
| 380 | + .. versionadded:: 3.9 |
| 381 | + |
| 382 | + .. abstractmethod:: files() |
| 383 | + |
| 384 | + Returns a :class:`importlib.abc.Traversable` object for the loaded |
| 385 | + package. |
0 commit comments