Skip to content

Commit 982a891

Browse files
committed
'pip freeze {NAME}' outputs the installed versions of package {NAME} and its recursive dependencies.
1 parent 80fb4fd commit 982a891

File tree

1 file changed

+31
-3
lines changed

1 file changed

+31
-3
lines changed

pip/commands/freeze.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,30 @@
77
from pip.log import logger
88
from pip.basecommand import Command
99
from pip.util import get_installed_distributions
10+
from pip._vendor import pkg_resources
11+
1012

1113
# packages to exclude from freeze output
1214
freeze_excludes = stdlib_pkgs + ['setuptools', 'pip', 'distribute']
1315

1416

17+
def recursive_dependencies(query):
18+
"""Return list of dependencies of ``dists``, recursively."""
19+
dependencies = set()
20+
installed = dict(
21+
[(p.project_name.lower(), p) for p in pkg_resources.working_set])
22+
query_names = [name.lower() for name in query]
23+
for pkg in query_names:
24+
try:
25+
dist = installed[pkg]
26+
for dep in dist.requires():
27+
dependencies.add(dep.project_name)
28+
dependencies.update(recursive_dependencies([dep.project_name]))
29+
except KeyError:
30+
pass # pkg is not installed.
31+
return dependencies
32+
33+
1534
class FreezeCommand(Command):
1635
"""
1736
Output installed packages in requirements format.
@@ -20,7 +39,7 @@ class FreezeCommand(Command):
2039
"""
2140
name = 'freeze'
2241
usage = """
23-
%prog [options]"""
42+
%prog [options] [PACKAGE PACKAGE...]"""
2443
summary = 'Output installed packages in requirements format.'
2544

2645
def __init__(self, *args, **kw):
@@ -72,10 +91,19 @@ def run(self, options, args):
7291
for link in find_links:
7392
f.write('-f %s\n' % link)
7493
installations = {}
94+
95+
only_dists = []
96+
if args:
97+
only_dists = args
98+
only_dists.extend(recursive_dependencies(only_dists))
99+
only_dists = [name.lower() for name in only_dists]
100+
75101
for dist in get_installed_distributions(local_only=local_only,
76102
skip=freeze_excludes):
77-
req = pip.FrozenRequirement.from_dist(dist, find_tags=find_tags)
78-
installations[req.name] = req
103+
if not only_dists or dist.project_name.lower() in only_dists:
104+
req = pip.FrozenRequirement.from_dist(
105+
dist, find_tags=find_tags)
106+
installations[req.name] = req
79107
if requirement:
80108
req_f = open(requirement)
81109
for line in req_f:

0 commit comments

Comments
 (0)