|
33 | 33 | from __future__ import division
|
34 | 34 | from __future__ import print_function
|
35 | 35 |
|
| 36 | +import itertools |
| 37 | + |
36 | 38 | from fire import completion
|
37 | 39 | from fire import custom_descriptions
|
38 | 40 | from fire import decorators
|
@@ -167,6 +169,11 @@ def _DescriptionSection(component, info):
|
167 | 169 | return None
|
168 | 170 |
|
169 | 171 |
|
| 172 | +def _CreateKeywordOnlyFlagItem(flag, docstring_info, spec): |
| 173 | + return _CreateFlagItem( |
| 174 | + flag, docstring_info, required=flag not in spec.kwonlydefaults) |
| 175 | + |
| 176 | + |
170 | 177 | def _ArgsAndFlagsSections(info, spec, metadata):
|
171 | 178 | """The "Args and Flags" sections of the help string."""
|
172 | 179 | args_with_no_defaults = spec.args[:len(spec.args) - len(spec.defaults)]
|
@@ -199,15 +206,15 @@ def _ArgsAndFlagsSections(info, spec, metadata):
|
199 | 206 | ('NOTES', 'You can also use flags syntax for POSITIONAL ARGUMENTS')
|
200 | 207 | )
|
201 | 208 |
|
202 |
| - optional_flag_items = [ |
| 209 | + positional_flag_items = [ |
203 | 210 | _CreateFlagItem(flag, docstring_info, required=False)
|
204 | 211 | for flag in args_with_defaults
|
205 | 212 | ]
|
206 |
| - required_flag_items = [ |
207 |
| - _CreateFlagItem(flag, docstring_info, required=True) |
| 213 | + kwonly_flag_items = [ |
| 214 | + _CreateKeywordOnlyFlagItem(flag, docstring_info, spec) |
208 | 215 | for flag in spec.kwonlyargs
|
209 | 216 | ]
|
210 |
| - flag_items = optional_flag_items + required_flag_items |
| 217 | + flag_items = positional_flag_items + kwonly_flag_items |
211 | 218 |
|
212 | 219 | if spec.varkw:
|
213 | 220 | description = _GetArgDescription(spec.varkw, docstring_info)
|
@@ -382,9 +389,7 @@ def _CreateFlagItem(flag, docstring_info, required=False):
|
382 | 389 | flag: The name of the flag.
|
383 | 390 | docstring_info: A docstrings.DocstringInfo namedtuple with information about
|
384 | 391 | the containing function's docstring.
|
385 |
| - required: Whether the flag is required. Keyword-only arguments (only in |
386 |
| - Python 3) become required flags, whereas normal keyword arguments become |
387 |
| - optional flags. |
| 392 | + required: Whether the flag is required. |
388 | 393 | Returns:
|
389 | 394 | A string to be used in constructing the help screen for the function.
|
390 | 395 | """
|
@@ -570,13 +575,21 @@ def _GetCallableUsageItems(spec, metadata):
|
570 | 575 | return items
|
571 | 576 |
|
572 | 577 |
|
| 578 | +def _KeywordOnlyArguments(spec, required=True): |
| 579 | + return (flag for flag in spec.kwonlyargs |
| 580 | + if required == (flag in spec.kwonlydefaults)) |
| 581 | + |
| 582 | + |
573 | 583 | def _GetCallableAvailabilityLines(spec):
|
574 | 584 | """The list of availability lines for a callable for use in a usage string."""
|
575 | 585 | args_with_defaults = spec.args[len(spec.args) - len(spec.defaults):]
|
576 | 586 |
|
577 | 587 | # TODO(dbieber): Handle args_with_no_defaults if not accepts_positional_args.
|
578 |
| - optional_flags = [('--' + flag) for flag in args_with_defaults] |
579 |
| - required_flags = [('--' + flag) for flag in spec.kwonlyargs] |
| 588 | + optional_flags = [('--' + flag) for flag in itertools.chain( |
| 589 | + args_with_defaults, _KeywordOnlyArguments(spec, required=False))] |
| 590 | + required_flags = [ |
| 591 | + ('--' + flag) for flag in _KeywordOnlyArguments(spec, required=True) |
| 592 | + ] |
580 | 593 |
|
581 | 594 | # Flags section:
|
582 | 595 | availability_lines = []
|
|
0 commit comments