blob: 8568d3f8b6e50a3a9e2c152705468bbb8a18437f [file] [log] [blame]
from __future__ import absolute_import
import collections
import logging
from pip._internal.utils.logging import indent_log
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
from .req_file import parse_requirements
from .req_install import InstallRequirement
from .req_set import RequirementSet
if MYPY_CHECK_RUNNING:
from typing import Iterator, List, Optional, Sequence, Tuple
__all__ = [
"RequirementSet", "InstallRequirement",
"parse_requirements", "install_given_reqs",
]
logger = logging.getLogger(__name__)
class InstallationResult(object):
def __init__(self, name):
# type: (str) -> None
self.name = name
def __repr__(self):
# type: () -> str
return "InstallationResult(name={!r})".format(self.name)
def _validate_requirements(
requirements, # type: List[InstallRequirement]
):
# type: (...) -> Iterator[Tuple[str, InstallRequirement]]
for req in requirements:
assert req.name, "invalid to-be-installed requirement: {}".format(req)
yield req.name, req
def install_given_reqs(
requirements, # type: List[InstallRequirement]
install_options, # type: List[str]
global_options, # type: Sequence[str]
root, # type: Optional[str]
home, # type: Optional[str]
prefix, # type: Optional[str]
warn_script_location, # type: bool
use_user_site, # type: bool
pycompile, # type: bool
):
# type: (...) -> List[InstallationResult]
"""
Install everything in the given list.
(to be called after having downloaded and unpacked the packages)
"""
to_install = collections.OrderedDict(_validate_requirements(requirements))
if to_install:
logger.info(
'Installing collected packages: %s',
', '.join(to_install.keys()),
)
installed = []
with indent_log():
for req_name, requirement in to_install.items():
if requirement.should_reinstall:
logger.info('Attempting uninstall: %s', req_name)
with indent_log():
uninstalled_pathset = requirement.uninstall(
auto_confirm=True
)
else:
uninstalled_pathset = None
try:
requirement.install(
install_options,
global_options,
root=root,
home=home,
prefix=prefix,
warn_script_location=warn_script_location,
use_user_site=use_user_site,
pycompile=pycompile,
)
except Exception:
# if install did not succeed, rollback previous uninstall
if uninstalled_pathset and not requirement.install_succeeded:
uninstalled_pathset.rollback()
raise
else:
if uninstalled_pathset and requirement.install_succeeded:
uninstalled_pathset.commit()
installed.append(InstallationResult(req_name))
return installed