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 = "39.0.1" 16 17_PIP_VERSION = "10.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._internal 32 return pip._internal.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 # Discard the return value 64 _bootstrap(root=root, upgrade=upgrade, user=user, 65 altinstall=altinstall, default_pip=default_pip, 66 verbosity=verbosity) 67 68 69def _bootstrap(root=None, upgrade=False, user=False, 70 altinstall=False, default_pip=True, 71 verbosity=0): 72 """ 73 Bootstrap pip into the current Python installation (or the given root 74 directory). Returns pip command status code. 75 76 Note that calling this function will alter both sys.path and os.environ. 77 """ 78 if altinstall and default_pip: 79 raise ValueError("Cannot use altinstall and default_pip together") 80 81 _disable_pip_configuration_settings() 82 83 # By default, installing pip and setuptools installs all of the 84 # following scripts (X.Y == running Python version): 85 # 86 # pip, pipX, pipX.Y, easy_install, easy_install-X.Y 87 # 88 # pip 1.5+ allows ensurepip to request that some of those be left out 89 if altinstall: 90 # omit pip, pipX and easy_install 91 os.environ["ENSUREPIP_OPTIONS"] = "altinstall" 92 elif not default_pip: 93 # omit pip and easy_install 94 os.environ["ENSUREPIP_OPTIONS"] = "install" 95 96 tmpdir = tempfile.mkdtemp() 97 try: 98 # Put our bundled wheels into a temporary directory and construct the 99 # additional paths that need added to sys.path 100 additional_paths = [] 101 for project, version in _PROJECTS: 102 wheel_name = "{}-{}-py2.py3-none-any.whl".format(project, version) 103 whl = pkgutil.get_data( 104 "ensurepip", 105 "_bundled/{}".format(wheel_name), 106 ) 107 with open(os.path.join(tmpdir, wheel_name), "wb") as fp: 108 fp.write(whl) 109 110 additional_paths.append(os.path.join(tmpdir, wheel_name)) 111 112 # Construct the arguments to be passed to the pip command 113 args = ["install", "--no-index", "--find-links", tmpdir] 114 if root: 115 args += ["--root", root] 116 if upgrade: 117 args += ["--upgrade"] 118 if user: 119 args += ["--user"] 120 if verbosity: 121 args += ["-" + "v" * verbosity] 122 123 return _run_pip(args + [p[0] for p in _PROJECTS], additional_paths) 124 finally: 125 shutil.rmtree(tmpdir, ignore_errors=True) 126 127def _uninstall_helper(verbosity=0): 128 """Helper to support a clean default uninstall process on Windows 129 130 Note that calling this function may alter os.environ. 131 """ 132 # Nothing to do if pip was never installed, or has been removed 133 try: 134 import pip 135 except ImportError: 136 return 137 138 # If the pip version doesn't match the bundled one, leave it alone 139 if pip.__version__ != _PIP_VERSION: 140 msg = ("ensurepip will only uninstall a matching version " 141 "({!r} installed, {!r} bundled)") 142 print(msg.format(pip.__version__, _PIP_VERSION), file=sys.stderr) 143 return 144 145 _disable_pip_configuration_settings() 146 147 # Construct the arguments to be passed to the pip command 148 args = ["uninstall", "-y", "--disable-pip-version-check"] 149 if verbosity: 150 args += ["-" + "v" * verbosity] 151 152 return _run_pip(args + [p[0] for p in reversed(_PROJECTS)]) 153 154 155def _main(argv=None): 156 import argparse 157 parser = argparse.ArgumentParser(prog="python -m ensurepip") 158 parser.add_argument( 159 "--version", 160 action="version", 161 version="pip {}".format(version()), 162 help="Show the version of pip that is bundled with this Python.", 163 ) 164 parser.add_argument( 165 "-v", "--verbose", 166 action="count", 167 default=0, 168 dest="verbosity", 169 help=("Give more output. Option is additive, and can be used up to 3 " 170 "times."), 171 ) 172 parser.add_argument( 173 "-U", "--upgrade", 174 action="store_true", 175 default=False, 176 help="Upgrade pip and dependencies, even if already installed.", 177 ) 178 parser.add_argument( 179 "--user", 180 action="store_true", 181 default=False, 182 help="Install using the user scheme.", 183 ) 184 parser.add_argument( 185 "--root", 186 default=None, 187 help="Install everything relative to this alternate root directory.", 188 ) 189 parser.add_argument( 190 "--altinstall", 191 action="store_true", 192 default=False, 193 help=("Make an alternate install, installing only the X.Y versioned " 194 "scripts (Default: pipX, pipX.Y, easy_install-X.Y)."), 195 ) 196 parser.add_argument( 197 "--default-pip", 198 action="store_true", 199 default=True, 200 dest="default_pip", 201 help=argparse.SUPPRESS, 202 ) 203 parser.add_argument( 204 "--no-default-pip", 205 action="store_false", 206 dest="default_pip", 207 help=("Make a non default install, installing only the X and X.Y " 208 "versioned scripts."), 209 ) 210 211 args = parser.parse_args(argv) 212 213 return _bootstrap( 214 root=args.root, 215 upgrade=args.upgrade, 216 user=args.user, 217 verbosity=args.verbosity, 218 altinstall=args.altinstall, 219 default_pip=args.default_pip, 220 ) 221