Source code for shiv.pip

import contextlib
import os
import subprocess
import sys

from typing import Generator, List

import click

from .bootstrap import extend_python_path, get_first_sitedir_index
from .constants import PIP_INSTALL_ERROR, PIP_REQUIRE_VIRTUALENV


[docs]@contextlib.contextmanager def clean_pip_env() -> Generator[None, None, None]: """A context manager for temporarily removing 'PIP_REQUIRE_VIRTUALENV' from the environment. Since shiv installs via `--target`, we need to ignore venv requirements if they exist. """ require_venv = os.environ.pop(PIP_REQUIRE_VIRTUALENV, None) try: yield finally: if require_venv is not None: os.environ[PIP_REQUIRE_VIRTUALENV] = require_venv
[docs]def install(args: List[str]) -> None: """`pip install` as a function. Accepts a list of pip arguments. .. code-block:: py >>> install(['numpy', '--target', 'site-packages']) Collecting numpy Downloading numpy-1.13.3-cp35-cp35m-manylinux1_x86_64.whl (16.9MB) 100% || 16.9MB 53kB/s Installing collected packages: numpy Successfully installed numpy-1.13.3 """ with clean_pip_env(): # if being invoked as a pyz, we must ensure we have access to our own # site-packages when subprocessing since there is no guarantee that pip # will be available subprocess_env = os.environ.copy() sitedir_index = get_first_sitedir_index() extend_python_path(subprocess_env, sys.path[sitedir_index:]) process = subprocess.Popen( [sys.executable, "-m", "pip", "--disable-pip-version-check", "install", *args], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=subprocess_env, universal_newlines=True, ) for output in process.stdout: # type: ignore if output: click.echo(output.rstrip()) if process.wait() > 0: sys.exit(PIP_INSTALL_ERROR)