mirror of https://github.com/python/cpython
115 lines
3.4 KiB
Python
115 lines
3.4 KiB
Python
import os
|
|
import os.path
|
|
import pkgutil
|
|
import sys
|
|
import tempfile
|
|
|
|
# TODO: Remove the --pre flag when a pip 1.5 final copy is available
|
|
|
|
|
|
__all__ = ["version", "bootstrap"]
|
|
|
|
|
|
_SETUPTOOLS_VERSION = "1.3.2"
|
|
|
|
_PIP_VERSION = "1.5rc1"
|
|
|
|
_PROJECTS = [
|
|
("setuptools", _SETUPTOOLS_VERSION),
|
|
("pip", _PIP_VERSION),
|
|
]
|
|
|
|
|
|
def _run_pip(args, additional_paths=None):
|
|
# Add our bundled software to the sys.path so we can import it
|
|
if additional_paths is not None:
|
|
sys.path = additional_paths + sys.path
|
|
|
|
# Install the bundled software
|
|
import pip
|
|
pip.main(args)
|
|
|
|
|
|
def version():
|
|
"""
|
|
Returns a string specifying the bundled version of pip.
|
|
"""
|
|
return _PIP_VERSION
|
|
|
|
|
|
def bootstrap(*, root=None, upgrade=False, user=False,
|
|
altinstall=False, default_pip=False,
|
|
verbosity=0):
|
|
"""
|
|
Bootstrap pip into the current Python installation (or the given root
|
|
directory).
|
|
"""
|
|
if altinstall and default_pip:
|
|
raise ValueError("Cannot use altinstall and default_pip together")
|
|
|
|
# By default, installing pip and setuptools installs all of the
|
|
# following scripts (X.Y == running Python version):
|
|
#
|
|
# pip, pipX, pipX.Y, easy_install, easy_install-X.Y
|
|
#
|
|
# pip 1.5+ allows ensurepip to request that some of those be left out
|
|
if altinstall:
|
|
# omit pip, pipX and easy_install
|
|
os.environ["ENSUREPIP_OPTIONS"] = "altinstall"
|
|
elif not default_pip:
|
|
# omit pip and easy_install
|
|
os.environ["ENSUREPIP_OPTIONS"] = "install"
|
|
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
# Put our bundled wheels into a temporary directory and construct the
|
|
# additional paths that need added to sys.path
|
|
additional_paths = []
|
|
for project, version in _PROJECTS:
|
|
wheel_name = "{}-{}-py2.py3-none-any.whl".format(project, version)
|
|
whl = pkgutil.get_data(
|
|
"ensurepip",
|
|
"_bundled/{}".format(wheel_name),
|
|
)
|
|
with open(os.path.join(tmpdir, wheel_name), "wb") as fp:
|
|
fp.write(whl)
|
|
|
|
additional_paths.append(os.path.join(tmpdir, wheel_name))
|
|
|
|
# Construct the arguments to be passed to the pip command
|
|
args = [
|
|
"install", "--no-index", "--find-links", tmpdir,
|
|
# Temporary until pip 1.5 is final
|
|
"--pre",
|
|
]
|
|
if root:
|
|
args += ["--root", root]
|
|
if upgrade:
|
|
args += ["--upgrade"]
|
|
if user:
|
|
args += ["--user"]
|
|
if verbosity:
|
|
args += ["-" + "v" * verbosity]
|
|
|
|
_run_pip(args + [p[0] for p in _PROJECTS], additional_paths)
|
|
|
|
def _uninstall(*, verbosity=0):
|
|
"""Helper to support a clean default uninstall process on Windows"""
|
|
# Nothing to do if pip was never installed, or has been removed
|
|
try:
|
|
import pip
|
|
except ImportError:
|
|
return
|
|
|
|
# If the pip version doesn't match the bundled one, leave it alone
|
|
if pip.__version__ != _PIP_VERSION:
|
|
msg = ("ensurepip will only uninstall a matching pip "
|
|
"({!r} installed, {!r} bundled)")
|
|
raise RuntimeError(msg.format(pip.__version__, _PIP_VERSION))
|
|
|
|
# Construct the arguments to be passed to the pip command
|
|
args = ["uninstall", "-y"]
|
|
if verbosity:
|
|
args += ["-" + "v" * verbosity]
|
|
|
|
_run_pip(args + [p[0] for p in reversed(_PROJECTS)])
|