Mercurial > repos > shellac > sam_consensus_v3
comparison env/lib/python3.9/site-packages/click/decorators.py @ 0:4f3585e2f14b draft default tip
"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author | shellac |
---|---|
date | Mon, 22 Mar 2021 18:12:50 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4f3585e2f14b |
---|---|
1 import inspect | |
2 import sys | |
3 from functools import update_wrapper | |
4 | |
5 from ._compat import iteritems | |
6 from ._unicodefun import _check_for_unicode_literals | |
7 from .core import Argument | |
8 from .core import Command | |
9 from .core import Group | |
10 from .core import Option | |
11 from .globals import get_current_context | |
12 from .utils import echo | |
13 | |
14 | |
15 def pass_context(f): | |
16 """Marks a callback as wanting to receive the current context | |
17 object as first argument. | |
18 """ | |
19 | |
20 def new_func(*args, **kwargs): | |
21 return f(get_current_context(), *args, **kwargs) | |
22 | |
23 return update_wrapper(new_func, f) | |
24 | |
25 | |
26 def pass_obj(f): | |
27 """Similar to :func:`pass_context`, but only pass the object on the | |
28 context onwards (:attr:`Context.obj`). This is useful if that object | |
29 represents the state of a nested system. | |
30 """ | |
31 | |
32 def new_func(*args, **kwargs): | |
33 return f(get_current_context().obj, *args, **kwargs) | |
34 | |
35 return update_wrapper(new_func, f) | |
36 | |
37 | |
38 def make_pass_decorator(object_type, ensure=False): | |
39 """Given an object type this creates a decorator that will work | |
40 similar to :func:`pass_obj` but instead of passing the object of the | |
41 current context, it will find the innermost context of type | |
42 :func:`object_type`. | |
43 | |
44 This generates a decorator that works roughly like this:: | |
45 | |
46 from functools import update_wrapper | |
47 | |
48 def decorator(f): | |
49 @pass_context | |
50 def new_func(ctx, *args, **kwargs): | |
51 obj = ctx.find_object(object_type) | |
52 return ctx.invoke(f, obj, *args, **kwargs) | |
53 return update_wrapper(new_func, f) | |
54 return decorator | |
55 | |
56 :param object_type: the type of the object to pass. | |
57 :param ensure: if set to `True`, a new object will be created and | |
58 remembered on the context if it's not there yet. | |
59 """ | |
60 | |
61 def decorator(f): | |
62 def new_func(*args, **kwargs): | |
63 ctx = get_current_context() | |
64 if ensure: | |
65 obj = ctx.ensure_object(object_type) | |
66 else: | |
67 obj = ctx.find_object(object_type) | |
68 if obj is None: | |
69 raise RuntimeError( | |
70 "Managed to invoke callback without a context" | |
71 " object of type '{}' existing".format(object_type.__name__) | |
72 ) | |
73 return ctx.invoke(f, obj, *args, **kwargs) | |
74 | |
75 return update_wrapper(new_func, f) | |
76 | |
77 return decorator | |
78 | |
79 | |
80 def _make_command(f, name, attrs, cls): | |
81 if isinstance(f, Command): | |
82 raise TypeError("Attempted to convert a callback into a command twice.") | |
83 try: | |
84 params = f.__click_params__ | |
85 params.reverse() | |
86 del f.__click_params__ | |
87 except AttributeError: | |
88 params = [] | |
89 help = attrs.get("help") | |
90 if help is None: | |
91 help = inspect.getdoc(f) | |
92 if isinstance(help, bytes): | |
93 help = help.decode("utf-8") | |
94 else: | |
95 help = inspect.cleandoc(help) | |
96 attrs["help"] = help | |
97 _check_for_unicode_literals() | |
98 return cls( | |
99 name=name or f.__name__.lower().replace("_", "-"), | |
100 callback=f, | |
101 params=params, | |
102 **attrs | |
103 ) | |
104 | |
105 | |
106 def command(name=None, cls=None, **attrs): | |
107 r"""Creates a new :class:`Command` and uses the decorated function as | |
108 callback. This will also automatically attach all decorated | |
109 :func:`option`\s and :func:`argument`\s as parameters to the command. | |
110 | |
111 The name of the command defaults to the name of the function with | |
112 underscores replaced by dashes. If you want to change that, you can | |
113 pass the intended name as the first argument. | |
114 | |
115 All keyword arguments are forwarded to the underlying command class. | |
116 | |
117 Once decorated the function turns into a :class:`Command` instance | |
118 that can be invoked as a command line utility or be attached to a | |
119 command :class:`Group`. | |
120 | |
121 :param name: the name of the command. This defaults to the function | |
122 name with underscores replaced by dashes. | |
123 :param cls: the command class to instantiate. This defaults to | |
124 :class:`Command`. | |
125 """ | |
126 if cls is None: | |
127 cls = Command | |
128 | |
129 def decorator(f): | |
130 cmd = _make_command(f, name, attrs, cls) | |
131 cmd.__doc__ = f.__doc__ | |
132 return cmd | |
133 | |
134 return decorator | |
135 | |
136 | |
137 def group(name=None, **attrs): | |
138 """Creates a new :class:`Group` with a function as callback. This | |
139 works otherwise the same as :func:`command` just that the `cls` | |
140 parameter is set to :class:`Group`. | |
141 """ | |
142 attrs.setdefault("cls", Group) | |
143 return command(name, **attrs) | |
144 | |
145 | |
146 def _param_memo(f, param): | |
147 if isinstance(f, Command): | |
148 f.params.append(param) | |
149 else: | |
150 if not hasattr(f, "__click_params__"): | |
151 f.__click_params__ = [] | |
152 f.__click_params__.append(param) | |
153 | |
154 | |
155 def argument(*param_decls, **attrs): | |
156 """Attaches an argument to the command. All positional arguments are | |
157 passed as parameter declarations to :class:`Argument`; all keyword | |
158 arguments are forwarded unchanged (except ``cls``). | |
159 This is equivalent to creating an :class:`Argument` instance manually | |
160 and attaching it to the :attr:`Command.params` list. | |
161 | |
162 :param cls: the argument class to instantiate. This defaults to | |
163 :class:`Argument`. | |
164 """ | |
165 | |
166 def decorator(f): | |
167 ArgumentClass = attrs.pop("cls", Argument) | |
168 _param_memo(f, ArgumentClass(param_decls, **attrs)) | |
169 return f | |
170 | |
171 return decorator | |
172 | |
173 | |
174 def option(*param_decls, **attrs): | |
175 """Attaches an option to the command. All positional arguments are | |
176 passed as parameter declarations to :class:`Option`; all keyword | |
177 arguments are forwarded unchanged (except ``cls``). | |
178 This is equivalent to creating an :class:`Option` instance manually | |
179 and attaching it to the :attr:`Command.params` list. | |
180 | |
181 :param cls: the option class to instantiate. This defaults to | |
182 :class:`Option`. | |
183 """ | |
184 | |
185 def decorator(f): | |
186 # Issue 926, copy attrs, so pre-defined options can re-use the same cls= | |
187 option_attrs = attrs.copy() | |
188 | |
189 if "help" in option_attrs: | |
190 option_attrs["help"] = inspect.cleandoc(option_attrs["help"]) | |
191 OptionClass = option_attrs.pop("cls", Option) | |
192 _param_memo(f, OptionClass(param_decls, **option_attrs)) | |
193 return f | |
194 | |
195 return decorator | |
196 | |
197 | |
198 def confirmation_option(*param_decls, **attrs): | |
199 """Shortcut for confirmation prompts that can be ignored by passing | |
200 ``--yes`` as parameter. | |
201 | |
202 This is equivalent to decorating a function with :func:`option` with | |
203 the following parameters:: | |
204 | |
205 def callback(ctx, param, value): | |
206 if not value: | |
207 ctx.abort() | |
208 | |
209 @click.command() | |
210 @click.option('--yes', is_flag=True, callback=callback, | |
211 expose_value=False, prompt='Do you want to continue?') | |
212 def dropdb(): | |
213 pass | |
214 """ | |
215 | |
216 def decorator(f): | |
217 def callback(ctx, param, value): | |
218 if not value: | |
219 ctx.abort() | |
220 | |
221 attrs.setdefault("is_flag", True) | |
222 attrs.setdefault("callback", callback) | |
223 attrs.setdefault("expose_value", False) | |
224 attrs.setdefault("prompt", "Do you want to continue?") | |
225 attrs.setdefault("help", "Confirm the action without prompting.") | |
226 return option(*(param_decls or ("--yes",)), **attrs)(f) | |
227 | |
228 return decorator | |
229 | |
230 | |
231 def password_option(*param_decls, **attrs): | |
232 """Shortcut for password prompts. | |
233 | |
234 This is equivalent to decorating a function with :func:`option` with | |
235 the following parameters:: | |
236 | |
237 @click.command() | |
238 @click.option('--password', prompt=True, confirmation_prompt=True, | |
239 hide_input=True) | |
240 def changeadmin(password): | |
241 pass | |
242 """ | |
243 | |
244 def decorator(f): | |
245 attrs.setdefault("prompt", True) | |
246 attrs.setdefault("confirmation_prompt", True) | |
247 attrs.setdefault("hide_input", True) | |
248 return option(*(param_decls or ("--password",)), **attrs)(f) | |
249 | |
250 return decorator | |
251 | |
252 | |
253 def version_option(version=None, *param_decls, **attrs): | |
254 """Adds a ``--version`` option which immediately ends the program | |
255 printing out the version number. This is implemented as an eager | |
256 option that prints the version and exits the program in the callback. | |
257 | |
258 :param version: the version number to show. If not provided Click | |
259 attempts an auto discovery via setuptools. | |
260 :param prog_name: the name of the program (defaults to autodetection) | |
261 :param message: custom message to show instead of the default | |
262 (``'%(prog)s, version %(version)s'``) | |
263 :param others: everything else is forwarded to :func:`option`. | |
264 """ | |
265 if version is None: | |
266 if hasattr(sys, "_getframe"): | |
267 module = sys._getframe(1).f_globals.get("__name__") | |
268 else: | |
269 module = "" | |
270 | |
271 def decorator(f): | |
272 prog_name = attrs.pop("prog_name", None) | |
273 message = attrs.pop("message", "%(prog)s, version %(version)s") | |
274 | |
275 def callback(ctx, param, value): | |
276 if not value or ctx.resilient_parsing: | |
277 return | |
278 prog = prog_name | |
279 if prog is None: | |
280 prog = ctx.find_root().info_name | |
281 ver = version | |
282 if ver is None: | |
283 try: | |
284 import pkg_resources | |
285 except ImportError: | |
286 pass | |
287 else: | |
288 for dist in pkg_resources.working_set: | |
289 scripts = dist.get_entry_map().get("console_scripts") or {} | |
290 for _, entry_point in iteritems(scripts): | |
291 if entry_point.module_name == module: | |
292 ver = dist.version | |
293 break | |
294 if ver is None: | |
295 raise RuntimeError("Could not determine version") | |
296 echo(message % {"prog": prog, "version": ver}, color=ctx.color) | |
297 ctx.exit() | |
298 | |
299 attrs.setdefault("is_flag", True) | |
300 attrs.setdefault("expose_value", False) | |
301 attrs.setdefault("is_eager", True) | |
302 attrs.setdefault("help", "Show the version and exit.") | |
303 attrs["callback"] = callback | |
304 return option(*(param_decls or ("--version",)), **attrs)(f) | |
305 | |
306 return decorator | |
307 | |
308 | |
309 def help_option(*param_decls, **attrs): | |
310 """Adds a ``--help`` option which immediately ends the program | |
311 printing out the help page. This is usually unnecessary to add as | |
312 this is added by default to all commands unless suppressed. | |
313 | |
314 Like :func:`version_option`, this is implemented as eager option that | |
315 prints in the callback and exits. | |
316 | |
317 All arguments are forwarded to :func:`option`. | |
318 """ | |
319 | |
320 def decorator(f): | |
321 def callback(ctx, param, value): | |
322 if value and not ctx.resilient_parsing: | |
323 echo(ctx.get_help(), color=ctx.color) | |
324 ctx.exit() | |
325 | |
326 attrs.setdefault("is_flag", True) | |
327 attrs.setdefault("expose_value", False) | |
328 attrs.setdefault("help", "Show this message and exit.") | |
329 attrs.setdefault("is_eager", True) | |
330 attrs["callback"] = callback | |
331 return option(*(param_decls or ("--help",)), **attrs)(f) | |
332 | |
333 return decorator |