|
10 | 10 | from typing import TYPE_CHECKING |
11 | 11 | from typing import Any |
12 | 12 | from typing import ClassVar |
13 | | -from typing import TypeVar |
14 | 13 |
|
15 | 14 | import click |
16 | 15 | from click import Choice |
|
29 | 28 | from _pytask.console import create_panel_title |
30 | 29 |
|
31 | 30 | if TYPE_CHECKING: |
32 | | - from collections.abc import Iterable |
33 | 31 | from collections.abc import Sequence |
34 | 32 |
|
35 | 33 |
|
|
38 | 36 |
|
39 | 37 | if importlib.metadata.version("click") < "8.2": |
40 | 38 | from click.parser import split_opt |
| 39 | +else: |
| 40 | + from click.parser import ( # type: ignore[attr-defined, no-redef, unused-ignore] |
| 41 | + _split_opt as split_opt, |
| 42 | + ) |
41 | 43 |
|
42 | | - class EnumChoice(Choice): # type: ignore[type-arg, unused-ignore] |
43 | | - """An enum-based choice type. |
44 | | -
|
45 | | - The implementation is copied from https://github.com/pallets/click/pull/2210 and |
46 | | - related discussion can be found in https://github.com/pallets/click/issues/605. |
47 | 44 |
|
48 | | - In contrast to using :class:`click.Choice`, using this type ensures that the |
49 | | - error message does not show the enum members. |
| 45 | +class EnumChoice(Choice): # type: ignore[type-arg, unused-ignore] |
| 46 | + """An enum-based choice type. |
50 | 47 |
|
51 | | - In contrast to the proposed implementation in the PR, this implementation does |
52 | | - not use the members than rather the values of the enum. |
| 48 | + The implementation is copied from https://github.com/pallets/click/pull/2210 and |
| 49 | + related discussion can be found in https://github.com/pallets/click/issues/605. |
53 | 50 |
|
54 | | - """ |
| 51 | + In contrast to using :class:`click.Choice`, using this type ensures that the |
| 52 | + error message does not show the enum members. |
55 | 53 |
|
56 | | - def __init__(self, enum_type: type[Enum], case_sensitive: bool = True) -> None: |
57 | | - super().__init__( |
58 | | - choices=[element.value for element in enum_type], |
59 | | - case_sensitive=case_sensitive, |
60 | | - ) |
61 | | - self.enum_type = enum_type |
62 | | - |
63 | | - def convert( |
64 | | - self, value: Any, param: Parameter | None, ctx: Context | None |
65 | | - ) -> Any: |
66 | | - if isinstance(value, Enum): |
67 | | - value = value.value |
68 | | - value = super().convert(value=value, param=param, ctx=ctx) |
69 | | - if value is None: |
70 | | - return None |
71 | | - return self.enum_type(value) |
| 54 | + In contrast to the proposed implementation in the PR, this implementation does |
| 55 | + not use the members than rather the values of the enum. |
72 | 56 |
|
73 | | -else: |
74 | | - from click.parser import ( # type: ignore[attr-defined, no-redef, unused-ignore] |
75 | | - _split_opt as split_opt, |
76 | | - ) |
77 | | - |
78 | | - ParamTypeValue = TypeVar("ParamTypeValue") |
| 57 | + """ |
79 | 58 |
|
80 | | - class EnumChoice(Choice): # type: ignore[no-redef, type-arg, unused-ignore] |
81 | | - def __init__( |
82 | | - self, choices: Iterable[ParamTypeValue], case_sensitive: bool = False |
83 | | - ) -> None: |
84 | | - super().__init__(choices=choices, case_sensitive=case_sensitive) # type: ignore[arg-type, unused-ignore] |
| 59 | + def __init__(self, enum_type: type[Enum], case_sensitive: bool = True) -> None: |
| 60 | + super().__init__( |
| 61 | + choices=[element.value for element in enum_type], |
| 62 | + case_sensitive=case_sensitive, |
| 63 | + ) |
| 64 | + self.enum_type = enum_type |
| 65 | + |
| 66 | + def convert(self, value: Any, param: Parameter | None, ctx: Context | None) -> Any: |
| 67 | + if isinstance(value, Enum): |
| 68 | + value = value.value |
| 69 | + value = super().convert(value=value, param=param, ctx=ctx) |
| 70 | + if value is None: |
| 71 | + return None |
| 72 | + return self.enum_type(value) |
85 | 73 |
|
86 | 74 |
|
87 | 75 | class _OptionHighlighter(RegexHighlighter): |
|
0 commit comments