__init__.py 2.9 KB

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