blob: 090c410808664dcc8e77d5f91c2b244fe08d4963 [file] [log] [blame]
Nick Coghland0cf0632013-11-11 22:11:55 +10001import os
2import os.path
3import pkgutil
4import sys
5import tempfile
6
7# TODO: Remove the --pre flag when a pip 1.5 final copy is available
8
9
10__all__ = ["version", "bootstrap"]
11
12
Donald Stufft8b36dac2013-12-20 19:03:18 -050013_SETUPTOOLS_VERSION = "2.0.1"
Nick Coghland0cf0632013-11-11 22:11:55 +100014
Donald Stufft8b36dac2013-12-20 19:03:18 -050015_PIP_VERSION = "1.5rc2"
Nick Coghland0cf0632013-11-11 22:11:55 +100016
17_PROJECTS = [
18 ("setuptools", _SETUPTOOLS_VERSION),
19 ("pip", _PIP_VERSION),
20]
21
22
Nick Coghlanfdf3a622013-11-30 17:15:09 +100023def _run_pip(args, additional_paths=None):
Nick Coghland0cf0632013-11-11 22:11:55 +100024 # Add our bundled software to the sys.path so we can import it
Nick Coghlanfdf3a622013-11-30 17:15:09 +100025 if additional_paths is not None:
26 sys.path = additional_paths + sys.path
Nick Coghland0cf0632013-11-11 22:11:55 +100027
28 # Install the bundled software
29 import pip
30 pip.main(args)
31
32
33def version():
34 """
35 Returns a string specifying the bundled version of pip.
36 """
37 return _PIP_VERSION
38
Nick Coghlaned9af522013-12-23 17:39:12 +100039def _clear_pip_environment_variables():
40 # We deliberately ignore all pip environment variables
41 # when invoking pip
42 # See http://bugs.python.org/issue19734 for details
43 keys_to_remove = [k for k in os.environ if k.startswith("PIP_")]
44 for k in keys_to_remove:
45 del os.environ[k]
46
Nick Coghland0cf0632013-11-11 22:11:55 +100047
48def bootstrap(*, root=None, upgrade=False, user=False,
49 altinstall=False, default_pip=False,
50 verbosity=0):
51 """
52 Bootstrap pip into the current Python installation (or the given root
53 directory).
Nick Coghlan6256fcb2013-12-23 16:16:07 +100054
55 Note that calling this function will alter both sys.path and os.environ.
Nick Coghland0cf0632013-11-11 22:11:55 +100056 """
57 if altinstall and default_pip:
58 raise ValueError("Cannot use altinstall and default_pip together")
59
Nick Coghlaned9af522013-12-23 17:39:12 +100060 _clear_pip_environment_variables()
Nick Coghlan6256fcb2013-12-23 16:16:07 +100061
Nick Coghland0cf0632013-11-11 22:11:55 +100062 # By default, installing pip and setuptools installs all of the
63 # following scripts (X.Y == running Python version):
64 #
65 # pip, pipX, pipX.Y, easy_install, easy_install-X.Y
66 #
67 # pip 1.5+ allows ensurepip to request that some of those be left out
68 if altinstall:
69 # omit pip, pipX and easy_install
70 os.environ["ENSUREPIP_OPTIONS"] = "altinstall"
71 elif not default_pip:
72 # omit pip and easy_install
73 os.environ["ENSUREPIP_OPTIONS"] = "install"
74
75 with tempfile.TemporaryDirectory() as tmpdir:
76 # Put our bundled wheels into a temporary directory and construct the
77 # additional paths that need added to sys.path
78 additional_paths = []
79 for project, version in _PROJECTS:
80 wheel_name = "{}-{}-py2.py3-none-any.whl".format(project, version)
81 whl = pkgutil.get_data(
82 "ensurepip",
83 "_bundled/{}".format(wheel_name),
84 )
85 with open(os.path.join(tmpdir, wheel_name), "wb") as fp:
86 fp.write(whl)
87
88 additional_paths.append(os.path.join(tmpdir, wheel_name))
89
90 # Construct the arguments to be passed to the pip command
91 args = [
92 "install", "--no-index", "--find-links", tmpdir,
93 # Temporary until pip 1.5 is final
94 "--pre",
95 ]
96 if root:
97 args += ["--root", root]
98 if upgrade:
99 args += ["--upgrade"]
100 if user:
101 args += ["--user"]
102 if verbosity:
103 args += ["-" + "v" * verbosity]
104
105 _run_pip(args + [p[0] for p in _PROJECTS], additional_paths)
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000106
107def _uninstall(*, verbosity=0):
Nick Coghlaned9af522013-12-23 17:39:12 +1000108 """Helper to support a clean default uninstall process on Windows
109
110 Note that calling this function may alter os.environ.
111 """
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000112 # Nothing to do if pip was never installed, or has been removed
113 try:
114 import pip
115 except ImportError:
116 return
117
118 # If the pip version doesn't match the bundled one, leave it alone
119 if pip.__version__ != _PIP_VERSION:
120 msg = ("ensurepip will only uninstall a matching pip "
121 "({!r} installed, {!r} bundled)")
122 raise RuntimeError(msg.format(pip.__version__, _PIP_VERSION))
123
Nick Coghlaned9af522013-12-23 17:39:12 +1000124 _clear_pip_environment_variables()
125
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000126 # Construct the arguments to be passed to the pip command
127 args = ["uninstall", "-y"]
128 if verbosity:
129 args += ["-" + "v" * verbosity]
130
131 _run_pip(args + [p[0] for p in reversed(_PROJECTS)])