Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 938d44d

Browse files
committed
Issue #14605: Expose importlib.abc.FileLoader and
importlib.machinery.(FileFinder, SourceFileLoader, _SourcelessFileLoader, ExtensionFileLoader). This exposes all of importlib's mechanisms that will become public on the sys module.
1 parent 8c5e920 commit 938d44d

17 files changed

Lines changed: 3232 additions & 3062 deletions

Doc/library/importlib.rst

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,34 @@ are also provided to help in implementing the core ABCs.
237237
module.
238238

239239

240+
.. class:: FileLoader(fullname, path)
241+
242+
An abstract base class which inherits from :class:`ResourceLoader` and
243+
:class:`ExecutionLoader`, providing concreate implementations of
244+
:meth:`ResourceLoader.get_data` and :meth:`ExecutionLoader.get_filename`.
245+
246+
The *fullname* argument is a fully resolved name of the module the loader is
247+
to handle. The *path* argument is the path to the file for the module.
248+
249+
.. versionadded:: 3.3
250+
251+
.. attribute:: name
252+
253+
The name of the module the loader can handle.
254+
255+
.. attribute:: path
256+
257+
Path to the file of the module.
258+
259+
.. method:: get_filename(fullname)
260+
261+
Returns :attr:`path`.
262+
263+
.. method:: get_data(path)
264+
265+
Returns the open, binary file for *path*.
266+
267+
240268
.. class:: SourceLoader
241269

242270
An abstract base class for implementing source (and optionally bytecode)
@@ -498,6 +526,163 @@ find and load modules.
498526
module. If no finder is ever found then ``None`` is returned.
499527

500528

529+
.. class:: FileFinder(path, \*loader_details)
530+
531+
A concrete implementation of :class:`importlib.abc.Finder` which caches
532+
results from the file system.
533+
534+
The *path* argument is the directory for which the finder is in charge of
535+
searching.
536+
537+
The *loader_details* argument is a variable number of 3-item tuples each
538+
containing a loader, file suffixes the loader recognizes, and a boolean
539+
representing whether the loader handles packages.
540+
541+
The finder will cache the directory contents as necessary, making stat calls
542+
for each module search to verify the cache is not outdated. Because cache
543+
staleness relies upon the granularity of the operating system's state
544+
information of the file system, there is a potential race condition of
545+
searching for a module, creating a new file, and then searching for the
546+
module the new file represents. If the operations happen fast enough to fit
547+
within the granularity of stat calls, then the module search will fail. To
548+
prevent this from happening, when you create a module dynamically, make sure
549+
to call :func:`importlib.invalidate_caches`.
550+
551+
.. versionadded:: 3.3
552+
553+
.. attribute:: path
554+
555+
The path the finder will search in.
556+
557+
.. method:: find_module(fullname)
558+
559+
Attempt to find the loader to handle *fullname* within :attr:`path`.
560+
561+
.. method:: invalidate_caches()
562+
563+
Clear out the internal cache.
564+
565+
.. classmethod:: path_hook(\*loader_details)
566+
567+
A class method which returns a closure for use on :attr:`sys.path_hooks`.
568+
An instance of :class:`FileFinder` is returned by the closure using the
569+
path argument given to the closure directly and *loader_details*
570+
indirectly.
571+
572+
If the argument to the closure is not an existing directory,
573+
:exc:`ImportError` is raised.
574+
575+
576+
.. class:: SourceFileLoader(fullname, path)
577+
578+
A concrete implementation of :class:`importlib.abc.SourceLoader` by
579+
subclassing :class:`importlib.abc.FileLoader` and providing some concrete
580+
implementations of other methods.
581+
582+
.. versionadded:: 3.3
583+
584+
.. attribute:: name
585+
586+
The name of the module that this loader will handle.
587+
588+
.. attribute:: path
589+
590+
The path to the source file.
591+
592+
.. method:: is_package(fullname)
593+
594+
Return true if :attr:`path` appears to be for a package.
595+
596+
.. method:: path_stats(path)
597+
598+
Concrete implementation of :meth:`importlib.abc.SourceLoader.path_stats`.
599+
600+
.. method:: set_data(path, data)
601+
602+
Concrete implementation of :meth:`importlib.abc.SourceLoader.set_data`.
603+
604+
.. method:: load_module(fullname)
605+
606+
Load the specified module if it is the same as :attr:`name`.
607+
608+
609+
.. class:: _SourcelessFileLoader(fullname, path)
610+
611+
A concrete implementation of :class:`importlib.abc.FileLoader` which can
612+
import bytecode files (i.e. no source code files exist).
613+
614+
It is **strongly** suggested you do not rely on this loader (hence the
615+
leading underscore of the class). Direct use of bytecode files (and thus not
616+
source code files) inhibits your modules from being usable by all Python
617+
implementations. It also runs the risk of your bytecode files not being
618+
usable by new versions of Python which change the bytecode format. This
619+
class is only documented as it is directly used by import and thus can
620+
potentially have instances show up as a module's ``__loader__`` attribute.
621+
622+
.. versionadded:: 3.3
623+
624+
.. attribute:: name
625+
626+
The name of the module the loader will handle.
627+
628+
.. attribute:: path
629+
630+
The path to the bytecode file.
631+
632+
.. method:: is_package(fullname)
633+
634+
Determines if the module is a package based on :attr:`path`.
635+
636+
.. method:: get_code(fullname)
637+
638+
Returns the code object for :attr:`name` created from :attr:`path`.
639+
640+
.. method:: get_source(fullname)
641+
642+
Returns ``None`` as bytecode files have no source when this loader is
643+
used.
644+
645+
.. method:: load_module(fullname)
646+
647+
Loads the specified module if it is the same as :attr:`name`.
648+
649+
650+
.. class:: ExtensionFileLoader(fullname, path)
651+
652+
A concrete implementation of :class:`importlib.abc.InspectLoader` for
653+
extension modules.
654+
655+
The *fullname* argument specifies the name of the module the loader is to
656+
support. The *path* argument is the path to the extension module's file.
657+
658+
.. versionadded:: 3.3
659+
660+
.. attribute:: name
661+
662+
Name of the module the loader supports.
663+
664+
.. attribute:: path
665+
666+
Path to the extension module.
667+
668+
.. method:: load_module(fullname)
669+
670+
Loads the extension module if and only if *fullname** is the same as
671+
:attr:`name`.
672+
673+
.. method:: is_package(fullname)
674+
675+
Returns ``False`` as extension modules can never be packages.
676+
677+
.. method:: get_code(fullname)
678+
679+
Returns ``None`` as extension modules lack a code object.
680+
681+
.. method:: get_source(fullname)
682+
683+
Returns ``None`` as extension modules do not have source code.
684+
685+
501686
:mod:`importlib.util` -- Utility code for importers
502687
---------------------------------------------------
503688

Lib/imp.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ def __init__(self, fullname, path, file=None):
7171

7272
def get_data(self, path):
7373
"""Gross hack to contort loader to deal w/ load_*()'s bad API."""
74-
if self.file and path == self._path:
74+
if self.file and path == self.path:
7575
with self.file:
7676
# Technically should be returning bytes, but
7777
# SourceLoader.get_code() just passed what is returned to
@@ -83,7 +83,7 @@ def get_data(self, path):
8383
return super().get_data(path)
8484

8585

86-
class _LoadSourceCompatibility(_HackedGetData, _bootstrap._SourceFileLoader):
86+
class _LoadSourceCompatibility(_HackedGetData, _bootstrap.SourceFileLoader):
8787

8888
"""Compatibility support for implementing load_source()."""
8989

@@ -115,7 +115,7 @@ def load_package(name, path):
115115
break
116116
else:
117117
raise ValueError('{!r} is not a package'.format(path))
118-
return _bootstrap._SourceFileLoader(name, path).load_module(name)
118+
return _bootstrap.SourceFileLoader(name, path).load_module(name)
119119

120120

121121
# XXX deprecate

0 commit comments

Comments
 (0)