]> granicus.if.org Git - python/commitdiff
Issue 2439: add pkgutils.get_data() as a convenience wrapper for the PEP 302 get_data...
authorNick Coghlan <ncoghlan@gmail.com>
Tue, 15 Apr 2008 10:25:31 +0000 (10:25 +0000)
committerNick Coghlan <ncoghlan@gmail.com>
Tue, 15 Apr 2008 10:25:31 +0000 (10:25 +0000)
Doc/library/pkgutil.rst
Lib/pkgutil.py
Misc/NEWS

index 1fbfb041dcccc09e93c9bfaea1e0cfe40af6d40c..d086ada01397698516c7b521e14f7fdd36c04135 100644 (file)
@@ -8,7 +8,7 @@
 
 .. versionadded:: 2.3
 
-This module provides a single function:
+This module provides functions to manipulate packages:
 
 
 .. function:: extend_path(path, name)
@@ -41,3 +41,24 @@ This module provides a single function:
    this function to raise an exception (in line with :func:`os.path.isdir`
    behavior).
 
+.. function:: get_data(package, resource)
+
+   Get a resource from a package.
+
+   This is a wrapper round the PEP 302 loader :func:`get_data` API. The package
+   argument should be the name of a package, in standard module format
+   (foo.bar). The resource argument should be in the form of a relative
+   filename, using ``/`` as the path separator. The parent directory name
+   ``..`` is not allowed, and nor is a rooted name (starting with a ``/``).
+
+   The function returns a binary string, which is the contents of the
+   specified resource.
+
+   For packages located in the filesystem, which have already been imported,
+   this is the rough equivalent of::
+
+       d = os.path.dirname(sys.modules[package].__file__)
+       data = open(os.path.join(d, resource), 'rb').read()
+
+   If the package cannot be located or loaded, or it uses a PEP 302 loader
+   which does not support :func:`get_data`, then None is returned.
index 37738e4a75d27493b0f373122b5f28d7595c96f9..c50928f701d1b0240214799107d1b11bcd2d525a 100644 (file)
@@ -544,3 +544,40 @@ def extend_path(path, name):
                 f.close()
 
     return path
+
+def get_data(package, resource):
+    """Get a resource from a package.
+
+    This is a wrapper round the PEP 302 loader get_data API. The package
+    argument should be the name of a package, in standard module format
+    (foo.bar). The resource argument should be in the form of a relative
+    filename, using '/' as the path separator. The parent directory name '..'
+    is not allowed, and nor is a rooted name (starting with a '/').
+
+    The function returns a binary string, which is the contents of the
+    specified resource.
+
+    For packages located in the filesystem, which have already been imported,
+    this is the rough equivalent of
+
+        d = os.path.dirname(sys.modules[package].__file__)
+        data = open(os.path.join(d, resource), 'rb').read()
+
+    If the package cannot be located or loaded, or it uses a PEP 302 loader
+    which does not support get_data(), then None is returned.
+    """
+
+    loader = get_loader(package)
+    if loader is None or not hasattr(loader, 'get_data'):
+        return None
+    mod = sys.modules.get(package) or loader.load_module(package)
+    if mod is None or not hasattr(mod, '__file__'):
+        return None
+
+    # Modify the resource name to be compatible with the loader.get_data
+    # signature - an os.path format "filename" starting with the dirname of
+    # the package's __file__
+    parts = resource.split('/')
+    parts.insert(0, os.path.dirname(mod.__file__))
+    resource_name = os.path.join(*parts)
+    return loader.get_data(resource_name)
index b4077e5af2b8dd4106bbc3527b03aa51ac23a1fc..6cc3678c4fc6a002a35b41d5d6a815a2a2cda867 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -29,6 +29,9 @@ Extensions Modules
 Library
 -------
 
+- Issue #2439: Added new function pkgutil.get_data(), which is a
+  convenience wrapper for the PEP 302 get_data() API.
+
 - Issue #2616: The ctypes.pointer() and ctypes.POINTER() functions are
   now implemented in C for better performance.