__init__.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. """
  2. Package containing all pip commands
  3. """
  4. from __future__ import annotations
  5. import importlib
  6. from collections import namedtuple
  7. from typing import Any
  8. from pip._internal.cli.base_command import Command
  9. CommandInfo = namedtuple("CommandInfo", "module_path, class_name, summary")
  10. # This dictionary does a bunch of heavy lifting for help output:
  11. # - Enables avoiding additional (costly) imports for presenting `--help`.
  12. # - The ordering matters for help display.
  13. #
  14. # Even though the module path starts with the same "pip._internal.commands"
  15. # prefix, the full path makes testing easier (specifically when modifying
  16. # `commands_dict` in test setup / teardown).
  17. commands_dict: dict[str, CommandInfo] = {
  18. "install": CommandInfo(
  19. "pip._internal.commands.install",
  20. "InstallCommand",
  21. "Install packages.",
  22. ),
  23. "lock": CommandInfo(
  24. "pip._internal.commands.lock",
  25. "LockCommand",
  26. "Generate a lock file.",
  27. ),
  28. "download": CommandInfo(
  29. "pip._internal.commands.download",
  30. "DownloadCommand",
  31. "Download packages.",
  32. ),
  33. "uninstall": CommandInfo(
  34. "pip._internal.commands.uninstall",
  35. "UninstallCommand",
  36. "Uninstall packages.",
  37. ),
  38. "freeze": CommandInfo(
  39. "pip._internal.commands.freeze",
  40. "FreezeCommand",
  41. "Output installed packages in requirements format.",
  42. ),
  43. "inspect": CommandInfo(
  44. "pip._internal.commands.inspect",
  45. "InspectCommand",
  46. "Inspect the python environment.",
  47. ),
  48. "list": CommandInfo(
  49. "pip._internal.commands.list",
  50. "ListCommand",
  51. "List installed packages.",
  52. ),
  53. "show": CommandInfo(
  54. "pip._internal.commands.show",
  55. "ShowCommand",
  56. "Show information about installed packages.",
  57. ),
  58. "check": CommandInfo(
  59. "pip._internal.commands.check",
  60. "CheckCommand",
  61. "Verify installed packages have compatible dependencies.",
  62. ),
  63. "config": CommandInfo(
  64. "pip._internal.commands.configuration",
  65. "ConfigurationCommand",
  66. "Manage local and global configuration.",
  67. ),
  68. "search": CommandInfo(
  69. "pip._internal.commands.search",
  70. "SearchCommand",
  71. "Search PyPI for packages.",
  72. ),
  73. "cache": CommandInfo(
  74. "pip._internal.commands.cache",
  75. "CacheCommand",
  76. "Inspect and manage pip's wheel cache.",
  77. ),
  78. "index": CommandInfo(
  79. "pip._internal.commands.index",
  80. "IndexCommand",
  81. "Inspect information available from package indexes.",
  82. ),
  83. "wheel": CommandInfo(
  84. "pip._internal.commands.wheel",
  85. "WheelCommand",
  86. "Build wheels from your requirements.",
  87. ),
  88. "hash": CommandInfo(
  89. "pip._internal.commands.hash",
  90. "HashCommand",
  91. "Compute hashes of package archives.",
  92. ),
  93. "completion": CommandInfo(
  94. "pip._internal.commands.completion",
  95. "CompletionCommand",
  96. "A helper command used for command completion.",
  97. ),
  98. "debug": CommandInfo(
  99. "pip._internal.commands.debug",
  100. "DebugCommand",
  101. "Show information useful for debugging.",
  102. ),
  103. "help": CommandInfo(
  104. "pip._internal.commands.help",
  105. "HelpCommand",
  106. "Show help for commands.",
  107. ),
  108. }
  109. def create_command(name: str, **kwargs: Any) -> Command:
  110. """
  111. Create an instance of the Command class with the given name.
  112. """
  113. module_path, class_name, summary = commands_dict[name]
  114. module = importlib.import_module(module_path)
  115. command_class = getattr(module, class_name)
  116. command = command_class(name=name, summary=summary, **kwargs)
  117. return command
  118. def get_similar_commands(name: str) -> str | None:
  119. """Command name auto-correct."""
  120. from difflib import get_close_matches
  121. name = name.lower()
  122. close_commands = get_close_matches(name, commands_dict.keys())
  123. if close_commands:
  124. return close_commands[0]
  125. else:
  126. return None