[Python-checkins] distutils2: added distutils2.util.find_packages

tarek.ziade python-checkins at python.org
Thu May 6 12:48:46 CEST 2010


tarek.ziade pushed 7c97f99f508b to distutils2:

http://hg.python.org/distutils2/rev/7c97f99f508b
changeset:   123:7c97f99f508b
user:        Tarek Ziade <tarek at ziade.org>
date:        Thu May 06 12:05:44 2010 +0200
summary:     added distutils2.util.find_packages
files:       src/CHANGES.txt, src/distutils2/tests/test_util.py, src/distutils2/util.py

diff --git a/src/CHANGES.txt b/src/CHANGES.txt
--- a/src/CHANGES.txt
+++ b/src/CHANGES.txt
@@ -5,6 +5,8 @@
 1.0a1
 -----
 
-- Initial import from the stdlib
+- Initial import from the stdlib [tarek]
+- Added support for PEP 376 in distutils2.version [tarek]
+- Added support for PEP 345 in distutils2.metadata [tarek]
+- Added distutils2.util.find_package [tarek]
 
-
diff --git a/src/distutils2/tests/test_util.py b/src/distutils2/tests/test_util.py
--- a/src/distutils2/tests/test_util.py
+++ b/src/distutils2/tests/test_util.py
@@ -14,7 +14,7 @@
                             check_environ, split_quoted, strtobool,
                             rfc822_escape, get_compiler_versions,
                             _find_exe_version, _MAC_OS_X_LD_VERSION,
-                            byte_compile)
+                            byte_compile, find_packages)
 from distutils2 import util
 from distutils2.tests import support
 
@@ -32,7 +32,9 @@
             self.stdout = StringIO(exes[self.cmd])
             self.stderr = StringIO()
 
-class UtilTestCase(support.EnvironGuard, unittest2.TestCase):
+class UtilTestCase(support.EnvironGuard,
+                   support.TempdirManager,
+                   unittest2.TestCase):
 
     def setUp(self):
         super(UtilTestCase, self).setUp()
@@ -257,6 +259,40 @@
         self.assertRaises(DistutilsFileError, util.newer, 'xxx', 'xxx')
 
 
+    def test_find_packages(self):
+        # let's create a structure we want to scan:
+        #
+        #   pkg1
+        #     __init__
+        #     pkg2
+        #       __init__
+        #     pkg3
+        #       __init__
+        #       pkg6
+        #           __init__
+        #     pkg4
+        #   pkg5
+        #     __init__
+        #
+        root = self.mkdtemp()
+        pkg1 = os.path.join(root, 'pkg1')
+        os.mkdir(pkg1)
+        self.write_file(os.path.join(pkg1, '__init__.py'))
+        os.mkdir(os.path.join(pkg1, 'pkg2'))
+        self.write_file(os.path.join(pkg1, 'pkg2', '__init__.py'))
+        os.mkdir(os.path.join(pkg1, 'pkg3'))
+        self.write_file(os.path.join(pkg1, 'pkg3', '__init__.py'))
+        os.mkdir(os.path.join(pkg1, 'pkg3', 'pkg6'))
+        self.write_file(os.path.join(pkg1, 'pkg3', 'pkg6', '__init__.py'))
+        os.mkdir(os.path.join(pkg1, 'pkg4'))
+        pkg5 = os.path.join(root, 'pkg5')
+        os.mkdir(pkg5)
+        self.write_file(os.path.join(pkg5, '__init__.py'))
+
+        res = find_packages([root], ['pkg1.pkg2'])
+        self.assertEquals(res, ['pkg1', 'pkg5', 'pkg1.pkg3', 'pkg1.pkg3.pkg6'])
+
+
 def test_suite():
     return unittest2.makeSuite(UtilTestCase)
 
diff --git a/src/distutils2/util.py b/src/distutils2/util.py
--- a/src/distutils2/util.py
+++ b/src/distutils2/util.py
@@ -7,6 +7,7 @@
 __revision__ = "$Id: util.py 77761 2010-01-26 22:46:15Z tarek.ziade $"
 
 import sys, os, string, re
+from fnmatch import fnmatchcase
 
 from distutils2.errors import (DistutilsPlatformError, DistutilsFileError,
                                DistutilsByteCompileError)
@@ -543,3 +544,51 @@
         f.write(line + "\n")
     f.close()
 
+def _is_package(path):
+    """Returns True if path is a package (a dir with an __init__ file."""
+    if not os.path.isdir(path):
+        return False
+    return os.path.isfile(os.path.join(path, '__init__.py'))
+
+def _package_name(root_path, path):
+    """Returns a dotted package name, given a subpath."""
+    if not path.startswith(root_path):
+        raise ValueError('"%s" is not a subpath of "%s"' % (path, root_path))
+    return path[len(root_path) + 1:].replace(os.sep, '.')
+
+def find_packages(paths=('.',), exclude=()):
+    """Return a list all Python packages found recursively within
+    directories 'paths'
+
+    'paths' should be supplied as a sequence of "cross-platform"
+    (i.e. URL-style) path; it will be converted to the appropriate local
+    path syntax.
+
+    'exclude' is a sequence of package names to exclude; '*' can be used as
+    a wildcard in the names, such that 'foo.*' will exclude all subpackages
+    of 'foo' (but not 'foo' itself).
+    """
+    packages = []
+    for path in paths:
+        path = convert_path(path)
+        for root, dirs, files in os.walk(path):
+            for dir_ in dirs:
+                fullpath = os.path.join(root, dir_)
+                # we work only with Python packages
+                if not _is_package(fullpath):
+                    continue
+
+                # see if it's excluded
+                excluded = False
+                package_name = _package_name(path, fullpath)
+                for pattern in exclude:
+                    if fnmatchcase(package_name, pattern):
+                        excluded = True
+                        break
+                if excluded:
+                    continue
+
+                # adding it to the list
+                packages.append(package_name)
+    return packages
+

--
Repository URL: http://hg.python.org/distutils2


More information about the Python-checkins mailing list