discovery.py 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. from __future__ import annotations
  2. from typing import TYPE_CHECKING
  3. from .base import PluginLoader
  4. if TYPE_CHECKING:
  5. from virtualenv.config.cli.parser import VirtualEnvConfigParser
  6. from virtualenv.discovery.discover import Discover
  7. class Discovery(PluginLoader):
  8. """Discovery plugins."""
  9. def get_discover(parser: VirtualEnvConfigParser, args: list[str] | None) -> Discover:
  10. discover_types = Discovery.entry_points_for("virtualenv.discovery")
  11. discovery_parser = parser.add_argument_group(
  12. title="discovery",
  13. description="discover and provide a target interpreter",
  14. )
  15. choices = _get_default_discovery(discover_types)
  16. # prefer the builtin if present, otherwise fallback to first defined type
  17. choices = sorted(choices, key=lambda a: 0 if a == "builtin" else 1)
  18. try:
  19. default_discovery = next(iter(choices))
  20. except StopIteration as e:
  21. msg = "No discovery plugin found. Try reinstalling virtualenv to fix this issue."
  22. raise RuntimeError(msg) from e
  23. discovery_parser.add_argument(
  24. "--discovery",
  25. choices=choices,
  26. default=default_discovery,
  27. required=False,
  28. help="interpreter discovery method",
  29. )
  30. options, _ = parser.parse_known_args(args)
  31. discovery = options.discovery
  32. if discovery not in discover_types:
  33. available = ", ".join(sorted(discover_types))
  34. msg = (
  35. f"discovery {discovery!r} is not available. "
  36. f"Available discovery methods: {available}. "
  37. f"Is the plugin installed?"
  38. )
  39. raise RuntimeError(msg)
  40. discover_class = discover_types[discovery]
  41. discover_class.add_parser_arguments(discovery_parser) # ty: ignore[unresolved-attribute]
  42. options, _ = parser.parse_known_args(args, namespace=options)
  43. return discover_class(options)
  44. def _get_default_discovery(discover_types: dict[str, type]) -> list[str]:
  45. return list(discover_types.keys())
  46. __all__ = [
  47. "Discovery",
  48. "get_discover",
  49. ]