Mercurial > repos > shellac > sam_consensus_v3
comparison env/lib/python3.9/site-packages/click/types.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 os | |
2 import stat | |
3 from datetime import datetime | |
4 | |
5 from ._compat import _get_argv_encoding | |
6 from ._compat import filename_to_ui | |
7 from ._compat import get_filesystem_encoding | |
8 from ._compat import get_streerror | |
9 from ._compat import open_stream | |
10 from ._compat import PY2 | |
11 from ._compat import text_type | |
12 from .exceptions import BadParameter | |
13 from .utils import LazyFile | |
14 from .utils import safecall | |
15 | |
16 | |
17 class ParamType(object): | |
18 """Helper for converting values through types. The following is | |
19 necessary for a valid type: | |
20 | |
21 * it needs a name | |
22 * it needs to pass through None unchanged | |
23 * it needs to convert from a string | |
24 * it needs to convert its result type through unchanged | |
25 (eg: needs to be idempotent) | |
26 * it needs to be able to deal with param and context being `None`. | |
27 This can be the case when the object is used with prompt | |
28 inputs. | |
29 """ | |
30 | |
31 is_composite = False | |
32 | |
33 #: the descriptive name of this type | |
34 name = None | |
35 | |
36 #: if a list of this type is expected and the value is pulled from a | |
37 #: string environment variable, this is what splits it up. `None` | |
38 #: means any whitespace. For all parameters the general rule is that | |
39 #: whitespace splits them up. The exception are paths and files which | |
40 #: are split by ``os.path.pathsep`` by default (":" on Unix and ";" on | |
41 #: Windows). | |
42 envvar_list_splitter = None | |
43 | |
44 def __call__(self, value, param=None, ctx=None): | |
45 if value is not None: | |
46 return self.convert(value, param, ctx) | |
47 | |
48 def get_metavar(self, param): | |
49 """Returns the metavar default for this param if it provides one.""" | |
50 | |
51 def get_missing_message(self, param): | |
52 """Optionally might return extra information about a missing | |
53 parameter. | |
54 | |
55 .. versionadded:: 2.0 | |
56 """ | |
57 | |
58 def convert(self, value, param, ctx): | |
59 """Converts the value. This is not invoked for values that are | |
60 `None` (the missing value). | |
61 """ | |
62 return value | |
63 | |
64 def split_envvar_value(self, rv): | |
65 """Given a value from an environment variable this splits it up | |
66 into small chunks depending on the defined envvar list splitter. | |
67 | |
68 If the splitter is set to `None`, which means that whitespace splits, | |
69 then leading and trailing whitespace is ignored. Otherwise, leading | |
70 and trailing splitters usually lead to empty items being included. | |
71 """ | |
72 return (rv or "").split(self.envvar_list_splitter) | |
73 | |
74 def fail(self, message, param=None, ctx=None): | |
75 """Helper method to fail with an invalid value message.""" | |
76 raise BadParameter(message, ctx=ctx, param=param) | |
77 | |
78 | |
79 class CompositeParamType(ParamType): | |
80 is_composite = True | |
81 | |
82 @property | |
83 def arity(self): | |
84 raise NotImplementedError() | |
85 | |
86 | |
87 class FuncParamType(ParamType): | |
88 def __init__(self, func): | |
89 self.name = func.__name__ | |
90 self.func = func | |
91 | |
92 def convert(self, value, param, ctx): | |
93 try: | |
94 return self.func(value) | |
95 except ValueError: | |
96 try: | |
97 value = text_type(value) | |
98 except UnicodeError: | |
99 value = str(value).decode("utf-8", "replace") | |
100 self.fail(value, param, ctx) | |
101 | |
102 | |
103 class UnprocessedParamType(ParamType): | |
104 name = "text" | |
105 | |
106 def convert(self, value, param, ctx): | |
107 return value | |
108 | |
109 def __repr__(self): | |
110 return "UNPROCESSED" | |
111 | |
112 | |
113 class StringParamType(ParamType): | |
114 name = "text" | |
115 | |
116 def convert(self, value, param, ctx): | |
117 if isinstance(value, bytes): | |
118 enc = _get_argv_encoding() | |
119 try: | |
120 value = value.decode(enc) | |
121 except UnicodeError: | |
122 fs_enc = get_filesystem_encoding() | |
123 if fs_enc != enc: | |
124 try: | |
125 value = value.decode(fs_enc) | |
126 except UnicodeError: | |
127 value = value.decode("utf-8", "replace") | |
128 else: | |
129 value = value.decode("utf-8", "replace") | |
130 return value | |
131 return value | |
132 | |
133 def __repr__(self): | |
134 return "STRING" | |
135 | |
136 | |
137 class Choice(ParamType): | |
138 """The choice type allows a value to be checked against a fixed set | |
139 of supported values. All of these values have to be strings. | |
140 | |
141 You should only pass a list or tuple of choices. Other iterables | |
142 (like generators) may lead to surprising results. | |
143 | |
144 The resulting value will always be one of the originally passed choices | |
145 regardless of ``case_sensitive`` or any ``ctx.token_normalize_func`` | |
146 being specified. | |
147 | |
148 See :ref:`choice-opts` for an example. | |
149 | |
150 :param case_sensitive: Set to false to make choices case | |
151 insensitive. Defaults to true. | |
152 """ | |
153 | |
154 name = "choice" | |
155 | |
156 def __init__(self, choices, case_sensitive=True): | |
157 self.choices = choices | |
158 self.case_sensitive = case_sensitive | |
159 | |
160 def get_metavar(self, param): | |
161 return "[{}]".format("|".join(self.choices)) | |
162 | |
163 def get_missing_message(self, param): | |
164 return "Choose from:\n\t{}.".format(",\n\t".join(self.choices)) | |
165 | |
166 def convert(self, value, param, ctx): | |
167 # Match through normalization and case sensitivity | |
168 # first do token_normalize_func, then lowercase | |
169 # preserve original `value` to produce an accurate message in | |
170 # `self.fail` | |
171 normed_value = value | |
172 normed_choices = {choice: choice for choice in self.choices} | |
173 | |
174 if ctx is not None and ctx.token_normalize_func is not None: | |
175 normed_value = ctx.token_normalize_func(value) | |
176 normed_choices = { | |
177 ctx.token_normalize_func(normed_choice): original | |
178 for normed_choice, original in normed_choices.items() | |
179 } | |
180 | |
181 if not self.case_sensitive: | |
182 if PY2: | |
183 lower = str.lower | |
184 else: | |
185 lower = str.casefold | |
186 | |
187 normed_value = lower(normed_value) | |
188 normed_choices = { | |
189 lower(normed_choice): original | |
190 for normed_choice, original in normed_choices.items() | |
191 } | |
192 | |
193 if normed_value in normed_choices: | |
194 return normed_choices[normed_value] | |
195 | |
196 self.fail( | |
197 "invalid choice: {}. (choose from {})".format( | |
198 value, ", ".join(self.choices) | |
199 ), | |
200 param, | |
201 ctx, | |
202 ) | |
203 | |
204 def __repr__(self): | |
205 return "Choice('{}')".format(list(self.choices)) | |
206 | |
207 | |
208 class DateTime(ParamType): | |
209 """The DateTime type converts date strings into `datetime` objects. | |
210 | |
211 The format strings which are checked are configurable, but default to some | |
212 common (non-timezone aware) ISO 8601 formats. | |
213 | |
214 When specifying *DateTime* formats, you should only pass a list or a tuple. | |
215 Other iterables, like generators, may lead to surprising results. | |
216 | |
217 The format strings are processed using ``datetime.strptime``, and this | |
218 consequently defines the format strings which are allowed. | |
219 | |
220 Parsing is tried using each format, in order, and the first format which | |
221 parses successfully is used. | |
222 | |
223 :param formats: A list or tuple of date format strings, in the order in | |
224 which they should be tried. Defaults to | |
225 ``'%Y-%m-%d'``, ``'%Y-%m-%dT%H:%M:%S'``, | |
226 ``'%Y-%m-%d %H:%M:%S'``. | |
227 """ | |
228 | |
229 name = "datetime" | |
230 | |
231 def __init__(self, formats=None): | |
232 self.formats = formats or ["%Y-%m-%d", "%Y-%m-%dT%H:%M:%S", "%Y-%m-%d %H:%M:%S"] | |
233 | |
234 def get_metavar(self, param): | |
235 return "[{}]".format("|".join(self.formats)) | |
236 | |
237 def _try_to_convert_date(self, value, format): | |
238 try: | |
239 return datetime.strptime(value, format) | |
240 except ValueError: | |
241 return None | |
242 | |
243 def convert(self, value, param, ctx): | |
244 # Exact match | |
245 for format in self.formats: | |
246 dtime = self._try_to_convert_date(value, format) | |
247 if dtime: | |
248 return dtime | |
249 | |
250 self.fail( | |
251 "invalid datetime format: {}. (choose from {})".format( | |
252 value, ", ".join(self.formats) | |
253 ) | |
254 ) | |
255 | |
256 def __repr__(self): | |
257 return "DateTime" | |
258 | |
259 | |
260 class IntParamType(ParamType): | |
261 name = "integer" | |
262 | |
263 def convert(self, value, param, ctx): | |
264 try: | |
265 return int(value) | |
266 except ValueError: | |
267 self.fail("{} is not a valid integer".format(value), param, ctx) | |
268 | |
269 def __repr__(self): | |
270 return "INT" | |
271 | |
272 | |
273 class IntRange(IntParamType): | |
274 """A parameter that works similar to :data:`click.INT` but restricts | |
275 the value to fit into a range. The default behavior is to fail if the | |
276 value falls outside the range, but it can also be silently clamped | |
277 between the two edges. | |
278 | |
279 See :ref:`ranges` for an example. | |
280 """ | |
281 | |
282 name = "integer range" | |
283 | |
284 def __init__(self, min=None, max=None, clamp=False): | |
285 self.min = min | |
286 self.max = max | |
287 self.clamp = clamp | |
288 | |
289 def convert(self, value, param, ctx): | |
290 rv = IntParamType.convert(self, value, param, ctx) | |
291 if self.clamp: | |
292 if self.min is not None and rv < self.min: | |
293 return self.min | |
294 if self.max is not None and rv > self.max: | |
295 return self.max | |
296 if ( | |
297 self.min is not None | |
298 and rv < self.min | |
299 or self.max is not None | |
300 and rv > self.max | |
301 ): | |
302 if self.min is None: | |
303 self.fail( | |
304 "{} is bigger than the maximum valid value {}.".format( | |
305 rv, self.max | |
306 ), | |
307 param, | |
308 ctx, | |
309 ) | |
310 elif self.max is None: | |
311 self.fail( | |
312 "{} is smaller than the minimum valid value {}.".format( | |
313 rv, self.min | |
314 ), | |
315 param, | |
316 ctx, | |
317 ) | |
318 else: | |
319 self.fail( | |
320 "{} is not in the valid range of {} to {}.".format( | |
321 rv, self.min, self.max | |
322 ), | |
323 param, | |
324 ctx, | |
325 ) | |
326 return rv | |
327 | |
328 def __repr__(self): | |
329 return "IntRange({}, {})".format(self.min, self.max) | |
330 | |
331 | |
332 class FloatParamType(ParamType): | |
333 name = "float" | |
334 | |
335 def convert(self, value, param, ctx): | |
336 try: | |
337 return float(value) | |
338 except ValueError: | |
339 self.fail( | |
340 "{} is not a valid floating point value".format(value), param, ctx | |
341 ) | |
342 | |
343 def __repr__(self): | |
344 return "FLOAT" | |
345 | |
346 | |
347 class FloatRange(FloatParamType): | |
348 """A parameter that works similar to :data:`click.FLOAT` but restricts | |
349 the value to fit into a range. The default behavior is to fail if the | |
350 value falls outside the range, but it can also be silently clamped | |
351 between the two edges. | |
352 | |
353 See :ref:`ranges` for an example. | |
354 """ | |
355 | |
356 name = "float range" | |
357 | |
358 def __init__(self, min=None, max=None, clamp=False): | |
359 self.min = min | |
360 self.max = max | |
361 self.clamp = clamp | |
362 | |
363 def convert(self, value, param, ctx): | |
364 rv = FloatParamType.convert(self, value, param, ctx) | |
365 if self.clamp: | |
366 if self.min is not None and rv < self.min: | |
367 return self.min | |
368 if self.max is not None and rv > self.max: | |
369 return self.max | |
370 if ( | |
371 self.min is not None | |
372 and rv < self.min | |
373 or self.max is not None | |
374 and rv > self.max | |
375 ): | |
376 if self.min is None: | |
377 self.fail( | |
378 "{} is bigger than the maximum valid value {}.".format( | |
379 rv, self.max | |
380 ), | |
381 param, | |
382 ctx, | |
383 ) | |
384 elif self.max is None: | |
385 self.fail( | |
386 "{} is smaller than the minimum valid value {}.".format( | |
387 rv, self.min | |
388 ), | |
389 param, | |
390 ctx, | |
391 ) | |
392 else: | |
393 self.fail( | |
394 "{} is not in the valid range of {} to {}.".format( | |
395 rv, self.min, self.max | |
396 ), | |
397 param, | |
398 ctx, | |
399 ) | |
400 return rv | |
401 | |
402 def __repr__(self): | |
403 return "FloatRange({}, {})".format(self.min, self.max) | |
404 | |
405 | |
406 class BoolParamType(ParamType): | |
407 name = "boolean" | |
408 | |
409 def convert(self, value, param, ctx): | |
410 if isinstance(value, bool): | |
411 return bool(value) | |
412 value = value.lower() | |
413 if value in ("true", "t", "1", "yes", "y"): | |
414 return True | |
415 elif value in ("false", "f", "0", "no", "n"): | |
416 return False | |
417 self.fail("{} is not a valid boolean".format(value), param, ctx) | |
418 | |
419 def __repr__(self): | |
420 return "BOOL" | |
421 | |
422 | |
423 class UUIDParameterType(ParamType): | |
424 name = "uuid" | |
425 | |
426 def convert(self, value, param, ctx): | |
427 import uuid | |
428 | |
429 try: | |
430 if PY2 and isinstance(value, text_type): | |
431 value = value.encode("ascii") | |
432 return uuid.UUID(value) | |
433 except ValueError: | |
434 self.fail("{} is not a valid UUID value".format(value), param, ctx) | |
435 | |
436 def __repr__(self): | |
437 return "UUID" | |
438 | |
439 | |
440 class File(ParamType): | |
441 """Declares a parameter to be a file for reading or writing. The file | |
442 is automatically closed once the context tears down (after the command | |
443 finished working). | |
444 | |
445 Files can be opened for reading or writing. The special value ``-`` | |
446 indicates stdin or stdout depending on the mode. | |
447 | |
448 By default, the file is opened for reading text data, but it can also be | |
449 opened in binary mode or for writing. The encoding parameter can be used | |
450 to force a specific encoding. | |
451 | |
452 The `lazy` flag controls if the file should be opened immediately or upon | |
453 first IO. The default is to be non-lazy for standard input and output | |
454 streams as well as files opened for reading, `lazy` otherwise. When opening a | |
455 file lazily for reading, it is still opened temporarily for validation, but | |
456 will not be held open until first IO. lazy is mainly useful when opening | |
457 for writing to avoid creating the file until it is needed. | |
458 | |
459 Starting with Click 2.0, files can also be opened atomically in which | |
460 case all writes go into a separate file in the same folder and upon | |
461 completion the file will be moved over to the original location. This | |
462 is useful if a file regularly read by other users is modified. | |
463 | |
464 See :ref:`file-args` for more information. | |
465 """ | |
466 | |
467 name = "filename" | |
468 envvar_list_splitter = os.path.pathsep | |
469 | |
470 def __init__( | |
471 self, mode="r", encoding=None, errors="strict", lazy=None, atomic=False | |
472 ): | |
473 self.mode = mode | |
474 self.encoding = encoding | |
475 self.errors = errors | |
476 self.lazy = lazy | |
477 self.atomic = atomic | |
478 | |
479 def resolve_lazy_flag(self, value): | |
480 if self.lazy is not None: | |
481 return self.lazy | |
482 if value == "-": | |
483 return False | |
484 elif "w" in self.mode: | |
485 return True | |
486 return False | |
487 | |
488 def convert(self, value, param, ctx): | |
489 try: | |
490 if hasattr(value, "read") or hasattr(value, "write"): | |
491 return value | |
492 | |
493 lazy = self.resolve_lazy_flag(value) | |
494 | |
495 if lazy: | |
496 f = LazyFile( | |
497 value, self.mode, self.encoding, self.errors, atomic=self.atomic | |
498 ) | |
499 if ctx is not None: | |
500 ctx.call_on_close(f.close_intelligently) | |
501 return f | |
502 | |
503 f, should_close = open_stream( | |
504 value, self.mode, self.encoding, self.errors, atomic=self.atomic | |
505 ) | |
506 # If a context is provided, we automatically close the file | |
507 # at the end of the context execution (or flush out). If a | |
508 # context does not exist, it's the caller's responsibility to | |
509 # properly close the file. This for instance happens when the | |
510 # type is used with prompts. | |
511 if ctx is not None: | |
512 if should_close: | |
513 ctx.call_on_close(safecall(f.close)) | |
514 else: | |
515 ctx.call_on_close(safecall(f.flush)) | |
516 return f | |
517 except (IOError, OSError) as e: # noqa: B014 | |
518 self.fail( | |
519 "Could not open file: {}: {}".format( | |
520 filename_to_ui(value), get_streerror(e) | |
521 ), | |
522 param, | |
523 ctx, | |
524 ) | |
525 | |
526 | |
527 class Path(ParamType): | |
528 """The path type is similar to the :class:`File` type but it performs | |
529 different checks. First of all, instead of returning an open file | |
530 handle it returns just the filename. Secondly, it can perform various | |
531 basic checks about what the file or directory should be. | |
532 | |
533 .. versionchanged:: 6.0 | |
534 `allow_dash` was added. | |
535 | |
536 :param exists: if set to true, the file or directory needs to exist for | |
537 this value to be valid. If this is not required and a | |
538 file does indeed not exist, then all further checks are | |
539 silently skipped. | |
540 :param file_okay: controls if a file is a possible value. | |
541 :param dir_okay: controls if a directory is a possible value. | |
542 :param writable: if true, a writable check is performed. | |
543 :param readable: if true, a readable check is performed. | |
544 :param resolve_path: if this is true, then the path is fully resolved | |
545 before the value is passed onwards. This means | |
546 that it's absolute and symlinks are resolved. It | |
547 will not expand a tilde-prefix, as this is | |
548 supposed to be done by the shell only. | |
549 :param allow_dash: If this is set to `True`, a single dash to indicate | |
550 standard streams is permitted. | |
551 :param path_type: optionally a string type that should be used to | |
552 represent the path. The default is `None` which | |
553 means the return value will be either bytes or | |
554 unicode depending on what makes most sense given the | |
555 input data Click deals with. | |
556 """ | |
557 | |
558 envvar_list_splitter = os.path.pathsep | |
559 | |
560 def __init__( | |
561 self, | |
562 exists=False, | |
563 file_okay=True, | |
564 dir_okay=True, | |
565 writable=False, | |
566 readable=True, | |
567 resolve_path=False, | |
568 allow_dash=False, | |
569 path_type=None, | |
570 ): | |
571 self.exists = exists | |
572 self.file_okay = file_okay | |
573 self.dir_okay = dir_okay | |
574 self.writable = writable | |
575 self.readable = readable | |
576 self.resolve_path = resolve_path | |
577 self.allow_dash = allow_dash | |
578 self.type = path_type | |
579 | |
580 if self.file_okay and not self.dir_okay: | |
581 self.name = "file" | |
582 self.path_type = "File" | |
583 elif self.dir_okay and not self.file_okay: | |
584 self.name = "directory" | |
585 self.path_type = "Directory" | |
586 else: | |
587 self.name = "path" | |
588 self.path_type = "Path" | |
589 | |
590 def coerce_path_result(self, rv): | |
591 if self.type is not None and not isinstance(rv, self.type): | |
592 if self.type is text_type: | |
593 rv = rv.decode(get_filesystem_encoding()) | |
594 else: | |
595 rv = rv.encode(get_filesystem_encoding()) | |
596 return rv | |
597 | |
598 def convert(self, value, param, ctx): | |
599 rv = value | |
600 | |
601 is_dash = self.file_okay and self.allow_dash and rv in (b"-", "-") | |
602 | |
603 if not is_dash: | |
604 if self.resolve_path: | |
605 rv = os.path.realpath(rv) | |
606 | |
607 try: | |
608 st = os.stat(rv) | |
609 except OSError: | |
610 if not self.exists: | |
611 return self.coerce_path_result(rv) | |
612 self.fail( | |
613 "{} '{}' does not exist.".format( | |
614 self.path_type, filename_to_ui(value) | |
615 ), | |
616 param, | |
617 ctx, | |
618 ) | |
619 | |
620 if not self.file_okay and stat.S_ISREG(st.st_mode): | |
621 self.fail( | |
622 "{} '{}' is a file.".format(self.path_type, filename_to_ui(value)), | |
623 param, | |
624 ctx, | |
625 ) | |
626 if not self.dir_okay and stat.S_ISDIR(st.st_mode): | |
627 self.fail( | |
628 "{} '{}' is a directory.".format( | |
629 self.path_type, filename_to_ui(value) | |
630 ), | |
631 param, | |
632 ctx, | |
633 ) | |
634 if self.writable and not os.access(value, os.W_OK): | |
635 self.fail( | |
636 "{} '{}' is not writable.".format( | |
637 self.path_type, filename_to_ui(value) | |
638 ), | |
639 param, | |
640 ctx, | |
641 ) | |
642 if self.readable and not os.access(value, os.R_OK): | |
643 self.fail( | |
644 "{} '{}' is not readable.".format( | |
645 self.path_type, filename_to_ui(value) | |
646 ), | |
647 param, | |
648 ctx, | |
649 ) | |
650 | |
651 return self.coerce_path_result(rv) | |
652 | |
653 | |
654 class Tuple(CompositeParamType): | |
655 """The default behavior of Click is to apply a type on a value directly. | |
656 This works well in most cases, except for when `nargs` is set to a fixed | |
657 count and different types should be used for different items. In this | |
658 case the :class:`Tuple` type can be used. This type can only be used | |
659 if `nargs` is set to a fixed number. | |
660 | |
661 For more information see :ref:`tuple-type`. | |
662 | |
663 This can be selected by using a Python tuple literal as a type. | |
664 | |
665 :param types: a list of types that should be used for the tuple items. | |
666 """ | |
667 | |
668 def __init__(self, types): | |
669 self.types = [convert_type(ty) for ty in types] | |
670 | |
671 @property | |
672 def name(self): | |
673 return "<{}>".format(" ".join(ty.name for ty in self.types)) | |
674 | |
675 @property | |
676 def arity(self): | |
677 return len(self.types) | |
678 | |
679 def convert(self, value, param, ctx): | |
680 if len(value) != len(self.types): | |
681 raise TypeError( | |
682 "It would appear that nargs is set to conflict with the" | |
683 " composite type arity." | |
684 ) | |
685 return tuple(ty(x, param, ctx) for ty, x in zip(self.types, value)) | |
686 | |
687 | |
688 def convert_type(ty, default=None): | |
689 """Converts a callable or python type into the most appropriate | |
690 param type. | |
691 """ | |
692 guessed_type = False | |
693 if ty is None and default is not None: | |
694 if isinstance(default, tuple): | |
695 ty = tuple(map(type, default)) | |
696 else: | |
697 ty = type(default) | |
698 guessed_type = True | |
699 | |
700 if isinstance(ty, tuple): | |
701 return Tuple(ty) | |
702 if isinstance(ty, ParamType): | |
703 return ty | |
704 if ty is text_type or ty is str or ty is None: | |
705 return STRING | |
706 if ty is int: | |
707 return INT | |
708 # Booleans are only okay if not guessed. This is done because for | |
709 # flags the default value is actually a bit of a lie in that it | |
710 # indicates which of the flags is the one we want. See get_default() | |
711 # for more information. | |
712 if ty is bool and not guessed_type: | |
713 return BOOL | |
714 if ty is float: | |
715 return FLOAT | |
716 if guessed_type: | |
717 return STRING | |
718 | |
719 # Catch a common mistake | |
720 if __debug__: | |
721 try: | |
722 if issubclass(ty, ParamType): | |
723 raise AssertionError( | |
724 "Attempted to use an uninstantiated parameter type ({}).".format(ty) | |
725 ) | |
726 except TypeError: | |
727 pass | |
728 return FuncParamType(ty) | |
729 | |
730 | |
731 #: A dummy parameter type that just does nothing. From a user's | |
732 #: perspective this appears to just be the same as `STRING` but internally | |
733 #: no string conversion takes place. This is necessary to achieve the | |
734 #: same bytes/unicode behavior on Python 2/3 in situations where you want | |
735 #: to not convert argument types. This is usually useful when working | |
736 #: with file paths as they can appear in bytes and unicode. | |
737 #: | |
738 #: For path related uses the :class:`Path` type is a better choice but | |
739 #: there are situations where an unprocessed type is useful which is why | |
740 #: it is is provided. | |
741 #: | |
742 #: .. versionadded:: 4.0 | |
743 UNPROCESSED = UnprocessedParamType() | |
744 | |
745 #: A unicode string parameter type which is the implicit default. This | |
746 #: can also be selected by using ``str`` as type. | |
747 STRING = StringParamType() | |
748 | |
749 #: An integer parameter. This can also be selected by using ``int`` as | |
750 #: type. | |
751 INT = IntParamType() | |
752 | |
753 #: A floating point value parameter. This can also be selected by using | |
754 #: ``float`` as type. | |
755 FLOAT = FloatParamType() | |
756 | |
757 #: A boolean parameter. This is the default for boolean flags. This can | |
758 #: also be selected by using ``bool`` as a type. | |
759 BOOL = BoolParamType() | |
760 | |
761 #: A UUID parameter. | |
762 UUID = UUIDParameterType() |