summaryrefslogtreecommitdiffstats
path: root/Lib/importlib
diff options
context:
space:
mode:
authorBrett Cannon <brett@python.org>2012-04-22 23:58:33 (GMT)
committerBrett Cannon <brett@python.org>2012-04-22 23:58:33 (GMT)
commit938d44d59c9cc142d35f51a908cabf781b482f26 (patch)
tree93d2bd601f966f742ef2f6caca7b374e84f6a0b2 /Lib/importlib
parent8c5e920ae3e98ebc5b37a105cf86e4c1e9649f57 (diff)
downloadcpython-938d44d59c9cc142d35f51a908cabf781b482f26.zip
cpython-938d44d59c9cc142d35f51a908cabf781b482f26.tar.gz
cpython-938d44d59c9cc142d35f51a908cabf781b482f26.tar.bz2
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.
Diffstat (limited to 'Lib/importlib')
-rw-r--r--Lib/importlib/_bootstrap.py101
-rw-r--r--Lib/importlib/abc.py33
-rw-r--r--Lib/importlib/machinery.py4
-rw-r--r--Lib/importlib/test/extension/test_case_sensitivity.py7
-rw-r--r--Lib/importlib/test/extension/test_finder.py7
-rw-r--r--Lib/importlib/test/extension/test_loader.py4
-rw-r--r--Lib/importlib/test/extension/test_path_hook.py3
-rw-r--r--Lib/importlib/test/source/test_case_sensitivity.py11
-rw-r--r--Lib/importlib/test/source/test_file_loader.py18
-rw-r--r--Lib/importlib/test/source/test_finder.py15
-rw-r--r--Lib/importlib/test/source/test_path_hook.py9
-rw-r--r--Lib/importlib/test/source/test_source_encoding.py4
-rw-r--r--Lib/importlib/test/test_abc.py9
13 files changed, 137 insertions, 88 deletions
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py
index 04ceb56..d9df2b7 100644
--- a/Lib/importlib/_bootstrap.py
+++ b/Lib/importlib/_bootstrap.py
@@ -13,6 +13,9 @@ work. One should use importlib as the public-facing version of this module.
# reference any injected objects! This includes not only global code but also
# anything specified at the class level.
+# XXX Make sure all public names have no single leading underscore and all
+# others do.
+
# Bootstrap-related code ######################################################
@@ -283,7 +286,7 @@ def _check_name(method):
"""
def _check_name_wrapper(self, name, *args, **kwargs):
- if self._name != name:
+ if self.name != name:
raise ImportError("loader cannot handle %s" % name, name=name)
return method(self, name, *args, **kwargs)
_wrap(_check_name_wrapper, method)
@@ -423,7 +426,7 @@ class FrozenImporter:
class _LoaderBasics:
"""Base class of common code needed by both SourceLoader and
- _SourcelessFileLoader."""
+ SourcelessFileLoader."""
def is_package(self, fullname):
"""Concrete implementation of InspectLoader.is_package by checking if
@@ -608,7 +611,7 @@ class SourceLoader(_LoaderBasics):
return self._load_module(fullname)
-class _FileLoader:
+class FileLoader:
"""Base file loader class which implements the loader protocol methods that
require file system usage."""
@@ -616,13 +619,13 @@ class _FileLoader:
def __init__(self, fullname, path):
"""Cache the module name and the path to the file found by the
finder."""
- self._name = fullname
- self._path = path
+ self.name = fullname
+ self.path = path
@_check_name
def get_filename(self, fullname):
"""Return the path to the source file as found by the finder."""
- return self._path
+ return self.path
def get_data(self, path):
"""Return the data from path as raw bytes."""
@@ -630,7 +633,7 @@ class _FileLoader:
return file.read()
-class _SourceFileLoader(_FileLoader, SourceLoader):
+class SourceFileLoader(FileLoader, SourceLoader):
"""Concrete implementation of SourceLoader using the file system."""
@@ -668,7 +671,7 @@ class _SourceFileLoader(_FileLoader, SourceLoader):
pass
-class _SourcelessFileLoader(_FileLoader, _LoaderBasics):
+class _SourcelessFileLoader(FileLoader, _LoaderBasics):
"""Loader which handles sourceless file imports."""
@@ -692,7 +695,7 @@ class _SourcelessFileLoader(_FileLoader, _LoaderBasics):
return None
-class _ExtensionFileLoader:
+class ExtensionFileLoader:
"""Loader for extension modules.
@@ -701,8 +704,8 @@ class _ExtensionFileLoader:
"""
def __init__(self, name, path):
- self._name = name
- self._path = path
+ self.name = name
+ self.path = path
@_check_name
@set_package
@@ -711,8 +714,8 @@ class _ExtensionFileLoader:
"""Load an extension module."""
is_reload = fullname in sys.modules
try:
- module = _imp.load_dynamic(fullname, self._path)
- verbose_message('extension module loaded from {!r}', self._path)
+ module = _imp.load_dynamic(fullname, self.path)
+ verbose_message('extension module loaded from {!r}', self.path)
return module
except:
if not is_reload and fullname in sys.modules:
@@ -805,24 +808,25 @@ class PathFinder:
return None
-class _FileFinder:
+class FileFinder:
"""File-based finder.
- Constructor takes a list of objects detailing what file extensions their
- loader supports along with whether it can be used for a package.
+ Interactions with the file system are cached for performance, being
+ refreshed when the directory the finder is handling has been modified.
"""
def __init__(self, path, *details):
- """Initialize with finder details."""
+ """Initialize with the path to search on and a variable number of
+ 3-tuples containing the loader, file suffixes the loader recognizes, and
+ a boolean of whether the loader handles packages."""
packages = []
modules = []
- for detail in details:
- modules.extend((suffix, detail.loader) for suffix in detail.suffixes)
- if detail.supports_packages:
- packages.extend((suffix, detail.loader)
- for suffix in detail.suffixes)
+ for loader, suffixes, supports_packages in details:
+ modules.extend((suffix, loader) for suffix in suffixes)
+ if supports_packages:
+ packages.extend((suffix, loader) for suffix in suffixes)
self.packages = packages
self.modules = modules
# Base (directory) path
@@ -898,46 +902,29 @@ class _FileFinder:
if sys.platform.startswith(CASE_INSENSITIVE_PLATFORMS):
self._relaxed_path_cache = set(fn.lower() for fn in contents)
+ @classmethod
+ def path_hook(cls, *loader_details):
+ """A class method which returns a closure to use on sys.path_hook
+ which will return an instance using the specified loaders and the path
+ called on the closure.
-class _SourceFinderDetails:
-
- loader = _SourceFileLoader
- supports_packages = True
-
- def __init__(self):
- self.suffixes = _suffix_list(_imp.PY_SOURCE)
-
-class _SourcelessFinderDetails:
-
- loader = _SourcelessFileLoader
- supports_packages = True
-
- def __init__(self):
- self.suffixes = _suffix_list(_imp.PY_COMPILED)
-
+ If the path called on the closure is not a directory, ImportError is
+ raised.
-class _ExtensionFinderDetails:
+ """
+ def path_hook_for_FileFinder(path):
+ """Path hook for importlib.machinery.FileFinder."""
+ if not _path_isdir(path):
+ raise ImportError("only directories are supported", path=path)
+ return cls(path, *loader_details)
- loader = _ExtensionFileLoader
- supports_packages = False
+ return path_hook_for_FileFinder
- def __init__(self):
- self.suffixes = _suffix_list(_imp.C_EXTENSION)
# Import itself ###############################################################
-def _file_path_hook(path):
- """If the path is a directory, return a file-based finder."""
- if _path_isdir(path):
- return _FileFinder(path, _ExtensionFinderDetails(),
- _SourceFinderDetails(),
- _SourcelessFinderDetails())
- else:
- raise ImportError("only directories are supported", path=path)
-
-
-_DEFAULT_PATH_HOOK = _file_path_hook
+_DEFAULT_PATH_HOOK = None # Set in _setup()
class _DefaultPathFinder(PathFinder):
@@ -1209,6 +1196,12 @@ def _setup(sys_module, _imp_module):
if builtin_os == 'nt':
SOURCE_SUFFIXES.append('.pyw')
+ supported_loaders = [(ExtensionFileLoader, _suffix_list(3), False),
+ (SourceFileLoader, _suffix_list(1), True),
+ (_SourcelessFileLoader, _suffix_list(2), True)]
+ setattr(self_module, '_DEFAULT_PATH_HOOK',
+ FileFinder.path_hook(*supported_loaders))
+
def _install(sys_module, _imp_module):
"""Install importlib as the implementation of import.
diff --git a/Lib/importlib/abc.py b/Lib/importlib/abc.py
index 43e4866..baa09fd 100644
--- a/Lib/importlib/abc.py
+++ b/Lib/importlib/abc.py
@@ -1,6 +1,12 @@
"""Abstract base classes related to import."""
from . import _bootstrap
from . import machinery
+try:
+ import _frozen_importlib
+except ImportError as exc:
+ if exc.name != '_frozen_importlib':
+ raise
+ _frozen_importlib = None
import abc
import imp
import marshal
@@ -9,6 +15,14 @@ import tokenize
import warnings
+def _register(abstract_cls, *classes):
+ for cls in classes:
+ abstract_cls.register(cls)
+ if _frozen_importlib is not None:
+ frozen_cls = getattr(_frozen_importlib, cls.__name__)
+ abstract_cls.register(frozen_cls)
+
+
class Loader(metaclass=abc.ABCMeta):
"""Abstract base class for import loaders."""
@@ -32,9 +46,8 @@ class Finder(metaclass=abc.ABCMeta):
"""
raise NotImplementedError
-Finder.register(machinery.BuiltinImporter)
-Finder.register(machinery.FrozenImporter)
-Finder.register(machinery.PathFinder)
+_register(Finder, machinery.BuiltinImporter, machinery.FrozenImporter,
+ machinery.PathFinder, machinery.FileFinder)
class ResourceLoader(Loader):
@@ -80,8 +93,8 @@ class InspectLoader(Loader):
module. The fullname is a str. Returns a str."""
raise NotImplementedError
-InspectLoader.register(machinery.BuiltinImporter)
-InspectLoader.register(machinery.FrozenImporter)
+_register(InspectLoader, machinery.BuiltinImporter, machinery.FrozenImporter,
+ machinery.ExtensionFileLoader)
class ExecutionLoader(InspectLoader):
@@ -100,6 +113,15 @@ class ExecutionLoader(InspectLoader):
raise NotImplementedError
+class FileLoader(_bootstrap.FileLoader, ResourceLoader, ExecutionLoader):
+
+ """Abstract base class partially implementing the ResourceLoader and
+ ExecutionLoader ABCs."""
+
+_register(FileLoader, machinery.SourceFileLoader,
+ machinery._SourcelessFileLoader)
+
+
class SourceLoader(_bootstrap.SourceLoader, ResourceLoader, ExecutionLoader):
"""Abstract base class for loading source code (and optionally any
@@ -146,6 +168,7 @@ class SourceLoader(_bootstrap.SourceLoader, ResourceLoader, ExecutionLoader):
"""
raise NotImplementedError
+_register(SourceLoader, machinery.SourceFileLoader)
class PyLoader(SourceLoader):
diff --git a/Lib/importlib/machinery.py b/Lib/importlib/machinery.py
index 5197744..c9906c7 100644
--- a/Lib/importlib/machinery.py
+++ b/Lib/importlib/machinery.py
@@ -3,3 +3,7 @@
from ._bootstrap import BuiltinImporter
from ._bootstrap import FrozenImporter
from ._bootstrap import PathFinder
+from ._bootstrap import FileFinder
+from ._bootstrap import SourceFileLoader
+from ._bootstrap import _SourcelessFileLoader
+from ._bootstrap import ExtensionFileLoader
diff --git a/Lib/importlib/test/extension/test_case_sensitivity.py b/Lib/importlib/test/extension/test_case_sensitivity.py
index add830d..1ba2a33 100644
--- a/Lib/importlib/test/extension/test_case_sensitivity.py
+++ b/Lib/importlib/test/extension/test_case_sensitivity.py
@@ -1,3 +1,4 @@
+import imp
import sys
from test import support
import unittest
@@ -13,8 +14,10 @@ class ExtensionModuleCaseSensitivityTest(unittest.TestCase):
good_name = ext_util.NAME
bad_name = good_name.upper()
assert good_name != bad_name
- finder = _bootstrap._FileFinder(ext_util.PATH,
- _bootstrap._ExtensionFinderDetails())
+ finder = _bootstrap.FileFinder(ext_util.PATH,
+ (_bootstrap.ExtensionFileLoader,
+ _bootstrap._suffix_list(imp.C_EXTENSION),
+ False))
return finder.find_module(bad_name)
def test_case_sensitive(self):
diff --git a/Lib/importlib/test/extension/test_finder.py b/Lib/importlib/test/extension/test_finder.py
index ea97483..a28cd07 100644
--- a/Lib/importlib/test/extension/test_finder.py
+++ b/Lib/importlib/test/extension/test_finder.py
@@ -2,6 +2,7 @@ from importlib import _bootstrap
from .. import abc
from . import util
+import imp
import unittest
class FinderTests(abc.FinderTests):
@@ -9,8 +10,10 @@ class FinderTests(abc.FinderTests):
"""Test the finder for extension modules."""
def find_module(self, fullname):
- importer = _bootstrap._FileFinder(util.PATH,
- _bootstrap._ExtensionFinderDetails())
+ importer = _bootstrap.FileFinder(util.PATH,
+ (_bootstrap.ExtensionFileLoader,
+ _bootstrap._suffix_list(imp.C_EXTENSION),
+ False))
return importer.find_module(fullname)
def test_module(self):
diff --git a/Lib/importlib/test/extension/test_loader.py b/Lib/importlib/test/extension/test_loader.py
index 9e5edad..ab2b686 100644
--- a/Lib/importlib/test/extension/test_loader.py
+++ b/Lib/importlib/test/extension/test_loader.py
@@ -12,7 +12,7 @@ class LoaderTests(abc.LoaderTests):
"""Test load_module() for extension modules."""
def load_module(self, fullname):
- loader = _bootstrap._ExtensionFileLoader(ext_util.NAME,
+ loader = _bootstrap.ExtensionFileLoader(ext_util.NAME,
ext_util.FILEPATH)
return loader.load_module(fullname)
@@ -25,7 +25,7 @@ class LoaderTests(abc.LoaderTests):
self.assertEqual(getattr(module, attr), value)
self.assertTrue(ext_util.NAME in sys.modules)
self.assertTrue(isinstance(module.__loader__,
- _bootstrap._ExtensionFileLoader))
+ _bootstrap.ExtensionFileLoader))
def test_package(self):
# Extensions are not found in packages.
diff --git a/Lib/importlib/test/extension/test_path_hook.py b/Lib/importlib/test/extension/test_path_hook.py
index 4610420..673c300 100644
--- a/Lib/importlib/test/extension/test_path_hook.py
+++ b/Lib/importlib/test/extension/test_path_hook.py
@@ -14,7 +14,8 @@ class PathHookTests(unittest.TestCase):
# XXX Should it only work for directories containing an extension module?
def hook(self, entry):
- return _bootstrap._file_path_hook(entry)
+ return _bootstrap.FileFinder.path_hook((_bootstrap.ExtensionFileLoader,
+ _bootstrap._suffix_list(imp.C_EXTENSION), False))(entry)
def test_success(self):
# Path hook should handle a directory where a known extension module
diff --git a/Lib/importlib/test/source/test_case_sensitivity.py b/Lib/importlib/test/source/test_case_sensitivity.py
index 569f516..d4bae8d 100644
--- a/Lib/importlib/test/source/test_case_sensitivity.py
+++ b/Lib/importlib/test/source/test_case_sensitivity.py
@@ -2,6 +2,7 @@
from importlib import _bootstrap
from .. import util
from . import util as source_util
+import imp
import os
import sys
from test import support as test_support
@@ -19,9 +20,13 @@ class CaseSensitivityTest(unittest.TestCase):
assert name != name.lower()
def find(self, path):
- finder = _bootstrap._FileFinder(path,
- _bootstrap._SourceFinderDetails(),
- _bootstrap._SourcelessFinderDetails())
+ finder = _bootstrap.FileFinder(path,
+ (_bootstrap.SourceFileLoader,
+ _bootstrap._suffix_list(imp.PY_SOURCE),
+ True),
+ (_bootstrap._SourcelessFileLoader,
+ _bootstrap._suffix_list(imp.PY_COMPILED),
+ True))
return finder.find_module(self.name)
def sensitivity_test(self):
diff --git a/Lib/importlib/test/source/test_file_loader.py b/Lib/importlib/test/source/test_file_loader.py
index 710339c..764dcff 100644
--- a/Lib/importlib/test/source/test_file_loader.py
+++ b/Lib/importlib/test/source/test_file_loader.py
@@ -27,7 +27,7 @@ class SimpleTest(unittest.TestCase):
# [basic]
def test_module(self):
with source_util.create_modules('_temp') as mapping:
- loader = _bootstrap._SourceFileLoader('_temp', mapping['_temp'])
+ loader = _bootstrap.SourceFileLoader('_temp', mapping['_temp'])
module = loader.load_module('_temp')
self.assertTrue('_temp' in sys.modules)
check = {'__name__': '_temp', '__file__': mapping['_temp'],
@@ -37,7 +37,7 @@ class SimpleTest(unittest.TestCase):
def test_package(self):
with source_util.create_modules('_pkg.__init__') as mapping:
- loader = _bootstrap._SourceFileLoader('_pkg',
+ loader = _bootstrap.SourceFileLoader('_pkg',
mapping['_pkg.__init__'])
module = loader.load_module('_pkg')
self.assertTrue('_pkg' in sys.modules)
@@ -50,7 +50,7 @@ class SimpleTest(unittest.TestCase):
def test_lacking_parent(self):
with source_util.create_modules('_pkg.__init__', '_pkg.mod')as mapping:
- loader = _bootstrap._SourceFileLoader('_pkg.mod',
+ loader = _bootstrap.SourceFileLoader('_pkg.mod',
mapping['_pkg.mod'])
module = loader.load_module('_pkg.mod')
self.assertTrue('_pkg.mod' in sys.modules)
@@ -65,7 +65,7 @@ class SimpleTest(unittest.TestCase):
def test_module_reuse(self):
with source_util.create_modules('_temp') as mapping:
- loader = _bootstrap._SourceFileLoader('_temp', mapping['_temp'])
+ loader = _bootstrap.SourceFileLoader('_temp', mapping['_temp'])
module = loader.load_module('_temp')
module_id = id(module)
module_dict_id = id(module.__dict__)
@@ -90,7 +90,7 @@ class SimpleTest(unittest.TestCase):
setattr(orig_module, attr, value)
with open(mapping[name], 'w') as file:
file.write('+++ bad syntax +++')
- loader = _bootstrap._SourceFileLoader('_temp', mapping['_temp'])
+ loader = _bootstrap.SourceFileLoader('_temp', mapping['_temp'])
with self.assertRaises(SyntaxError):
loader.load_module(name)
for attr in attributes:
@@ -101,7 +101,7 @@ class SimpleTest(unittest.TestCase):
with source_util.create_modules('_temp') as mapping:
with open(mapping['_temp'], 'w') as file:
file.write('=')
- loader = _bootstrap._SourceFileLoader('_temp', mapping['_temp'])
+ loader = _bootstrap.SourceFileLoader('_temp', mapping['_temp'])
with self.assertRaises(SyntaxError):
loader.load_module('_temp')
self.assertTrue('_temp' not in sys.modules)
@@ -114,7 +114,7 @@ class SimpleTest(unittest.TestCase):
file.write("# test file for importlib")
try:
with util.uncache('_temp'):
- loader = _bootstrap._SourceFileLoader('_temp', file_path)
+ loader = _bootstrap.SourceFileLoader('_temp', file_path)
mod = loader.load_module('_temp')
self.assertEqual(file_path, mod.__file__)
self.assertEqual(imp.cache_from_source(file_path),
@@ -140,7 +140,7 @@ class SimpleTest(unittest.TestCase):
if e.errno != getattr(errno, 'EOVERFLOW', None):
raise
self.skipTest("cannot set modification time to large integer ({})".format(e))
- loader = _bootstrap._SourceFileLoader('_temp', mapping['_temp'])
+ loader = _bootstrap.SourceFileLoader('_temp', mapping['_temp'])
mod = loader.load_module('_temp')
# Sanity checks.
self.assertEqual(mod.__cached__, compiled)
@@ -255,7 +255,7 @@ class BadBytecodeTest(unittest.TestCase):
class SourceLoaderBadBytecodeTest(BadBytecodeTest):
- loader = _bootstrap._SourceFileLoader
+ loader = _bootstrap.SourceFileLoader
@source_util.writes_bytecode_files
def test_empty_file(self):
diff --git a/Lib/importlib/test/source/test_finder.py b/Lib/importlib/test/source/test_finder.py
index 315aa77..f5de58a 100644
--- a/Lib/importlib/test/source/test_finder.py
+++ b/Lib/importlib/test/source/test_finder.py
@@ -3,6 +3,7 @@ from . import util as source_util
from importlib import _bootstrap
import errno
+import imp
import os
import py_compile
from test.support import make_legacy_pyc
@@ -35,9 +36,11 @@ class FinderTests(abc.FinderTests):
"""
def import_(self, root, module):
- finder = _bootstrap._FileFinder(root,
- _bootstrap._SourceFinderDetails(),
- _bootstrap._SourcelessFinderDetails())
+ loader_details = [(_bootstrap.SourceFileLoader,
+ _bootstrap._suffix_list(imp.PY_SOURCE), True),
+ (_bootstrap._SourcelessFileLoader,
+ _bootstrap._suffix_list(imp.PY_COMPILED), True)]
+ finder = _bootstrap.FileFinder(root, *loader_details)
return finder.find_module(module)
def run_test(self, test, create=None, *, compile_=None, unlink=None):
@@ -135,7 +138,8 @@ class FinderTests(abc.FinderTests):
def test_empty_string_for_dir(self):
# The empty string from sys.path means to search in the cwd.
- finder = _bootstrap._FileFinder('', _bootstrap._SourceFinderDetails())
+ finder = _bootstrap.FileFinder('', (_bootstrap.SourceFileLoader,
+ _bootstrap._suffix_list(imp.PY_SOURCE), True))
with open('mod.py', 'w') as file:
file.write("# test file for importlib")
try:
@@ -146,7 +150,8 @@ class FinderTests(abc.FinderTests):
def test_invalidate_caches(self):
# invalidate_caches() should reset the mtime.
- finder = _bootstrap._FileFinder('', _bootstrap._SourceFinderDetails())
+ finder = _bootstrap.FileFinder('', (_bootstrap.SourceFileLoader,
+ _bootstrap._suffix_list(imp.PY_SOURCE), True))
finder._path_mtime = 42
finder.invalidate_caches()
self.assertEqual(finder._path_mtime, -1)
diff --git a/Lib/importlib/test/source/test_path_hook.py b/Lib/importlib/test/source/test_path_hook.py
index 3de822c..663a128 100644
--- a/Lib/importlib/test/source/test_path_hook.py
+++ b/Lib/importlib/test/source/test_path_hook.py
@@ -1,6 +1,7 @@
from . import util as source_util
from importlib import _bootstrap
+import imp
import unittest
@@ -8,14 +9,18 @@ class PathHookTest(unittest.TestCase):
"""Test the path hook for source."""
+ def path_hook(self):
+ return _bootstrap.FileFinder.path_hook((_bootstrap.SourceFileLoader,
+ _bootstrap._suffix_list(imp.PY_SOURCE), True))
+
def test_success(self):
with source_util.create_modules('dummy') as mapping:
- self.assertTrue(hasattr(_bootstrap._file_path_hook(mapping['.root']),
+ self.assertTrue(hasattr(self.path_hook()(mapping['.root']),
'find_module'))
def test_empty_string(self):
# The empty string represents the cwd.
- self.assertTrue(hasattr(_bootstrap._file_path_hook(''), 'find_module'))
+ self.assertTrue(hasattr(self.path_hook()(''), 'find_module'))
def test_main():
diff --git a/Lib/importlib/test/source/test_source_encoding.py b/Lib/importlib/test/source/test_source_encoding.py
index 72a1360..0ca5195 100644
--- a/Lib/importlib/test/source/test_source_encoding.py
+++ b/Lib/importlib/test/source/test_source_encoding.py
@@ -35,7 +35,7 @@ class EncodingTest(unittest.TestCase):
with source_util.create_modules(self.module_name) as mapping:
with open(mapping[self.module_name], 'wb') as file:
file.write(source)
- loader = _bootstrap._SourceFileLoader(self.module_name,
+ loader = _bootstrap.SourceFileLoader(self.module_name,
mapping[self.module_name])
return loader.load_module(self.module_name)
@@ -97,7 +97,7 @@ class LineEndingTest(unittest.TestCase):
with source_util.create_modules(module_name) as mapping:
with open(mapping[module_name], 'wb') as file:
file.write(source)
- loader = _bootstrap._SourceFileLoader(module_name,
+ loader = _bootstrap.SourceFileLoader(module_name,
mapping[module_name])
return loader.load_module(module_name)
diff --git a/Lib/importlib/test/test_abc.py b/Lib/importlib/test/test_abc.py
index 0ecbe39..e9eec60 100644
--- a/Lib/importlib/test/test_abc.py
+++ b/Lib/importlib/test/test_abc.py
@@ -50,7 +50,7 @@ class InspectLoader(InheritanceTests, unittest.TestCase):
superclasses = [abc.Loader]
subclasses = [abc.PyLoader, machinery.BuiltinImporter,
- machinery.FrozenImporter]
+ machinery.FrozenImporter, machinery.ExtensionFileLoader]
class ExecutionLoader(InheritanceTests, unittest.TestCase):
@@ -59,9 +59,16 @@ class ExecutionLoader(InheritanceTests, unittest.TestCase):
subclasses = [abc.PyLoader]
+class FileLoader(InheritanceTests, unittest.TestCase):
+
+ superclasses = [abc.ResourceLoader, abc.ExecutionLoader]
+ subclasses = [machinery.SourceFileLoader, machinery._SourcelessFileLoader]
+
+
class SourceLoader(InheritanceTests, unittest.TestCase):
superclasses = [abc.ResourceLoader, abc.ExecutionLoader]
+ subclasses = [machinery.SourceFileLoader]
class PyLoader(InheritanceTests, unittest.TestCase):