packages bundled in ensurepip bundled have wheelname set packages from wheelpkgdir have wheelpath set directory of system wheel packages some linux distribution packaging policies recommend against bundling dependencies for example fedora installs wheel packages in the usrsharepythonwheels directory and don t install the ensurepip bundled package ignore path doesn t exist or permission error make the code deterministic if a directory contains multiple wheel files of the same package but don t attempt to implement correct version comparison since this case should not happen filename is like pip21 2 4py3noneany whl extract 21 2 4 from pip21 2 4py3noneany whl only used the wheel package directory if all packages are found there run the bootstrapping in a subprocess to avoid leaking any state that happens after pip has executed particularly this avoids the case when pip holds onto the files in additionalpaths preventing us to remove them at the end of the invocation cmd sys executable w ignore deprecationwarning c code if sys flags isolated run code in isolated mode if currently running isolated cmd insert1 i return subprocess runcmd checktrue returncode def version return getpackages pip version def disablepipconfigurationsettings we deliberately ignore all pip environment variables when invoking pip see http bugs python orgissue19734 for details keystoremove k for k in os environ if k startswithpip for k in keystoremove del os environk we also ignore the settings in the default pip configuration file see http bugs python orgissue20053 for details os environ pipconfigfile os devnull def bootstrap rootnone upgradefalse userfalse altinstallfalse defaultpipfalse verbosity0 discard the return value bootstraprootroot upgradeupgrade useruser altinstallaltinstall defaultpipdefaultpip verbosityverbosity def bootstrap rootnone upgradefalse userfalse altinstallfalse defaultpipfalse verbosity0 if altinstall and defaultpip raise valueerrorcannot use altinstall and defaultpip together sys auditensurepip bootstrap root disablepipconfigurationsettings by default installing pip installs all of the following scripts x y running python version pip pipx pipx y pip 1 5 allows ensurepip to request that some of those be left out if altinstall omit pip pipx os environensurepipoptions altinstall elif not defaultpip omit pip os environensurepipoptions 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 additionalpaths for name package in getpackages items if package wheelname use bundled wheel package wheelname package wheelname wheelpath resources filesensurepip bundled wheelname whl wheelpath readbytes else use the wheel package directory with openpackage wheelpath rb as fp whl fp read wheelname os path basenamepackage wheelpath filename os path jointmpdir wheelname with openfilename wb as fp fp writewhl additionalpaths appendfilename construct the arguments to be passed to the pip command args install nocachedir noindex findlinks tmpdir if root args root root if upgrade args upgrade if user args user if verbosity args v verbosity return runpipargs packagenames additionalpaths def uninstallhelper verbosity0 nothing to do if pip was never installed or has been removed try import pip except importerror return if the installed pip version doesn t match the available one leave it alone availableversion version if pip version availableversion printfensurepip will only uninstall a matching version fpip version r installed favailableversion r available filesys stderr return disablepipconfigurationsettings construct the arguments to be passed to the pip command args uninstall y disablepipversioncheck if verbosity args v verbosity return runpipargs reversedpackagenames def mainargvnone import argparse parser argparse argumentparserprogpython m ensurepip parser addargument version actionversion versionpip formatversion helpshow the version of pip that is bundled with this python parser addargument v verbose actioncount default0 destverbosity helpgive more output option is additive and can be used up to 3 times parser addargument u upgrade actionstoretrue defaultfalse helpupgrade pip and dependencies even if already installed parser addargument user actionstoretrue defaultfalse helpinstall using the user scheme parser addargument root defaultnone helpinstall everything relative to this alternate root directory parser addargument altinstall actionstoretrue defaultfalse helpmake an alternate install installing only the x y versioned scripts default pipx pipx y parser addargument defaultpip actionstoretrue defaultfalse helpmake a default pip install installing the unqualified pip in addition to the versioned scripts args parser parseargsargv return bootstrap rootargs root upgradeargs upgrade userargs user verbosityargs verbosity altinstallargs altinstall defaultpipargs defaultpip packages bundled in ensurepip _bundled have wheel_name set packages from wheel_pkg_dir have wheel_path set directory of system wheel packages some linux distribution packaging policies recommend against bundling dependencies for example fedora installs wheel packages in the usr share python wheels directory and don t install the ensurepip _bundled package ignore path doesn t exist or permission error make the code deterministic if a directory contains multiple wheel files of the same package but don t attempt to implement correct version comparison since this case should not happen filename is like pip 21 2 4 py3 none any whl extract 21 2 4 from pip 21 2 4 py3 none any whl only used the wheel package directory if all packages are found there run the bootstrapping in a subprocess to avoid leaking any state that happens after pip has executed particularly this avoids the case when pip holds onto the files in additional_paths preventing us to remove them at the end of the invocation import runpy import sys sys path additional_paths or sys path sys argv 1 args runpy run_module pip run_name __main__ alter_sys true run code in isolated mode if currently running isolated returns a string specifying the bundled version of pip we deliberately ignore all pip environment variables when invoking pip see http bugs python org issue19734 for details we also ignore the settings in the default pip configuration file see http bugs python org issue20053 for details bootstrap pip into the current python installation or the given root directory note that calling this function will alter both sys path and os environ discard the return value bootstrap pip into the current python installation or the given root directory returns pip command status code note that calling this function will alter both sys path and os environ by default installing pip installs all of the following scripts x y running python version pip pipx pipx y pip 1 5 allows ensurepip to request that some of those be left out omit pip pipx omit pip put our bundled wheels into a temporary directory and construct the additional paths that need added to sys path use bundled wheel package use the wheel package directory construct the arguments to be passed to the pip command helper to support a clean default uninstall process on windows note that calling this function may alter os environ nothing to do if pip was never installed or has been removed if the installed pip version doesn t match the available one leave it alone construct the arguments to be passed to the pip command
import collections
import os
import os.path
import subprocess
import sys
import sysconfig
import tempfile
from importlib import resources


__all__ = ["version", "bootstrap"]
_PACKAGE_NAMES = ('pip',)
_PIP_VERSION = "23.2.1"
_PROJECTS = [
    ("pip", _PIP_VERSION, "py3"),
]



_Package = collections.namedtuple('Package',
                                  ('version', 'wheel_name', 'wheel_path'))





_WHEEL_PKG_DIR = sysconfig.get_config_var('WHEEL_PKG_DIR')


def _find_packages(path):
    packages = {}
    try:
        filenames = os.listdir(path)
    except OSError:
        
        filenames = ()
    
    
    
    filenames = sorted(filenames)
    for filename in filenames:
        
        if not filename.endswith(".whl"):
            continue
        for name in _PACKAGE_NAMES:
            prefix = name + '-'
            if filename.startswith(prefix):
                break
        else:
            continue

        
        version = filename.removeprefix(prefix).partition('-')[0]
        wheel_path = os.path.join(path, filename)
        packages[name] = _Package(version, None, wheel_path)
    return packages


def _get_packages():
    global _PACKAGES, _WHEEL_PKG_DIR
    if _PACKAGES is not None:
        return _PACKAGES

    packages = {}
    for name, version, py_tag in _PROJECTS:
        wheel_name = f"{name}-{version}-{py_tag}-none-any.whl"
        packages[name] = _Package(version, wheel_name, None)
    if _WHEEL_PKG_DIR:
        dir_packages = _find_packages(_WHEEL_PKG_DIR)
        
        if all(name in dir_packages for name in _PACKAGE_NAMES):
            packages = dir_packages
    _PACKAGES = packages
    return packages
_PACKAGES = None


def _run_pip(args, additional_paths=None):
    
    
    
    
    code = f

    cmd = [
        sys.executable,
        '-W',
        'ignore::DeprecationWarning',
        '-c',
        code,
    ]
    if sys.flags.isolated:
        
        cmd.insert(1, '-I')
    return subprocess.run(cmd, check=True).returncode


def version():
    
    return _get_packages()['pip'].version


def _disable_pip_configuration_settings():
    
    
    
    keys_to_remove = [k for k in os.environ if k.startswith("PIP_")]
    for k in keys_to_remove:
        del os.environ[k]
    
    
    os.environ['PIP_CONFIG_FILE'] = os.devnull


def bootstrap(*, root=None, upgrade=False, user=False,
              altinstall=False, default_pip=False,
              verbosity=0):
    
    
    _bootstrap(root=root, upgrade=upgrade, user=user,
               altinstall=altinstall, default_pip=default_pip,
               verbosity=verbosity)


def _bootstrap(*, root=None, upgrade=False, user=False,
              altinstall=False, default_pip=False,
              verbosity=0):
    
    if altinstall and default_pip:
        raise ValueError("Cannot use altinstall and default_pip together")

    sys.audit("ensurepip.bootstrap", root)

    _disable_pip_configuration_settings()

    
    
    
    
    
    
    if altinstall:
        
        os.environ["ENSUREPIP_OPTIONS"] = "altinstall"
    elif not default_pip:
        
        os.environ["ENSUREPIP_OPTIONS"] = "install"

    with tempfile.TemporaryDirectory() as tmpdir:
        
        
        additional_paths = []
        for name, package in _get_packages().items():
            if package.wheel_name:
                
                wheel_name = package.wheel_name
                wheel_path = resources.files("ensurepip") / "_bundled" / wheel_name
                whl = wheel_path.read_bytes()
            else:
                
                with open(package.wheel_path, "rb") as fp:
                    whl = fp.read()
                wheel_name = os.path.basename(package.wheel_path)

            filename = os.path.join(tmpdir, wheel_name)
            with open(filename, "wb") as fp:
                fp.write(whl)

            additional_paths.append(filename)

        
        args = ["install", "--no-cache-dir", "--no-index", "--find-links", tmpdir]
        if root:
            args += ["--root", root]
        if upgrade:
            args += ["--upgrade"]
        if user:
            args += ["--user"]
        if verbosity:
            args += ["-" + "v" * verbosity]

        return _run_pip([*args, *_PACKAGE_NAMES], additional_paths)

def _uninstall_helper(*, verbosity=0):
    
    
    try:
        import pip
    except ImportError:
        return

    
    
    available_version = version()
    if pip.__version__ != available_version:
        print(f"ensurepip will only uninstall a matching version "
              f"({pip.__version__!r} installed, "
              f"{available_version!r} available)",
              file=sys.stderr)
        return

    _disable_pip_configuration_settings()

    
    args = ["uninstall", "-y", "--disable-pip-version-check"]
    if verbosity:
        args += ["-" + "v" * verbosity]

    return _run_pip([*args, *reversed(_PACKAGE_NAMES)])


def _main(argv=None):
    import argparse
    parser = argparse.ArgumentParser(prog="python -m ensurepip")
    parser.add_argument(
        "--version",
        action="version",
        version="pip {}".format(version()),
        help="Show the version of pip that is bundled with this Python.",
    )
    parser.add_argument(
        "-v", "--verbose",
        action="count",
        default=0,
        dest="verbosity",
        help=("Give more output. Option is additive, and can be used up to 3 "
              "times."),
    )
    parser.add_argument(
        "-U", "--upgrade",
        action="store_true",
        default=False,
        help="Upgrade pip and dependencies, even if already installed.",
    )
    parser.add_argument(
        "--user",
        action="store_true",
        default=False,
        help="Install using the user scheme.",
    )
    parser.add_argument(
        "--root",
        default=None,
        help="Install everything relative to this alternate root directory.",
    )
    parser.add_argument(
        "--altinstall",
        action="store_true",
        default=False,
        help=("Make an alternate install, installing only the X.Y versioned "
              "scripts (Default: pipX, pipX.Y)."),
    )
    parser.add_argument(
        "--default-pip",
        action="store_true",
        default=False,
        help=("Make a default pip install, installing the unqualified pip "
              "in addition to the versioned scripts."),
    )

    args = parser.parse_args(argv)

    return _bootstrap(
        root=args.root,
        upgrade=args.upgrade,
        user=args.user,
        verbosity=args.verbosity,
        altinstall=args.altinstall,
        default_pip=args.default_pip,
    )