__init__.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import collections
  2. import logging
  3. from typing import Generator, List, Optional, Sequence, Tuple
  4. from pip._internal.utils.logging import indent_log
  5. from .req_file import parse_requirements
  6. from .req_install import InstallRequirement
  7. from .req_set import RequirementSet
  8. __all__ = [
  9. "RequirementSet",
  10. "InstallRequirement",
  11. "parse_requirements",
  12. "install_given_reqs",
  13. ]
  14. logger = logging.getLogger(__name__)
  15. class InstallationResult:
  16. def __init__(self, name: str) -> None:
  17. self.name = name
  18. def __repr__(self) -> str:
  19. return f"InstallationResult(name={self.name!r})"
  20. def _validate_requirements(
  21. requirements: List[InstallRequirement],
  22. ) -> Generator[Tuple[str, InstallRequirement], None, None]:
  23. for req in requirements:
  24. assert req.name, f"invalid to-be-installed requirement: {req}"
  25. yield req.name, req
  26. def install_given_reqs(
  27. requirements: List[InstallRequirement],
  28. global_options: Sequence[str],
  29. root: Optional[str],
  30. home: Optional[str],
  31. prefix: Optional[str],
  32. warn_script_location: bool,
  33. use_user_site: bool,
  34. pycompile: bool,
  35. ) -> List[InstallationResult]:
  36. """
  37. Install everything in the given list.
  38. (to be called after having downloaded and unpacked the packages)
  39. """
  40. to_install = collections.OrderedDict(_validate_requirements(requirements))
  41. if to_install:
  42. logger.info(
  43. "Installing collected packages: %s",
  44. ", ".join(to_install.keys()),
  45. )
  46. installed = []
  47. with indent_log():
  48. for req_name, requirement in to_install.items():
  49. if requirement.should_reinstall:
  50. logger.info("Attempting uninstall: %s", req_name)
  51. with indent_log():
  52. uninstalled_pathset = requirement.uninstall(auto_confirm=True)
  53. else:
  54. uninstalled_pathset = None
  55. try:
  56. requirement.install(
  57. global_options,
  58. root=root,
  59. home=home,
  60. prefix=prefix,
  61. warn_script_location=warn_script_location,
  62. use_user_site=use_user_site,
  63. pycompile=pycompile,
  64. )
  65. except Exception:
  66. # if install did not succeed, rollback previous uninstall
  67. if uninstalled_pathset and not requirement.install_succeeded:
  68. uninstalled_pathset.rollback()
  69. raise
  70. else:
  71. if uninstalled_pathset and requirement.install_succeeded:
  72. uninstalled_pathset.commit()
  73. installed.append(InstallationResult(req_name))
  74. return installed