···11from enum import Enum
22-from typing import Any, Dict, Generic, Optional, Type, TypeVar, Union
22+from typing import Dict, Generic, Optional, Type, TypeVar, Union
3344import click
55from click import Context, Parameter
···3434 # This is to support when click is given a default that is a variant. If we have a value that is our variant,
3535 # we can just return it without trying to coerce.
3636 if isinstance(value, self.enum):
3737- return value
3838-3939- assert isinstance(value, str)
4040- try:
4141- return self.choice_map[_to_kebab_case(value)]
4242- except KeyError:
4343- self.fail('invalid choice: %s. (choose from %s)' % (value, ', '.join(self.choices)), param, ctx)
4444-4545- return None
4646-4747-4848-class EnumChoicePb2(click.Choice):
4949- """For use with `@click.option(...)` in order to support for choosing a single value of a protobuf enum.
5050-5151- Example usage:
5252- ```
5353- from some_pb2 import SomeEnum
5454-5555- @click.option('--choice', type=EnumChoicePb2(SomeEnum), default=SomeEnum.SOME_VALUE)
5656- def func(choice):
5757- click.echo(f"Your choice was: {choice}")
5858- ```
5959- """
6060-6161- choice_map: Dict[str, int]
6262- enum_class: Any
6363-6464- def __init__(self, enum_class: Any):
6565- self.enum_class = enum_class
6666- # Build choice map from enum descriptor
6767- self.choice_map = {}
6868-6969- # Get the enum descriptor and build choices from value names
7070- for value_descriptor in enum_class.DESCRIPTOR.values:
7171- kebab_name = _to_kebab_case(value_descriptor.name)
7272- self.choice_map[kebab_name] = value_descriptor.number
7373-7474- super().__init__(choices=list(self.choice_map.keys()))
7575-7676- def convert(self, value: Union[str, int], param: Optional[Parameter], ctx: Optional[Context]) -> Optional[int]:
7777- # If we already have an int (protobuf enum value), return it
7878- if isinstance(value, int):
7937 return value
80388139 assert isinstance(value, str)