Commits

Anonymous committed d3b9e93 Merge

merging the directory branch

Comments (0)

Files changed (2)

 # -*- coding: utf8 -*-
 """ PEP 376
 """
+from __future__ import with_statement
 import os
 from os.path import join, splitext, isdir
 from os import listdir
             self.obsoletes = None
 
 
+#
+# function used to detect a PEP 376 .egg-info directory
+#
+def is_egg_info(path):
+    """Returns True if `path` is an egg-info directory.
+
+    Also makes sure it doesn't pick older versions by checking
+    the presence of `RECORD` and `PKG-INFO`.
+    """
+    if not (splitext(path)[-1].lower() == '.egg-info' and isdir(path)):
+        return False
+    content = os.listdir(path)
+    return 'PKG-INFO' in content and 'RECORD' in content
+
+
 SEP_TRANS = maketrans('/', os.path.sep)
 
 #
                 return True
         return False
 
-    def owns(self, path):
-        """Returns True is the path is listed in the RECORD file and nowhere
-        else.
-
-        e.g. if the project uses this file.
-        """
-        if not self.uses(path):
-            return False
-
-        for egg_info in get_egg_infos():
-            if egg_info is not self and egg_info.uses(path):
-                return False
-
-        return True
-
     def get_file(self, path, binary=False):
         """Returns a file instance on the path.
 
         return open(fullpath, binary and 'rb' or 'r')
 
 #
-# cache managment
+# Directory represents a directory that contains egg-info files
+#
+class EggInfoDirectory(list):
+
+    def __init__(self, path):
+        self.path = path
+        # filling the list once (see if it's the best way)
+        # to minimize I/O
+        for element in os.listdir(self.path):
+            fullpath = join(self.path, element)
+            if is_egg_info(fullpath):
+                self.append(EggInfo(fullpath))
+
+    def file_users(self, path):
+        """Returns EggInfo instances for the projects that uses `path`."""
+        for egg_info in self:
+            if egg_info.uses(path):
+                yield egg_info
+
+    def owner(self, path):
+        """Returns the owner of `path`."""
+        users = [egg_info for egg_info in self if egg_info.uses(path)]
+        if len(users) == 1:
+            return users[0]
+        return None
+
+#
+# Directories is a collection of directories, initialized with a
+# list of paths.
+#
+class EggInfoDirectories(list):
+
+    def __init__(self, paths=sys.path):
+        super(EggInfoDirectories, self).__init__()
+        for path in paths:
+            if os.path.isdir(path):
+                self.append(EggInfoDirectory(path))
+
+    def get_egg_infos(self):
+        """Iterates on all .egg-info directories founded in sys.path.
+
+        Each returned element is an EggInfo instance.
+        Uses a memory cache to minimize I/O access.
+        """
+        for directory in self:
+            for egg_info in directory:
+                yield egg_info
+
+    def get_egg_info(self, project_name):
+        """Returns an EggInfo instance for the given project name.
+
+        If not found, returns None.
+        """
+        for directory in self:
+            for egg_info in directory:
+                if egg_info.name == project_name:
+                    return egg_info
+
+    def get_file_users(self, path):
+        """Iterates over all projects to find out which project uses the file.
+
+        Return EggInfo instances.
+        """
+        for directory in self:
+            for egg_info in directory.file_users(path):
+                yield egg_info
+
+#
+# high level APIs
 #
 
-_EGG_INFO_CACHE = {}
-_CACHE_ENABLED = True
+def get_egg_infos(paths=sys.path):
+    dirs = EggInfoDirectories(paths)
+    return dirs.get_egg_infos()
 
-def purge_cache():
-    global _EGG_INFO_CACHE
-    _EGG_INFO_CACHE = {}
+def get_egg_info(project_name, paths=sys.path):
+    dirs = EggInfoDirectories(paths)
+    return dirs.get_egg_info(project_name)
 
-def enable_cache():
-    global _CACHE_ENABLED
-    _CACHE_ENABLED = True
+def get_file_users(path, paths=sys.path):
+    dirs = EggInfoDirectories(paths)
+    return dirs.get_file_users(path)
 
-def disable_cache():
-    global _CACHE_ENABLED
-    _CACHE_ENABLED = True
 
-def cache_enabled():
-    return _CACHE_ENABLED
-
-#
-# .egg-info finders
-#
-
-def is_egg_info(path):
-    """Returns True if `path` is an egg-info directory.
-
-    Also makes sure it doesn't pick older versions by checking
-    the presence of `RECORD` and `PKG-INFO`.
-    """
-    if not (splitext(path)[-1].lower() == '.egg-info' and isdir(path)):
-        return False
-    content = os.listdir(path)
-    return 'PKG-INFO' in content and 'RECORD' in content
-
-def egg_info_dirs(path):
-    """Returns the EGG-INFO directories found in `path`."""
-    if is_egg_info(path):
-        yield path
-    elif isdir(path):
-        for element in os.listdir(path):
-            fullpath = join(path, element)
-            if is_egg_info(fullpath):
-                yield fullpath
-
-def get_egg_infos():
-    """Iterates on all .egg-info directories founded in sys.path.
-
-    Each returned element is an EggInfo instance.
-    Uses a memory cache to minimize I/O access.
-    """
-    for path in sys.path:
-        if _CACHE_ENABLED and path in _EGG_INFO_CACHE:
-            for egg_info in _EGG_INFO_CACHE[path]:
-                yield egg_info
-        else:
-            egg_infos = []
-            for egg_info_dir in egg_info_dirs(path):
-                egg_info = EggInfo(egg_info_dir)
-                if _CACHE_ENABLED:
-                    egg_infos.append(egg_info)
-                yield egg_info
-            # the cache is created only if all elements have been
-            # iterated through
-            if _CACHE_ENABLED:
-                _EGG_INFO_CACHE[path] = egg_infos
-
-def get_egg_info(project_name):
-    """Returns an EggInfo instance for the given project name.
-
-    If not found, returns None.
-    """
-    for project in get_egg_infos():
-        if project.name == project_name:
-            return project
-
-#
-# helper for the uninstall feature
-#
-
-def get_file_users(path):
-    """Iterates over all projects to find out which project uses the file.
-
-    Return EggInfo instances.
-    """
-    for egg_info in get_egg_infos():
-        if egg_info.uses(path):
-            yield egg_info
-
     del sys.old
 
 def test_get_egg_infos():
-    projects = list(get_egg_infos())
+    projects = list(get_egg_infos([SITE_PKG]))
     assert_equals(len(projects), 2)
 
-def test_get_egg_info():
-    assert_equals(get_egg_info('xxx'), None)
+def test_egg_info_directory():
+    assert_equals(get_egg_info('xxx', [SITE_PKG]), None)
 
-    project = get_egg_info('mercurial')
+    project = get_egg_info('mercurial', [SITE_PKG])
     assert_equals(project.name, 'mercurial')
 
-    project = get_egg_info('processing')
+    project = get_egg_info('processing', [SITE_PKG])
     assert_equals(project.name, 'processing')
 
 def test_egg_info():
 
-    egg_info = get_egg_info('mercurial')
+    egg_info = get_egg_info('mercurial', [SITE_PKG])
     assert_equals(str(egg_info), "EggInfo('mercurial')")
 
     files = list(egg_info.get_installed_files())
 
     assert egg_info.uses('mercurial/filelog.py')
     assert not egg_info.uses('mercurial/filelog.sasasasa')
-    assert egg_info.owns('mercurial/filelog.pyc')
-    assert not egg_info.owns('mercurial/filelog.py')
+
+
+def test_directory():
+    dir = EggInfoDirectory(SITE_PKG)
+
+    egg_info = dir.owner('mercurial/filelog.pyc')
+    assert egg_info.name == 'mercurial'
+    assert dir.owner('mercurial/filelog.py') is None
 
 def test_get_file_users():
 
-    users = list(get_file_users('mercurial/filelog.py'))
+    users = list(get_file_users('mercurial/filelog.py', [SITE_PKG]))
     assert_equals(len(users), 2)