Commits

Anonymous committed 1392949 Merge

merge

Comments (0)

Files changed (4)

pip/commands/freeze.py

 from pip.req import InstallRequirement
 from pip.log import logger
 from pip.basecommand import Command
+from pip.util import dist_location, is_local
 
 class FreezeCommand(Command):
     name = 'freeze'
             default=[],
             metavar='URL',
             help='URL for finding packages, which will be added to the frozen requirements file')
+        self.parser.add_option(
+            '-l', '--local',
+            dest='local',
+            action='store_true',
+            default=False,
+            help='If in a virtualenv, do not report globally-installed packages')
 
     def run(self, options, args):
         requirement = options.requirement
         find_links = options.find_links or []
+        local_only = options.local
         ## FIXME: Obviously this should be settable:
         find_tags = False
         skip_match = None
             f.write('-f %s\n' % link)
         installations = {}
         for dist in pkg_resources.working_set:
+            if local_only and not is_local(dist_location(dist)):
+                continue
             if dist.key in ('setuptools', 'pip', 'python'):
                 ## FIXME: also skip virtualenv?
                 continue
 from pip.util import display_path, rmtree, format_size
 from pip.util import splitext, ask, backup_dir
 from pip.util import url_to_filename, filename_to_url
-from pip.util import is_url, is_filename
-from pip.util import renames, normalize_path, is_framework_layout
+from pip.util import is_url, is_filename, is_local
+from pip.util import renames, normalize_path, egg_link_path
 from pip.util import make_path_relative, is_svn_page, file_contents
 from pip.util import has_leading_dir, split_leading_dir
 from pip.util import get_file_content
         if not self.check_if_exists():
             raise UninstallationError("Cannot uninstall requirement %s, not installed" % (self.name,))
         dist = self.satisfied_by or self.conflicts_with
-        paths_to_remove = UninstallPathSet(dist, sys.prefix)
+
+        paths_to_remove = UninstallPathSet(dist)
 
         pip_egg_info_path = os.path.join(dist.location,
                                          dist.egg_name()) + '.egg-info'
         easy_install_egg = dist.egg_name() + '.egg'
-        # This won't find a globally-installed develop egg if
-        # we're in a virtualenv.
-        # (There doesn't seem to be any metadata in the
-        # Distribution object for a develop egg that points back
-        # to its .egg-link and easy-install.pth files).  That's
-        # OK, because we restrict ourselves to making changes
-        # within sys.prefix anyway.
-        develop_egg_link = os.path.join(site_packages,
-                                        dist.project_name) + '.egg-link'
+        develop_egg_link = egg_link_path(dist)
         if os.path.exists(pip_egg_info_path):
             # package installed by pip
             paths_to_remove.add(pip_egg_info_path)
 class UninstallPathSet(object):
     """A set of file paths to be removed in the uninstallation of a
     requirement."""
-    def __init__(self, dist, restrict_to_prefix):
+    def __init__(self, dist):
         self.paths = set()
         self._refuse = set()
         self.pth = {}
-        self.prefix = normalize_path(restrict_to_prefix)
         self.dist = dist
         self.location = normalize_path(dist.location)
         self.save_dir = None
         False otherwise.
 
         """
-        ok_prefixes = [self.prefix]
-        # Yep, we are special casing the framework layout of MacPython here
-        if is_framework_layout(sys.prefix):
-            for location in ('/Library', '/usr/local'):
-                if path.startswith(location):
-                    ok_prefixes.append(location)
-        return any([path.startswith(prefix) for prefix in ok_prefixes])
+        return is_local(path)
         
     def _can_uninstall(self):
         if not self._permitted(self.location):
             logger.notify("Not uninstalling %s at %s, outside environment %s"
-                          % (self.dist.project_name, self.location,
-                             self.prefix))
+                          % (self.dist.project_name, self.location, sys.prefix))
             return False
         return True
 
 import re
 from pip.backwardcompat import WindowsError
 from pip.exceptions import InstallationError
+from pip.locations import site_packages
 
 __all__ = ['rmtree', 'display_path', 'backup_dir',
            'find_command', 'splitext', 'ask', 'Inf',
            'format_size', 'is_url', 'is_filename',
            'strip_prefix', 'is_svn_page', 'file_contents',
            'split_leading_dir', 'has_leading_dir',
-           'make_path_relative', 'normalize_path', 'is_framework_layout',
+           'make_path_relative', 'normalize_path',
            'get_file_content', 'renames']
 
 def rmtree(dir):
     """
     return os.path.normcase(os.path.realpath(path))
 
-def is_framework_layout(site_packages_dir):
-    """Return True if the current platform is the default Python of Mac OS X
-    which installs scripts in /usr/local/bin"""
-    return (sys.platform[:6] == 'darwin' and
-            (site_packages_dir[:9] == '/Library/' or
-             site_packages_dir[:16] == '/System/Library/'))
-
 _scheme_re = re.compile(r'^(http|https|file):', re.I)
 _url_slash_drive_re = re.compile(r'/*([a-z])\|', re.I)
 
             os.removedirs(head)
         except OSError:
             pass
+
+def is_local(path):
+    """
+    Return True if path is within sys.prefix, if we're running in a virtualenv.
+
+    If we're not in a virtualenv, all paths are considered "local."
+
+    """
+    if not hasattr(sys, 'real_prefix'):
+        return True
+    return normalize_path(path).startswith(normalize_path(sys.prefix))
+
+def egg_link_path(dist):
+    """
+    Return the path where we'd expect to find a .egg-link file for
+    this distribution. (There doesn't seem to be any metadata in the
+    Distribution object for a develop egg that points back to its
+    .egg-link and easy-install.pth files).
+
+    This won't find a globally-installed develop egg if we're in a
+    virtualenv. 
+
+    """
+    return os.path.join(site_packages, dist.project_name) + '.egg-link'
+
+def dist_location(dist):
+    """
+    Get the site-packages location of this distribution. Generally
+    this is dist.location, except in the case of develop-installed
+    packages, where dist.location is the source code location, and we
+    want to know where the egg-link file is.
+
+    """
+    egg_link = egg_link_path(dist)
+    if os.path.exists(egg_link):
+        return egg_link
+    return dist.location

tests/test_freeze.txt

     -e hg+http://bitbucket.org/jezdez/django-dbtemplates/@...#egg=django_dbtemplates-...
     ...
 
-Heck, now look in the Bazaar:
+Heck, now look in the Bazaar::
 
     >>> reset_env()
     >>> env = get_env()
     -f bzr+http://bazaar.launchpad.net/...django-wikiapp/django-wikiapp/release-0.1/#egg=django-wikiapp
     -e bzr+http://bazaar.launchpad.net/...django-wikiapp/django-wikiapp/release-0.1/@...#egg=django_wikiapp-...
     ...
+
+
+Test that wsgiref (from global site-packages) is reported normally, but not with --local::
+
+    >>> reset_env()
+    >>> result = run_pip('install', 'initools==0.2')
+    >>> result = run_pip('freeze', expect_stderr=True)
+    >>> print result
+    Script result: ...ython... pip.main() .../test-scratch freeze
+    -- stdout: --------------------
+    INITools==0.2
+    wsgiref==...
+    <BLANKLINE>
+    >>> result2 = run_pip('freeze', '--local', expect_stderr=True)
+    >>> print result2
+    Script result: ...ython... pip.main() .../test-scratch freeze --local
+    -- stdout: --------------------
+    INITools==0.2
+    <BLANKLINE>
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.