def test_find_module(self):
record = []
class MockedModuleGraph(modulegraph.ModuleGraph):
def _find_module(self, name, path, parent=None):
if path == None:
path = sys.path
record.append((name, path))
return super(MockedModuleGraph, self)._find_module(name, path, parent)
mockedgraph = MockedModuleGraph()
try:
graph = modulegraph.ModuleGraph()
m = graph._find_module('sys', None)
self.assertEqual(record, [])
self.assertEqual(m, (None, None, ("", "", imp.C_BUILTIN)))
xml = graph.import_hook("xml")[0]
self.assertEqual(xml.identifier, 'xml')
self.assertRaises(ImportError, graph._find_module, 'xml', None)
self.assertEqual(record, [])
m = mockedgraph._find_module('shutil', None)
self.assertEqual(record, [
('shutil', graph.path),
])
self.assertTrue(isinstance(m, tuple))
self.assertEqual(len(m), 3)
self.assertTrue(hasattr(m[0], 'read'))
self.assertIsInstance(m[0].read(), str)
srcfn = shutil.__file__
if srcfn.endswith('.pyc'):
srcfn = srcfn[:-1]
self.assertEqual(os.path.realpath(m[1]), os.path.realpath(srcfn))
self.assertEqual(m[2], ('.py', READ_MODE, imp.PY_SOURCE))
m[0].close()
m2 = graph._find_module('shutil', None)
self.assertEqual(m[1:], m2[1:])
m2[0].close()
record[:] = []
m = mockedgraph._find_module('sax', xml.packagepath, xml)
# FIXME: PyInstaller appends `__init__.py` to the pkg-directory
#self.assertEqual(m,
# (None, os.path.join(os.path.dirname(xml.filename), 'sax'),
# ('', '', imp.PKG_DIRECTORY)))
self.assertEqual(record, [
('sax', xml.packagepath),
])
if m[0] is not None: m[0].close()
finally:
pass
python类C_BUILTIN的实例源码
def _find_module(self, name, path, parent=None):
"""
3-tuple describing the physical location of the module with the passed
name if this module is physically findable _or_ raise `ImportError`.
This high-level method wraps the low-level `modulegraph.find_module()`
function with additional support for graph-based module caching.
Parameters
----------
name : str
Fully-qualified name of the Python module to be found.
path : list
List of the absolute paths of all directories to search for this
module _or_ `None` if the default path list `self.path` is to be
searched.
parent : Node
Package containing this module if this module is a submodule of a
package _or_ `None` if this is a top-level module.
Returns
----------
(file_handle, filename, metadata)
See `modulegraph._find_module()` for details.
Raises
----------
ImportError
If this module is _not_ found.
"""
if parent is not None:
# assert path is not None
fullname = parent.identifier + '.' + name
else:
fullname = name
node = self.findNode(fullname)
if node is not None:
self.msg(3, "find_module: already included?", node)
raise ImportError(name)
if path is None:
if name in sys.builtin_module_names:
return (None, None, ("", "", imp.C_BUILTIN))
path = self.path
return self._find_module_path(fullname, name, path)