1
1
# -*- coding: utf-8 -*-
2
2
3
- from typing import Optional , List , Tuple , Dict , Set
4
-
5
3
import collections
6
- import weakref
7
4
import inspect
5
+ import weakref
6
+ from collections .abc import Callable
7
+ from typing import (
8
+ Any ,
9
+ Dict ,
10
+ List ,
11
+ Mapping ,
12
+ Optional ,
13
+ Sequence ,
14
+ Set ,
15
+ Tuple ,
16
+ Union ,
17
+ )
8
18
9
19
import click
10
20
from click .core import augment_usage_errors
16
26
resolve_wrappers
17
27
)
18
28
29
+ FC = Union [Callable , click .Command ]
30
+
19
31
20
32
class GroupedOption (click .Option ):
21
33
"""Represents grouped (related) optional values
@@ -27,7 +39,7 @@ class GroupedOption(click.Option):
27
39
:param attrs: additional option attributes
28
40
"""
29
41
30
- def __init__ (self , param_decls = None , * , group : 'OptionGroup' , ** attrs ):
42
+ def __init__ (self , param_decls : Optional [ Sequence [ str ]] = None , * , group : 'OptionGroup' , ** attrs : Any ):
31
43
super ().__init__ (param_decls , ** attrs )
32
44
33
45
for attr in group .forbidden_option_attrs :
@@ -45,13 +57,15 @@ def group(self) -> 'OptionGroup':
45
57
"""
46
58
return self .__group
47
59
48
- def handle_parse_result (self , ctx , opts , args ):
60
+ def handle_parse_result (
61
+ self , ctx : click .Context , opts : Mapping [str , Any ], args : List [str ]
62
+ ) -> Tuple [Any , List [str ]]:
49
63
with augment_usage_errors (ctx , param = self ):
50
64
if not ctx .resilient_parsing :
51
65
self .group .handle_parse_result (self , ctx , opts )
52
66
return super ().handle_parse_result (ctx , opts , args )
53
67
54
- def get_help_record (self , ctx : click .Context ):
68
+ def get_help_record (self , ctx : click .Context ) -> Optional [ Tuple [ str , str ]] :
55
69
help_record = super ().get_help_record (ctx )
56
70
if help_record is None :
57
71
# this happens if the option is hidden
@@ -69,7 +83,9 @@ class _GroupTitleFakeOption(click.Option):
69
83
"""The helper `Option` class to display option group title in help
70
84
"""
71
85
72
- def __init__ (self , param_decls = None , * , group : 'OptionGroup' , ** attrs ):
86
+ def __init__ (
87
+ self , param_decls : Optional [Sequence [str ]] = None , * , group : 'OptionGroup' , ** attrs : Any
88
+ ) -> None :
73
89
self .__group = group
74
90
super ().__init__ (param_decls , hidden = True , expose_value = False , help = group .help , ** attrs )
75
91
@@ -78,7 +94,7 @@ def __init__(self, param_decls=None, *, group: 'OptionGroup', **attrs):
78
94
self .opts = []
79
95
self .secondary_opts = []
80
96
81
- def get_help_record (self , ctx : click .Context ):
97
+ def get_help_record (self , ctx : click .Context ) -> Optional [ Tuple [ str , str ]] :
82
98
return self .__group .get_help_record (ctx )
83
99
84
100
@@ -92,13 +108,14 @@ class OptionGroup:
92
108
:param help: the group help text or None
93
109
"""
94
110
95
- def __init__ (self , name : Optional [str ] = None , * ,
96
- hidden = False , help : Optional [str ] = None ) -> None : # noqa
111
+ def __init__ (
112
+ self , name : Optional [str ] = None , * , hidden : bool = False , help : Optional [str ] = None
113
+ ) -> None :
97
114
self ._name = name if name else ''
98
115
self ._help = inspect .cleandoc (help if help else '' )
99
116
self ._hidden = hidden
100
117
101
- self ._options = collections .defaultdict (weakref .WeakValueDictionary )
118
+ self ._options : Mapping [ Any , Any ] = collections .defaultdict (weakref .WeakValueDictionary )
102
119
self ._group_title_options = weakref .WeakValueDictionary ()
103
120
104
121
@property
@@ -155,13 +172,13 @@ def get_help_record(self, ctx: click.Context) -> Optional[Tuple[str, str]]:
155
172
156
173
return name , help_
157
174
158
- def option (self , * param_decls , ** attrs ) :
175
+ def option (self , * param_decls : str , ** attrs : Any ) -> Callable :
159
176
"""Decorator attaches an grouped option to the command
160
177
161
178
The decorator is used for adding options to the group and to the Click-command
162
179
"""
163
180
164
- def decorator (func ) :
181
+ def decorator (func : FC ) -> FC :
165
182
option_attrs = attrs .copy ()
166
183
option_attrs .setdefault ('cls' , GroupedOption )
167
184
if self ._hidden :
@@ -191,7 +208,7 @@ def get_option_names(self, ctx: click.Context) -> List[str]:
191
208
"""
192
209
return list (reversed (list (self .get_options (ctx ))))
193
210
194
- def get_error_hint (self , ctx , option_names : Optional [Set [str ]] = None ) -> str :
211
+ def get_error_hint (self , ctx : click . Context , option_names : Optional [Set [str ]] = None ) -> str :
195
212
options = self .get_options (ctx )
196
213
text = ''
197
214
@@ -205,11 +222,11 @@ def get_error_hint(self, ctx, option_names: Optional[Set[str]] = None) -> str:
205
222
206
223
return text
207
224
208
- def handle_parse_result (self , option : GroupedOption , ctx : click .Context , opts : dict ) -> None :
225
+ def handle_parse_result (self , option : GroupedOption , ctx : click .Context , opts : Mapping [ str , Any ] ) -> None :
209
226
"""The method should be used for adding specific behavior and relation for options in the group
210
227
"""
211
228
212
- def _check_mixing_decorators (self , func ) :
229
+ def _check_mixing_decorators (self , func : Callable ) -> None :
213
230
func , params = get_callback_and_params (func )
214
231
215
232
if not params or func not in self ._options :
@@ -222,7 +239,7 @@ def _check_mixing_decorators(self, func):
222
239
if last_param .name != title_option .name and last_param .name not in options :
223
240
raise_mixing_decorators_error (last_param , func )
224
241
225
- def _add_title_fake_option (self , func ) :
242
+ def _add_title_fake_option (self , func : FC ) -> None :
226
243
callback , params = get_callback_and_params (func )
227
244
228
245
if callback not in self ._group_title_options :
@@ -240,7 +257,7 @@ def _add_title_fake_option(self, func):
240
257
title_index = params .index (title_option )
241
258
params [- 1 ], params [title_index ] = params [title_index ], params [- 1 ]
242
259
243
- def _option_memo (self , func ) :
260
+ def _option_memo (self , func : Callable ) -> None :
244
261
func , params = get_callback_and_params (func )
245
262
option = params [- 1 ]
246
263
self ._options [func ][option .name ] = option
@@ -263,7 +280,7 @@ def forbidden_option_attrs(self) -> List[str]:
263
280
def name_extra (self ) -> List [str ]:
264
281
return super ().name_extra + ['required_any' ]
265
282
266
- def handle_parse_result (self , option : GroupedOption , ctx : click .Context , opts : dict ) -> None :
283
+ def handle_parse_result (self , option : GroupedOption , ctx : click .Context , opts : Mapping [ str , Any ] ) -> None :
267
284
if option .name in opts :
268
285
return
269
286
@@ -301,7 +318,7 @@ def forbidden_option_attrs(self) -> List[str]:
301
318
def name_extra (self ) -> List [str ]:
302
319
return super ().name_extra + ['required_all' ]
303
320
304
- def handle_parse_result (self , option : GroupedOption , ctx : click .Context , opts : dict ) -> None :
321
+ def handle_parse_result (self , option : GroupedOption , ctx : click .Context , opts : Mapping [ str , Any ] ) -> None :
305
322
option_names = set (self .get_options (ctx ))
306
323
307
324
if not option_names .issubset (opts ):
@@ -330,7 +347,7 @@ def forbidden_option_attrs(self) -> List[str]:
330
347
def name_extra (self ) -> List [str ]:
331
348
return super ().name_extra + ['mutually_exclusive' ]
332
349
333
- def handle_parse_result (self , option : GroupedOption , ctx : click .Context , opts : dict ) -> None :
350
+ def handle_parse_result (self , option : GroupedOption , ctx : click .Context , opts : Mapping [ str , Any ] ) -> None :
334
351
option_names = set (self .get_options (ctx ))
335
352
given_option_names = option_names .intersection (opts )
336
353
given_option_count = len (given_option_names )
@@ -357,7 +374,7 @@ class RequiredMutuallyExclusiveOptionGroup(MutuallyExclusiveOptionGroup):
357
374
def name_extra (self ) -> List [str ]:
358
375
return super ().name_extra + ['required' ]
359
376
360
- def handle_parse_result (self , option : GroupedOption , ctx : click .Context , opts : dict ) -> None :
377
+ def handle_parse_result (self , option : GroupedOption , ctx : click .Context , opts : Mapping [ str , Any ] ) -> None :
361
378
super ().handle_parse_result (option , ctx , opts )
362
379
363
380
option_names = set (self .get_option_names (ctx ))
@@ -389,7 +406,7 @@ def forbidden_option_attrs(self) -> List[str]:
389
406
def name_extra (self ) -> List [str ]:
390
407
return super ().name_extra + ['all_or_none' ]
391
408
392
- def handle_parse_result (self , option : GroupedOption , ctx : click .Context , opts : dict ) -> None :
409
+ def handle_parse_result (self , option : GroupedOption , ctx : click .Context , opts : Mapping [ str , Any ] ) -> None :
393
410
option_names = set (self .get_options (ctx ))
394
411
395
412
if not option_names .isdisjoint (opts ) and option_names .intersection (opts ) != option_names :
0 commit comments