def settable_options(doc, argv, ignore, options_first):
"""Determine which options we can set, which ones are boolean, and which ones are repeatable.
All set items are option long names.
:param str doc: Docstring from docoptcfg().
:param iter argv: CLI arguments from docoptcfg().
:param iter ignore: Options to ignore from docoptcfg().
:param bool options_first: docopt argument from docoptcfg().
:return: Settable options, boolean options, repeatable options, and short to long option name mapping.
:rtype: tuple
"""
settable, booleans, repeatable, short_map = set(), set(), set(), dict()
# Determine which options are settable by docoptcfg and which ones are flags/booleans.
options = docopt.parse_defaults(doc)
short_map.update((o.short, o.long) for o in options)
parsed_argv = docopt.parse_argv(docopt.TokenStream(argv, docopt.DocoptExit), list(options), options_first)
overridden = [o.long for o in parsed_argv if hasattr(o, 'long')]
for option in options:
if option.long in overridden or (option.long in ignore or option.short in ignore):
continue
if option.argcount == 0:
booleans.add(option.long)
settable.add(option.long)
# Determine which options are repeatable.
if settable and '...' in doc:
pattern = docopt.parse_pattern(docopt.formal_usage(docopt.DocoptExit.usage), options)
for option in pattern.fix().flat():
if not hasattr(option, 'long'):
continue # Positional argument or sub-command.
if getattr(option, 'long') not in settable:
continue # Don't care about this if we can't set it.
if getattr(option, 'long') in booleans and getattr(option, 'value') == 0:
repeatable.add(getattr(option, 'long'))
elif hasattr(getattr(option, 'value'), '__iter__'):
repeatable.add(getattr(option, 'long'))
return settable, booleans, repeatable, short_map
评论列表
文章目录