Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""
2@file
3@brief Helpers for pip
5Some links to look:
7* `installing_python_packages_programatically.py <https://gist.github.com/rwilcox/755524>`_
8* `Calling pip programmatically <http://blog.ducky.io/python/2013/08/22/calling-pip-programmatically/>`_
9"""
12class PQPipError(Exception):
13 """
14 Any exception raised by one of the following function.
15 """
17 def __init__(self, *args):
18 """
19 @param args either a string 3 strings (cmd, out, err)
20 """
21 if len(args) == 1:
22 Exception.__init__(self, args[0]) # pragma: no cover
23 else:
24 cmd, out, err = args
25 mes = "CMD:\n{0}\nOUT:\n{1}\n[piperror]\n{2}".format(cmd, out, err)
26 Exception.__init__(self, mes)
29class Distribution:
30 """
31 Common interface for old and recent pip packages.
33 .. versionadded:: 1.5
34 """
36 def __init__(self, dist):
37 self.dist = dist
39 def __getattr__(self, attr):
40 if attr == 'key':
41 if hasattr(self.__dict__['dist'], 'key'):
42 return self.__dict__['dist'].key
43 return self.__dict__['dist'].canonical_name
44 if attr == 'dist':
45 return self.__dict__['dist']
46 if attr in {'_get_metadata', 'requires', 'PKG_INFO', 'project_name',
47 'py_version', 'platform', 'extras'}:
48 if hasattr(self.__dict__['dist'], attr):
49 return getattr(self.__dict__['dist'], attr)
50 return getattr(self.__dict__['dist']._dist, attr)
51 return getattr(self.__dict__['dist'], attr)
54def get_installed_distributions(local_only=True, skip=None,
55 include_editables=True, editables_only=False,
56 user_only=False, use_cmd=False):
57 """
58 Directs call to function *get_installed_distributions* from :epkg:`pip`.
60 Return a list of installed Distribution objects.
62 :param local_only: if True (default), only return installations
63 local to the current virtualenv, if in a virtualenv.
64 :param skip: argument is an iterable of lower-case project names to
65 ignore; defaults to ``pip.compat.stdlib_pkgs`` (if *skip* is None)
66 :param editables: if False, don't report editables.
67 :param editables_only: if True , only report editables.
68 :param user_only: if True , only report installations in the user
69 site directory.
70 :param use_cmd: if True, use a different process (updated package list)
71 :return: list of installed Distribution objects.
73 .. versionadded:: 1.5
74 """
75 if use_cmd:
76 raise NotImplementedError("use_cmd should be False")
77 if skip is None:
78 try:
79 from pip._internal.utils.compat import stdlib_pkgs
80 skip = stdlib_pkgs
81 except ImportError:
82 pass
83 try:
84 from pip._internal.metadata import get_default_environment
85 return list(map(Distribution,
86 get_default_environment().iter_installed_distributions(
87 local_only=local_only, skip=skip,
88 include_editables=include_editables,
89 editables_only=editables_only,
90 user_only=user_only)))
92 except ImportError:
93 from pip._internal.utils.misc import get_installed_distributions as getd
94 return list(map(Distribution, getd(
95 local_only=local_only, skip=skip,
96 include_editables=include_editables,
97 editables_only=editables_only,
98 user_only=user_only, use_cmd=use_cmd)))
101def get_packages_list():
102 """
103 calls ``pip list`` to retrieve the list of packages
104 """
105 return get_installed_distributions(local_only=True)
108def package2dict(pkg):
109 """
110 Extracts information from a package.
112 @param pkg type *pip._vendor.pkg_resources.Distribution*
113 @return dictionary
114 """
115 return dict(
116 version=pkg.version,
117 project_name=pkg.project_name,
118 py_version=pkg.py_version,
119 requires=pkg.requires,
120 platform=pkg.platform,
121 extras=pkg.extras,
122 location=pkg.location)
125def get_package_info(name=None, start=0, end=-1):
126 """
127 Calls ``pip show`` to retrieve information about packages.
129 @param name name of he packages or None to get all of them in a list
130 @param start start at package n (in list return by @see fn get_packages_list)
131 @param end end at package n, -1 for all
132 @return dictionary or list of dictionaries
133 """
134 from pip._internal.commands.show import search_packages_info
135 if name is None:
136 res = []
137 packs = get_packages_list()
138 if end == -1:
139 end = len(packs) # pragma: no cover
140 subp = packs[start:end]
141 if len(subp) == 0:
142 raise PQPipError( # pragma: no cover
143 "No package, start={0}, end={1}, len(subp)={2}, len(packs)={3}".format(
144 start, end, len(subp), len(packs)))
145 for cp in subp:
146 pack = cp.project_name
147 info = get_package_info(pack)
148 res.append(info)
149 if len(res) == 0 and len(subp) > 0:
150 raise PQPipError( # pragma: no cover
151 "Empty list, unexpected, start={0}, end={1}, len(subp)={3}".format(
152 start, end, len(subp)))
153 return res
155 res = list(search_packages_info([name]))
156 if len(res) != 1:
157 raise PQPipError( # pragma: no cover
158 "Unexpected number of results {0} for {1}".format(
159 len(res), name))
160 return res[0]