图片解析应用
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

80 lines
3.0 KiB

  1. from collections import defaultdict
  2. from logging import getLogger
  3. from typing import Any, DefaultDict
  4. from pip._vendor.resolvelib.reporters import BaseReporter
  5. from .base import Candidate, Requirement
  6. logger = getLogger(__name__)
  7. class PipReporter(BaseReporter):
  8. def __init__(self) -> None:
  9. self.reject_count_by_package: DefaultDict[str, int] = defaultdict(int)
  10. self._messages_at_reject_count = {
  11. 1: (
  12. "pip is looking at multiple versions of {package_name} to "
  13. "determine which version is compatible with other "
  14. "requirements. This could take a while."
  15. ),
  16. 8: (
  17. "pip is still looking at multiple versions of {package_name} to "
  18. "determine which version is compatible with other "
  19. "requirements. This could take a while."
  20. ),
  21. 13: (
  22. "This is taking longer than usual. You might need to provide "
  23. "the dependency resolver with stricter constraints to reduce "
  24. "runtime. See https://pip.pypa.io/warnings/backtracking for "
  25. "guidance. If you want to abort this run, press Ctrl + C."
  26. ),
  27. }
  28. def rejecting_candidate(self, criterion: Any, candidate: Candidate) -> None:
  29. self.reject_count_by_package[candidate.name] += 1
  30. count = self.reject_count_by_package[candidate.name]
  31. if count not in self._messages_at_reject_count:
  32. return
  33. message = self._messages_at_reject_count[count]
  34. logger.info("INFO: %s", message.format(package_name=candidate.name))
  35. msg = "Will try a different candidate, due to conflict:"
  36. for req_info in criterion.information:
  37. req, parent = req_info.requirement, req_info.parent
  38. # Inspired by Factory.get_installation_error
  39. msg += "\n "
  40. if parent:
  41. msg += f"{parent.name} {parent.version} depends on "
  42. else:
  43. msg += "The user requested "
  44. msg += req.format_for_error()
  45. logger.debug(msg)
  46. class PipDebuggingReporter(BaseReporter):
  47. """A reporter that does an info log for every event it sees."""
  48. def starting(self) -> None:
  49. logger.info("Reporter.starting()")
  50. def starting_round(self, index: int) -> None:
  51. logger.info("Reporter.starting_round(%r)", index)
  52. def ending_round(self, index: int, state: Any) -> None:
  53. logger.info("Reporter.ending_round(%r, state)", index)
  54. def ending(self, state: Any) -> None:
  55. logger.info("Reporter.ending(%r)", state)
  56. def adding_requirement(self, requirement: Requirement, parent: Candidate) -> None:
  57. logger.info("Reporter.adding_requirement(%r, %r)", requirement, parent)
  58. def rejecting_candidate(self, criterion: Any, candidate: Candidate) -> None:
  59. logger.info("Reporter.rejecting_candidate(%r, %r)", criterion, candidate)
  60. def pinning(self, candidate: Candidate) -> None:
  61. logger.info("Reporter.pinning(%r)", candidate)