1#!/usr/bin/env python2 2from __future__ import print_function 3 4import os 5import os.path 6import pkgutil 7import shutil 8import sys 9import tempfile 10 11 12__all__ = ["version", "bootstrap"] 13 14 15_SETUPTOOLS_VERSION = "28.8.0" 16 17_PIP_VERSION = "9.0.1" 18 19_PROJECTS = [ 20 ("setuptools", _SETUPTOOLS_VERSION), 21 ("pip", _PIP_VERSION), 22] 23 24 25def _run_pip(args, additional_paths=None): 26 # Add our bundled software to the sys.path so we can import it 27 if additional_paths is not None: 28 sys.path = additional_paths + sys.path 29 30 # Install the bundled software 31 import pip 32 pip.main(args) 33 34 35def version(): 36 """ 37 Returns a string specifying the bundled version of pip. 38 """ 39 return _PIP_VERSION 40 41 42def _disable_pip_configuration_settings(): 43 # We deliberately ignore all pip environment variables 44 # when invoking pip 45 # See http://bugs.python.org/issue19734 for details 46 keys_to_remove = [k for k in os.environ if k.startswith("PIP_")] 47 for k in keys_to_remove: 48 del os.environ[k] 49 # We also ignore the settings in the default pip configuration file 50 # See http://bugs.python.org/issue20053 for details 51 os.environ['PIP_CONFIG_FILE'] = os.devnull 52 53 54def bootstrap(root=None, upgrade=False, user=False, 55 altinstall=False, default_pip=True, 56 verbosity=0): 57 """ 58 Bootstrap pip into the current Python installation (or the given root 59 directory). 60 61 Note that calling this function will alter both sys.path and os.environ. 62 """ 63 if altinstall and default_pip: 64 raise ValueError("Cannot use altinstall and default_pip together") 65 66 _disable_pip_configuration_settings() 67 68 # By default, installing pip and setuptools installs all of the 69 # following scripts (X.Y == running Python version): 70 # 71 # pip, pipX, pipX.Y, easy_install, easy_install-X.Y 72 # 73 # pip 1.5+ allows ensurepip to request that some of those be left out 74 if altinstall: 75 # omit pip, pipX and easy_install 76 os.environ["ENSUREPIP_OPTIONS"] = "altinstall" 77 elif not default_pip: 78 # omit pip and easy_install 79 os.environ["ENSUREPIP_OPTIONS"] = "install" 80 81 tmpdir = tempfile.mkdtemp() 82 try: 83 # Put our bundled wheels into a temporary directory and construct the 84 # additional paths that need added to sys.path 85 additional_paths = [] 86 for project, version in _PROJECTS: 87 wheel_name = "{}-{}-py2.py3-none-any.whl".format(project, version) 88 whl = pkgutil.get_data( 89 "ensurepip", 90 "_bundled/{}".format(wheel_name), 91 ) 92 with open(os.path.join(tmpdir, wheel_name), "wb") as fp: 93 fp.write(whl) 94 95 additional_paths.append(os.path.join(tmpdir, wheel_name)) 96 97 # Construct the arguments to be passed to the pip command 98 args = ["install", "--no-index", "--find-links", tmpdir] 99 if root: 100 args += ["--root", root] 101 if upgrade: 102 args += ["--upgrade"] 103 if user: 104 args += ["--user"] 105 if verbosity: 106 args += ["-" + "v" * verbosity] 107 108 _run_pip(args + [p[0] for p in _PROJECTS], additional_paths) 109 finally: 110 shutil.rmtree(tmpdir, ignore_errors=True) 111 112 113def _uninstall_helper(verbosity=0): 114 """Helper to support a clean default uninstall process on Windows 115 116 Note that calling this function may alter os.environ. 117 """ 118 # Nothing to do if pip was never installed, or has been removed 119 try: 120 import pip 121 except ImportError: 122 return 123 124 # If the pip version doesn't match the bundled one, leave it alone 125 if pip.__version__ != _PIP_VERSION: 126 msg = ("ensurepip will only uninstall a matching version " 127 "({!r} installed, {!r} bundled)") 128 print(msg.format(pip.__version__, _PIP_VERSION), file=sys.stderr) 129 return 130 131 _disable_pip_configuration_settings() 132 133 # Construct the arguments to be passed to the pip command 134 args = ["uninstall", "-y", "--disable-pip-version-check"] 135 if verbosity: 136 args += ["-" + "v" * verbosity] 137 138 _run_pip(args + [p[0] for p in reversed(_PROJECTS)]) 139 140 141def _main(argv=None): 142 import argparse 143 parser = argparse.ArgumentParser(prog="python -m ensurepip") 144 parser.add_argument( 145 "--version", 146 action="version", 147 version="pip {}".format(version()), 148 help="Show the version of pip that is bundled with this Python.", 149 ) 150 parser.add_argument( 151 "-v", "--verbose", 152 action="count", 153 default=0, 154 dest="verbosity", 155 help=("Give more output. Option is additive, and can be used up to 3 " 156 "times."), 157 ) 158 parser.add_argument( 159 "-U", "--upgrade", 160 action="store_true", 161 default=False, 162 help="Upgrade pip and dependencies, even if already installed.", 163 ) 164 parser.add_argument( 165 "--user", 166 action="store_true", 167 default=False, 168 help="Install using the user scheme.", 169 ) 170 parser.add_argument( 171 "--root", 172 default=None, 173 help="Install everything relative to this alternate root directory.", 174 ) 175 parser.add_argument( 176 "--altinstall", 177 action="store_true", 178 default=False, 179 help=("Make an alternate install, installing only the X.Y versioned" 180 "scripts (Default: pipX, pipX.Y, easy_install-X.Y)"), 181 ) 182 parser.add_argument( 183 "--default-pip", 184 action="store_true", 185 default=True, 186 dest="default_pip", 187 help=argparse.SUPPRESS, 188 ) 189 parser.add_argument( 190 "--no-default-pip", 191 action="store_false", 192 dest="default_pip", 193 help=("Make a non default install, installing only the X and X.Y " 194 "versioned scripts."), 195 ) 196 197 args = parser.parse_args(argv) 198 199 bootstrap( 200 root=args.root, 201 upgrade=args.upgrade, 202 user=args.user, 203 verbosity=args.verbosity, 204 altinstall=args.altinstall, 205 default_pip=args.default_pip, 206 ) 207