[Python-checkins] r71005 - python/branches/py3k/Doc/library/importlib.rst

brett.cannon python-checkins at python.org
Thu Apr 2 01:26:47 CEST 2009


Author: brett.cannon
Date: Thu Apr  2 01:26:47 2009
New Revision: 71005

Log:
Add a meta path importer example.

Modified:
   python/branches/py3k/Doc/library/importlib.rst

Modified: python/branches/py3k/Doc/library/importlib.rst
==============================================================================
--- python/branches/py3k/Doc/library/importlib.rst	(original)
+++ python/branches/py3k/Doc/library/importlib.rst	Thu Apr  2 01:26:47 2009
@@ -77,12 +77,12 @@
     ``pkg.mod``).
 
     The :func:`import_module` function acts as a simplifying wrapper around
-    :func:`__import__`. This means all semantics of the function are derived
-    from :func:`__import__`, including requiring the package from which an
-    import is occurring to have been previously imported (i.e., *package*
-    must already be imported).  The most important difference is that
-    :func:`import_module` returns the most nested package or module that
-    was imported (e.g. ``pkg.mod``), while :func:`__import__` returns the
+    :func:`importlib.__import__`. This means all semantics of the function are
+    derived from :func:`importlib.__import__`, including requiring the package
+    from which an import is occurring to have been previously imported
+    (i.e., *package* must already be imported). The most important difference
+    is that :func:`import_module` returns the most nested package or module
+    that was imported (e.g. ``pkg.mod``), while :func:`__import__` returns the
     top-level package or module (e.g. ``pkg``).
 
 
@@ -384,4 +384,95 @@
     attribute to be used at the global level of the module during
     initialization.
 
-.. XXX This whole chapter desperately needs examples...
+
+Example
+-------
+
+.. testcode::
+
+    """An importer where source is stored in a dict."""
+    from importlib import abc
+
+
+    class DictImporter(abc.Finder, abc.PyLoader):
+
+        """A meta path importer that stores source code in a dict.
+
+        The keys are the module names -- packages must end in ``.__init__``.
+        The values must be something that can be passed to 'bytes'.
+
+        """
+
+        def __init__(self, memory):
+            """Store the dict."""
+            self.memory = memory
+
+        def contains(self, name):
+            """See if a module or package is in the dict."""
+            if name in self.memory:
+                return name
+            package_name = '{}.__init__'.format(name)
+            if  package_name in self.memory:
+                return package_name
+            return False
+
+        __contains__ = contains  # Convenience.
+
+        def find_module(self, fullname, path=None):
+            """Find the module in the dict."""
+            if fullname in self:
+                return self
+            return None
+
+        def source_path(self, fullname):
+            """Return the module name if the module is in the dict."""
+            if not fullname in self:
+                raise ImportError
+            return fullname
+
+        def get_data(self, path):
+            """Return the bytes for the source.
+
+            The value found in the dict is passed through 'bytes' before being
+            returned.
+
+            """
+            name = self.contains(path)
+            if not name:
+                raise IOError
+            return bytes(self.memory[name])
+
+        def is_package(self, fullname):
+            """Tell if module is a package based on whether the dict contains the
+            name with ``.__init__`` appended to it."""
+            if fullname not in self:
+                raise ImportError
+            if fullname in self.memory:
+                return False
+            # If name is in this importer but not as it is then it must end in
+            # ``__init__``.
+            else:
+                return True
+
+.. testcode::
+    :hide:
+
+    import importlib
+    import sys
+
+
+    # Build the dict; keys of name, value of __package__.
+    names = {'_top_level': '', '_pkg.__init__': '_pkg', '_pkg.mod': '_pkg'}
+    source = {name: "name = {!r}".format(name).encode() for name in names}
+
+    # Register the meta path importer.
+    importer = DictImporter(source)
+    sys.meta_path.append(importer)
+
+    # Sanity check.
+    for name in names:
+        module = importlib.import_module(name)
+        assert module.__name__ == name
+        assert getattr(module, 'name') == name
+        assert module.__loader__ is importer
+        assert module.__package__ == names[name]


More information about the Python-checkins mailing list