diff options
| author | Brett Cannon <bcannon@gmail.com> | 2009-03-15 01:41:33 +0000 | 
|---|---|---|
| committer | Brett Cannon <bcannon@gmail.com> | 2009-03-15 01:41:33 +0000 | 
| commit | a113ac58be3ee73d1382af3bfbf47b7ed5e5f5a9 (patch) | |
| tree | 78b2a6b9730046c61c3d76c7cb7b7f195c695136 | |
| parent | 7aa21f75c1d9ac36f1ab7e00aa9d0048ef61476d (diff) | |
| download | cpython-git-a113ac58be3ee73d1382af3bfbf47b7ed5e5f5a9.tar.gz | |
Implement InspectLoader for BuiltinImporter.
| -rw-r--r-- | Doc/library/importlib.rst | 21 | ||||
| -rw-r--r-- | Lib/importlib/NOTES | 4 | ||||
| -rw-r--r-- | Lib/importlib/_bootstrap.py | 31 | ||||
| -rw-r--r-- | Lib/importlib/abc.py | 3 | ||||
| -rw-r--r-- | Lib/importlib/test/builtin/test_finder.py | 14 | ||||
| -rw-r--r-- | Lib/importlib/test/builtin/test_loader.py | 43 | ||||
| -rw-r--r-- | Lib/importlib/test/builtin/util.py | 7 | 
7 files changed, 91 insertions, 32 deletions
| diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index 3b2a288fa2..92fb7875de 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -175,11 +175,12 @@ are also provided to help in implementing the core ABCs.      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) @@ -188,12 +189,11 @@ are also provided to help in implementing the core ABCs.          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 @@ -274,7 +274,8 @@ find and load modules.      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. diff --git a/Lib/importlib/NOTES b/Lib/importlib/NOTES index 2220a166d8..44cfc09bd6 100644 --- a/Lib/importlib/NOTES +++ b/Lib/importlib/NOTES @@ -1,9 +1,7 @@  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. diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py index e94c1d2ddd..736e1b6665 100644 --- a/Lib/importlib/_bootstrap.py +++ b/Lib/importlib/_bootstrap.py @@ -173,6 +173,16 @@ def _check_name(method):      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() @@ -204,10 +214,9 @@ class BuiltinImporter:      @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) @@ -216,6 +225,24 @@ class BuiltinImporter:                  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: diff --git a/Lib/importlib/abc.py b/Lib/importlib/abc.py index 6b00569ef1..c9c542ad1f 100644 --- a/Lib/importlib/abc.py +++ b/Lib/importlib/abc.py @@ -14,7 +14,6 @@ class Loader(metaclass=abc.ABCMeta):          """Abstract method which when implemented should load a module."""          raise NotImplementedError -Loader.register(machinery.BuiltinImporter)  Loader.register(machinery.FrozenImporter) @@ -75,6 +74,8 @@ class InspectLoader(Loader):          module."""          return NotImplementedError +InspectLoader.register(machinery.BuiltinImporter) +  class PyLoader(_bootstrap.PyLoader, InspectLoader): diff --git a/Lib/importlib/test/builtin/test_finder.py b/Lib/importlib/test/builtin/test_finder.py index eacc36c27a..ef8e8fe67a 100644 --- a/Lib/importlib/test/builtin/test_finder.py +++ b/Lib/importlib/test/builtin/test_finder.py @@ -1,6 +1,7 @@  from importlib import machinery  from .. import abc  from .. import util +from . import util as builtin_util  import sys  import unittest @@ -9,13 +10,11 @@ class FinderTests(abc.FinderTests):      """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. @@ -40,8 +39,9 @@ class FinderTests(abc.FinderTests):      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) diff --git a/Lib/importlib/test/builtin/test_loader.py b/Lib/importlib/test/builtin/test_loader.py index 8a69d049ff..cfedb5d3c7 100644 --- a/Lib/importlib/test/builtin/test_loader.py +++ b/Lib/importlib/test/builtin/test_loader.py @@ -2,6 +2,7 @@ import importlib  from importlib import machinery  from .. import abc  from .. import util +from . import util as builtin_util  import sys  import types @@ -12,9 +13,6 @@ class LoaderTests(abc.LoaderTests):      """Test load_module() for built-in modules.""" -    assert 'errno' in sys.builtin_module_names -    name = 'errno' -      verification = {'__name__': 'errno', '__package__': '',                      '__loader__': machinery.BuiltinImporter} @@ -30,8 +28,8 @@ class LoaderTests(abc.LoaderTests):      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): @@ -48,9 +46,9 @@ class LoaderTests(abc.LoaderTests):      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): @@ -65,9 +63,36 @@ class LoaderTests(abc.LoaderTests):          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__': diff --git a/Lib/importlib/test/builtin/util.py b/Lib/importlib/test/builtin/util.py new file mode 100644 index 0000000000..5704699ee2 --- /dev/null +++ b/Lib/importlib/test/builtin/util.py @@ -0,0 +1,7 @@ +import sys + +assert 'errno' in sys.builtin_module_names +NAME = 'errno' + +assert 'importlib' not in sys.builtin_module_names +BAD_NAME = 'importlib' | 
