An abstract base class for a :term:`loader` which implements the optional
:pep:`302` protocol for loaders which inspect modules.
- .. method:: is_package(fullname)
+ .. method:: get_code(fullname)
- An abstract method to return a true value if the module is a package, a
- false value otherwise. :exc:`ImportError` is raised if the
- :term:`loader` cannot find the module.
+ An abstract method to return the :class:`code` object for a module.
+ :keyword:`None` is returned if the module does not have a code object
+ (e.g. built-in module). :exc:`ImportError` is raised if loader cannot
+ find the requested module.
.. method:: get_source(fullname)
source is available (e.g. a built-in module). Raises :exc:`ImportError`
if the loader cannot find the module specified.
- .. method:: get_code(fullname)
+ .. method:: is_package(fullname)
- An abstract method to return the :class:`code` object for a module.
- :keyword:`None` is returned if the module does not have a code object
- (e.g. built-in module). :exc:`ImportError` is raised if loader cannot
- find the requested module.
+ An abstract method to return a true value if the module is a package, a
+ false value otherwise. :exc:`ImportError` is raised if the
+ :term:`loader` cannot find the module.
.. class:: PyLoader
An :term:`importer` for built-in modules. All known built-in modules are
listed in :data:`sys.builtin_module_names`. This class implements the
- :class:`importlib.abc.Finder` and :class:`importlib.abc.Loader` ABCs.
+ :class:`importlib.abc.Finder` and :class:`importlib.abc.InspectLoader`
+ ABCs.
Only class methods are defined by this class to alleviate the need for
instantiation.
to do
/////
-* Fill in docstrings for ABCs.
-
-* Implement InspectLoader for BuiltinImporter and FrozenImporter.
+* Implement InspectLoader for FrozenImporter.
+ Expose function to see if a frozen module is a package.
return inner
+def _requires_builtin(fxn):
+ """Decorator to verify the named module is built-in."""
+ def wrapper(self, fullname):
+ if fullname not in sys.builtin_module_names:
+ raise ImportError("{0} is not a built-in module".format(fullname))
+ return fxn(self, fullname)
+ _wrap(wrapper, fxn)
+ return wrapper
+
+
def _suffix_list(suffix_type):
"""Return a list of file suffixes based on the imp file type."""
return [suffix[0] for suffix in imp.get_suffixes()
@classmethod
@set_package
@set_loader
+ @_requires_builtin
def load_module(cls, fullname):
"""Load a built-in module."""
- if fullname not in sys.builtin_module_names:
- raise ImportError("{0} is not a built-in module".format(fullname))
is_reload = fullname in sys.modules
try:
return imp.init_builtin(fullname)
del sys.modules[fullname]
raise
+ @classmethod
+ @_requires_builtin
+ def get_code(cls, fullname):
+ """Return None as built-in modules do not have code objects."""
+ return None
+
+ @classmethod
+ @_requires_builtin
+ def get_source(cls, fullname):
+ """Return None as built-in modules do not have source code."""
+ return None
+
+ @classmethod
+ @_requires_builtin
+ def is_package(cls, fullname):
+ """Return None as built-in module are never packages."""
+ return False
+
class FrozenImporter:
"""Abstract method which when implemented should load a module."""
raise NotImplementedError
-Loader.register(machinery.BuiltinImporter)
Loader.register(machinery.FrozenImporter)
module."""
return NotImplementedError
+InspectLoader.register(machinery.BuiltinImporter)
+
class PyLoader(_bootstrap.PyLoader, InspectLoader):
from importlib import machinery
from .. import abc
from .. import util
+from . import util as builtin_util
import sys
import unittest
"""Test find_module() for built-in modules."""
- assert 'errno' in sys.builtin_module_names
- name = 'errno'
-
def test_module(self):
# Common case.
- with util.uncache(self.name):
- self.assert_(machinery.BuiltinImporter.find_module(self.name))
+ with util.uncache(builtin_util.NAME):
+ found = machinery.BuiltinImporter.find_module(builtin_util.NAME)
+ self.assert_(found)
def test_package(self):
# Built-in modules cannot be a package.
def test_ignore_path(self):
# The value for 'path' should always trigger a failed import.
- with util.uncache(self.name):
- loader = machinery.BuiltinImporter.find_module(self.name, ['pkg'])
+ with util.uncache(builtin_util.NAME):
+ loader = machinery.BuiltinImporter.find_module(builtin_util.NAME,
+ ['pkg'])
self.assert_(loader is None)
from importlib import machinery
from .. import abc
from .. import util
+from . import util as builtin_util
import sys
import types
"""Test load_module() for built-in modules."""
- assert 'errno' in sys.builtin_module_names
- name = 'errno'
-
verification = {'__name__': 'errno', '__package__': '',
'__loader__': machinery.BuiltinImporter}
def test_module(self):
# Common case.
- with util.uncache(self.name):
- module = self.load_module(self.name)
+ with util.uncache(builtin_util.NAME):
+ module = self.load_module(builtin_util.NAME)
self.verify(module)
def test_package(self):
def test_module_reuse(self):
# Test that the same module is used in a reload.
- with util.uncache(self.name):
- module1 = self.load_module(self.name)
- module2 = self.load_module(self.name)
+ with util.uncache(builtin_util.NAME):
+ module1 = self.load_module(builtin_util.NAME)
+ module2 = self.load_module(builtin_util.NAME)
self.assert_(module1 is module2)
def test_unloadable(self):
self.assertRaises(ImportError, self.load_module, 'importlib')
+class InspectLoaderTests(unittest.TestCase):
+
+ """Tests for InspectLoader methods for BuiltinImporter."""
+
+ def test_get_code(self):
+ # There is no code object.
+ result = machinery.BuiltinImporter.get_code(builtin_util.NAME)
+ self.assert_(result is None)
+
+ def test_get_source(self):
+ # There is no source.
+ result = machinery.BuiltinImporter.get_source(builtin_util.NAME)
+ self.assert_(result is None)
+
+ def test_is_package(self):
+ # Cannot be a package.
+ result = machinery.BuiltinImporter.is_package(builtin_util.NAME)
+ self.assert_(not result)
+
+ def test_not_builtin(self):
+ # Modules not built-in should raise ImportError.
+ for meth_name in ('get_code', 'get_source', 'is_package'):
+ method = getattr(machinery.BuiltinImporter, meth_name)
+ self.assertRaises(ImportError, method, builtin_util.BAD_NAME)
+
+
+
def test_main():
from test.support import run_unittest
- run_unittest(LoaderTests)
+ run_unittest(LoaderTests, InspectLoaderTests)
if __name__ == '__main__':
--- /dev/null
+import sys
+
+assert 'errno' in sys.builtin_module_names
+NAME = 'errno'
+
+assert 'importlib' not in sys.builtin_module_names
+BAD_NAME = 'importlib'