prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Use the builtin plugin classes unless another plugin class is specifically asked for.
  **What's the problem this feature will solve?**
  
  I have a private plugin for virtualenv where I add an additional discovery class. This discovery class adds a new argument to the command line parser that is required but only when the discovery class is chosen. However I'm seeing an issue where using virtualenv via the command line as normal is now asking for this argument. The reason seems to be that virtualenv is picking a default discovery class but in a non-deterministic way and sometimes the additional discovery class is chosen as the default discovery class and so the argument is required. The default class is chosen depending on which entry point is discovered first. I believe entry points give no guarantees about order of discovery.
  
  The order of entry points discovery seems to change in different installs of virtualenv and the plugin, rather than changing in the same environment between different invocations of virtualenv.
  
  I believe the problem will be the same for creators, seeders, and activators as well.
  
  **Describe the solution you'd like**
  
  I would expect the builtin discovery class to be chosen as the default discovery class unless explicitly set otherwise.
  
  **Alternative Solutions**
  
  These classes could have a priority set at the class level. The builtin classes would have a priority set such that a plugin class could opt to set it's priority lower or higher than the builtins. virtualenv would then order these classes by their priority. Classes would be allowed to have the same priority with the understanding that the order of classes with the same priority value would be non-deterministic.
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `src/virtualenv/run/plugin/discovery.py`
  Content:
  ```
  1 from __future__ import absolute_import, unicode_literals
  2 
  3 from .base import PluginLoader
  4 
  5 
  6 class Discovery(PluginLoader):
  7     """"""
  8 
  9 
  10 def get_discover(parser, args):
  11     discover_types = Discovery.entry_points_for("virtualenv.discovery")
  12     discovery_parser = parser.add_argument_group(
  13         title="discovery",
  14         description="discover and provide a target interpreter",
  15     )
  16     discovery_parser.add_argument(
  17         "--discovery",
  18         choices=_get_default_discovery(discover_types),
  19         default=next(i for i in discover_types.keys()),
  20         required=False,
  21         help="interpreter discovery method",
  22     )
  23     options, _ = parser.parse_known_args(args)
  24     discover_class = discover_types[options.discovery]
  25     discover_class.add_parser_arguments(discovery_parser)
  26     options, _ = parser.parse_known_args(args, namespace=options)
  27     discover = discover_class(options)
  28     return discover
  29 
  30 
  31 def _get_default_discovery(discover_types):
  32     return list(discover_types.keys())
  33
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/src/virtualenv/run/plugin/discovery.py b/src/virtualenv/run/plugin/discovery.py
  --- a/src/virtualenv/run/plugin/discovery.py
  +++ b/src/virtualenv/run/plugin/discovery.py
  @@ -13,10 +13,13 @@
           title="discovery",
           description="discover and provide a target interpreter",
       )
  +    choices = _get_default_discovery(discover_types)
  +    # prefer the builtin if present, otherwise fallback to first defined type
  +    choices = sorted(choices, key=lambda a: 0 if a == "builtin" else 1)
       discovery_parser.add_argument(
           "--discovery",
  -        choices=_get_default_discovery(discover_types),
  -        default=next(i for i in discover_types.keys()),
  +        choices=choices,
  +        default=next(iter(choices)),
           required=False,
           help="interpreter discovery method",
       )
  
verification_info: {"golden_diff": "diff --git a/src/virtualenv/run/plugin/discovery.py b/src/virtualenv/run/plugin/discovery.py\n--- a/src/virtualenv/run/plugin/discovery.py\n+++ b/src/virtualenv/run/plugin/discovery.py\n@@ -13,10 +13,13 @@\n         title=\"discovery\",\n         description=\"discover and provide a target interpreter\",\n     )\n+    choices = _get_default_discovery(discover_types)\n+    # prefer the builtin if present, otherwise fallback to first defined type\n+    choices = sorted(choices, key=lambda a: 0 if a == \"builtin\" else 1)\n     discovery_parser.add_argument(\n         \"--discovery\",\n-        choices=_get_default_discovery(discover_types),\n-        default=next(i for i in discover_types.keys()),\n+        choices=choices,\n+        default=next(iter(choices)),\n         required=False,\n         help=\"interpreter discovery method\",\n     )\n", "issue": "Use the builtin plugin classes unless another plugin class is specifically asked for.\n**What's the problem this feature will solve?**\r\n\r\nI have a private plugin for virtualenv where I add an additional discovery class. This discovery class adds a new argument to the command line parser that is required but only when the discovery class is chosen. However I'm seeing an issue where using virtualenv via the command line as normal is now asking for this argument. The reason seems to be that virtualenv is picking a default discovery class but in a non-deterministic way and sometimes the additional discovery class is chosen as the default discovery class and so the argument is required. The default class is chosen depending on which entry point is discovered first. I believe entry points give no guarantees about order of discovery.\r\n\r\nThe order of entry points discovery seems to change in different installs of virtualenv and the plugin, rather than changing in the same environment between different invocations of virtualenv.\r\n\r\nI believe the problem will be the same for creators, seeders, and activators as well.\r\n\r\n**Describe the solution you'd like**\r\n\r\nI would expect the builtin discovery class to be chosen as the default discovery class unless explicitly set otherwise.\r\n\r\n**Alternative Solutions**\r\n\r\nThese classes could have a priority set at the class level. The builtin classes would have a priority set such that a plugin class could opt to set it's priority lower or higher than the builtins. virtualenv would then order these classes by their priority. Classes would be allowed to have the same priority with the understanding that the order of classes with the same priority value would be non-deterministic.\r\n\n", "before_files": [{"content": "from __future__ import absolute_import, unicode_literals\n\nfrom .base import PluginLoader\n\n\nclass Discovery(PluginLoader):\n    \"\"\"\"\"\"\n\n\ndef get_discover(parser, args):\n    discover_types = Discovery.entry_points_for(\"virtualenv.discovery\")\n    discovery_parser = parser.add_argument_group(\n        title=\"discovery\",\n        description=\"discover and provide a target interpreter\",\n    )\n    discovery_parser.add_argument(\n        \"--discovery\",\n        choices=_get_default_discovery(discover_types),\n        default=next(i for i in discover_types.keys()),\n        required=False,\n        help=\"interpreter discovery method\",\n    )\n    options, _ = parser.parse_known_args(args)\n    discover_class = discover_types[options.discovery]\n    discover_class.add_parser_arguments(discovery_parser)\n    options, _ = parser.parse_known_args(args, namespace=options)\n    discover = discover_class(options)\n    return discover\n\n\ndef _get_default_discovery(discover_types):\n    return list(discover_types.keys())\n", "path": "src/virtualenv/run/plugin/discovery.py"}], "after_files": [{"content": "from __future__ import absolute_import, unicode_literals\n\nfrom .base import PluginLoader\n\n\nclass Discovery(PluginLoader):\n    \"\"\"\"\"\"\n\n\ndef get_discover(parser, args):\n    discover_types = Discovery.entry_points_for(\"virtualenv.discovery\")\n    discovery_parser = parser.add_argument_group(\n        title=\"discovery\",\n        description=\"discover and provide a target interpreter\",\n    )\n    choices = _get_default_discovery(discover_types)\n    # prefer the builtin if present, otherwise fallback to first defined type\n    choices = sorted(choices, key=lambda a: 0 if a == \"builtin\" else 1)\n    discovery_parser.add_argument(\n        \"--discovery\",\n        choices=choices,\n        default=next(iter(choices)),\n        required=False,\n        help=\"interpreter discovery method\",\n    )\n    options, _ = parser.parse_known_args(args)\n    discover_class = discover_types[options.discovery]\n    discover_class.add_parser_arguments(discovery_parser)\n    options, _ = parser.parse_known_args(args, namespace=options)\n    discover = discover_class(options)\n    return discover\n\n\ndef _get_default_discovery(discover_types):\n    return list(discover_types.keys())\n", "path": "src/virtualenv/run/plugin/discovery.py"}]}