mirror of https://github.com/python/cpython
Implement InspectLoader for BuiltinImporter.
This commit is contained in:
parent
7aa21f75c1
commit
a113ac58be
|
@ -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
|
An abstract base class for a :term:`loader` which implements the optional
|
||||||
:pep:`302` protocol for loaders which inspect modules.
|
: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
|
An abstract method to return the :class:`code` object for a module.
|
||||||
false value otherwise. :exc:`ImportError` is raised if the
|
:keyword:`None` is returned if the module does not have a code object
|
||||||
:term:`loader` cannot find the module.
|
(e.g. built-in module). :exc:`ImportError` is raised if loader cannot
|
||||||
|
find the requested module.
|
||||||
|
|
||||||
.. method:: get_source(fullname)
|
.. 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`
|
source is available (e.g. a built-in module). Raises :exc:`ImportError`
|
||||||
if the loader cannot find the module specified.
|
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.
|
An abstract method to return a true value if the module is a package, a
|
||||||
:keyword:`None` is returned if the module does not have a code object
|
false value otherwise. :exc:`ImportError` is raised if the
|
||||||
(e.g. built-in module). :exc:`ImportError` is raised if loader cannot
|
:term:`loader` cannot find the module.
|
||||||
find the requested module.
|
|
||||||
|
|
||||||
|
|
||||||
.. class:: PyLoader
|
.. class:: PyLoader
|
||||||
|
@ -274,7 +274,8 @@ find and load modules.
|
||||||
|
|
||||||
An :term:`importer` for built-in modules. All known built-in modules are
|
An :term:`importer` for built-in modules. All known built-in modules are
|
||||||
listed in :data:`sys.builtin_module_names`. This class implements the
|
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
|
Only class methods are defined by this class to alleviate the need for
|
||||||
instantiation.
|
instantiation.
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
to do
|
to do
|
||||||
/////
|
/////
|
||||||
|
|
||||||
* Fill in docstrings for ABCs.
|
* Implement InspectLoader for FrozenImporter.
|
||||||
|
|
||||||
* Implement InspectLoader for BuiltinImporter and FrozenImporter.
|
|
||||||
|
|
||||||
+ Expose function to see if a frozen module is a package.
|
+ Expose function to see if a frozen module is a package.
|
||||||
|
|
||||||
|
|
|
@ -173,6 +173,16 @@ def _check_name(method):
|
||||||
return inner
|
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):
|
def _suffix_list(suffix_type):
|
||||||
"""Return a list of file suffixes based on the imp file type."""
|
"""Return a list of file suffixes based on the imp file type."""
|
||||||
return [suffix[0] for suffix in imp.get_suffixes()
|
return [suffix[0] for suffix in imp.get_suffixes()
|
||||||
|
@ -204,10 +214,9 @@ class BuiltinImporter:
|
||||||
@classmethod
|
@classmethod
|
||||||
@set_package
|
@set_package
|
||||||
@set_loader
|
@set_loader
|
||||||
|
@_requires_builtin
|
||||||
def load_module(cls, fullname):
|
def load_module(cls, fullname):
|
||||||
"""Load a built-in module."""
|
"""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
|
is_reload = fullname in sys.modules
|
||||||
try:
|
try:
|
||||||
return imp.init_builtin(fullname)
|
return imp.init_builtin(fullname)
|
||||||
|
@ -216,6 +225,24 @@ class BuiltinImporter:
|
||||||
del sys.modules[fullname]
|
del sys.modules[fullname]
|
||||||
raise
|
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:
|
class FrozenImporter:
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,6 @@ class Loader(metaclass=abc.ABCMeta):
|
||||||
"""Abstract method which when implemented should load a module."""
|
"""Abstract method which when implemented should load a module."""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
Loader.register(machinery.BuiltinImporter)
|
|
||||||
Loader.register(machinery.FrozenImporter)
|
Loader.register(machinery.FrozenImporter)
|
||||||
|
|
||||||
|
|
||||||
|
@ -75,6 +74,8 @@ class InspectLoader(Loader):
|
||||||
module."""
|
module."""
|
||||||
return NotImplementedError
|
return NotImplementedError
|
||||||
|
|
||||||
|
InspectLoader.register(machinery.BuiltinImporter)
|
||||||
|
|
||||||
|
|
||||||
class PyLoader(_bootstrap.PyLoader, InspectLoader):
|
class PyLoader(_bootstrap.PyLoader, InspectLoader):
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from importlib import machinery
|
from importlib import machinery
|
||||||
from .. import abc
|
from .. import abc
|
||||||
from .. import util
|
from .. import util
|
||||||
|
from . import util as builtin_util
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import unittest
|
import unittest
|
||||||
|
@ -9,13 +10,11 @@ class FinderTests(abc.FinderTests):
|
||||||
|
|
||||||
"""Test find_module() for built-in modules."""
|
"""Test find_module() for built-in modules."""
|
||||||
|
|
||||||
assert 'errno' in sys.builtin_module_names
|
|
||||||
name = 'errno'
|
|
||||||
|
|
||||||
def test_module(self):
|
def test_module(self):
|
||||||
# Common case.
|
# Common case.
|
||||||
with util.uncache(self.name):
|
with util.uncache(builtin_util.NAME):
|
||||||
self.assert_(machinery.BuiltinImporter.find_module(self.name))
|
found = machinery.BuiltinImporter.find_module(builtin_util.NAME)
|
||||||
|
self.assert_(found)
|
||||||
|
|
||||||
def test_package(self):
|
def test_package(self):
|
||||||
# Built-in modules cannot be a package.
|
# Built-in modules cannot be a package.
|
||||||
|
@ -40,8 +39,9 @@ class FinderTests(abc.FinderTests):
|
||||||
|
|
||||||
def test_ignore_path(self):
|
def test_ignore_path(self):
|
||||||
# The value for 'path' should always trigger a failed import.
|
# The value for 'path' should always trigger a failed import.
|
||||||
with util.uncache(self.name):
|
with util.uncache(builtin_util.NAME):
|
||||||
loader = machinery.BuiltinImporter.find_module(self.name, ['pkg'])
|
loader = machinery.BuiltinImporter.find_module(builtin_util.NAME,
|
||||||
|
['pkg'])
|
||||||
self.assert_(loader is None)
|
self.assert_(loader is None)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ import importlib
|
||||||
from importlib import machinery
|
from importlib import machinery
|
||||||
from .. import abc
|
from .. import abc
|
||||||
from .. import util
|
from .. import util
|
||||||
|
from . import util as builtin_util
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import types
|
import types
|
||||||
|
@ -12,9 +13,6 @@ class LoaderTests(abc.LoaderTests):
|
||||||
|
|
||||||
"""Test load_module() for built-in modules."""
|
"""Test load_module() for built-in modules."""
|
||||||
|
|
||||||
assert 'errno' in sys.builtin_module_names
|
|
||||||
name = 'errno'
|
|
||||||
|
|
||||||
verification = {'__name__': 'errno', '__package__': '',
|
verification = {'__name__': 'errno', '__package__': '',
|
||||||
'__loader__': machinery.BuiltinImporter}
|
'__loader__': machinery.BuiltinImporter}
|
||||||
|
|
||||||
|
@ -30,8 +28,8 @@ class LoaderTests(abc.LoaderTests):
|
||||||
|
|
||||||
def test_module(self):
|
def test_module(self):
|
||||||
# Common case.
|
# Common case.
|
||||||
with util.uncache(self.name):
|
with util.uncache(builtin_util.NAME):
|
||||||
module = self.load_module(self.name)
|
module = self.load_module(builtin_util.NAME)
|
||||||
self.verify(module)
|
self.verify(module)
|
||||||
|
|
||||||
def test_package(self):
|
def test_package(self):
|
||||||
|
@ -48,9 +46,9 @@ class LoaderTests(abc.LoaderTests):
|
||||||
|
|
||||||
def test_module_reuse(self):
|
def test_module_reuse(self):
|
||||||
# Test that the same module is used in a reload.
|
# Test that the same module is used in a reload.
|
||||||
with util.uncache(self.name):
|
with util.uncache(builtin_util.NAME):
|
||||||
module1 = self.load_module(self.name)
|
module1 = self.load_module(builtin_util.NAME)
|
||||||
module2 = self.load_module(self.name)
|
module2 = self.load_module(builtin_util.NAME)
|
||||||
self.assert_(module1 is module2)
|
self.assert_(module1 is module2)
|
||||||
|
|
||||||
def test_unloadable(self):
|
def test_unloadable(self):
|
||||||
|
@ -65,9 +63,36 @@ class LoaderTests(abc.LoaderTests):
|
||||||
self.assertRaises(ImportError, self.load_module, 'importlib')
|
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():
|
def test_main():
|
||||||
from test.support import run_unittest
|
from test.support import run_unittest
|
||||||
run_unittest(LoaderTests)
|
run_unittest(LoaderTests, InspectLoaderTests)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -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'
|
Loading…
Reference in New Issue