| Viewing file:  commandline.py (4.98 KB)      -rw-r--r-- Select action/file-type:
 
  (+) |  (+) |  (+) | Code (+) | Session (+) |  (+) | SDB (+) |  (+) |  (+) |  (+) |  (+) |  (+) | 
 
import argparseimport shlex
 import sys
 
 from copy import deepcopy
 
 from ..config import Configuration
 from ..setting import BooleanSetting, ChoiceSetting, ListSetting
 from .base import Source
 
 
 __all__ = ("CommandLineSource",)
 
 
 # pylint: disable=R0201
 
 
 class CommandLineSource(Source):
 # pylint: disable=R0913
 def __init__(
 self,
 arguments=None,
 options=None,
 version=None,
 parser_options=None,
 positional=None,
 ):
 super(CommandLineSource, self).__init__()
 
 if arguments is None:
 self.arguments = sys.argv[1:]
 elif isinstance(arguments, str):
 self.arguments = shlex.split(arguments)
 elif isinstance(arguments, (list, tuple)):
 self.arguments = arguments
 else:
 raise TypeError("arguments must be a string or list of strings")
 
 self.version = version
 self.options = options or {}
 self.parser_options = parser_options or {}
 self.positional = positional or ()
 
 def get_flags(self, setting):
 if setting.name in self.options:
 if "flags" in self.options[setting.name]:
 return self.options[setting.name]["flags"]
 
 flags = []
 flag = "--%s" % setting.name.lower().replace("_", "-")
 flags.append(flag)
 return flags
 
 def get_action(self, setting):
 if isinstance(setting, BooleanSetting):
 return "store_false" if setting.default else "store_true"
 elif isinstance(setting, ListSetting):
 return "append"
 else:
 return "store"
 
 # pylint: disable=W0613
 def get_default(self, setting):
 # Caveat: Returning something other than SUPPRESS probably won't
 # work the way you'd think.
 return argparse.SUPPRESS
 
 def get_type(self, setting):
 if isinstance(setting, (ListSetting, BooleanSetting)):
 return None
 elif isinstance(setting, ChoiceSetting):
 return setting.subtype.sanitize
 else:
 return setting.sanitize
 
 def get_dest(self, setting):
 return setting.name
 
 def get_choices(self, setting):
 if isinstance(setting, ChoiceSetting):
 return setting.choices
 else:
 return None
 
 def get_help(self, setting):
 if setting.name in self.options:
 if "help" in self.options[setting.name]:
 return self.options[setting.name]["help"]
 return None
 
 def get_metavar(self, setting):
 if setting.name in self.options:
 if "metavar" in self.options[setting.name]:
 return self.options[setting.name]["metavar"]
 return None
 
 def build_argument(self, setting):
 flags = self.get_flags(setting)
 action = self.get_action(setting)
 default = self.get_default(setting)
 argtype = self.get_type(setting)
 dest = self.get_dest(setting)
 choices = self.get_choices(setting)
 arghelp = self.get_help(setting)
 metavar = self.get_metavar(setting)
 
 argument_kwargs = {
 "action": action,
 "default": default,
 "dest": dest,
 "help": arghelp,
 }
 if argtype:
 argument_kwargs["type"] = argtype
 if choices:
 argument_kwargs["choices"] = choices
 if metavar:
 argument_kwargs["metavar"] = metavar
 
 return flags, argument_kwargs
 
 def build_parser(self, settings, manager):
 parser_options = deepcopy(self.parser_options)
 if not parser_options.get("prog") and manager:
 parser_options["prog"] = manager.name
 parser = argparse.ArgumentParser(**parser_options)
 
 add_version = self.version is not None
 
 for setting in settings:
 flags, argument_kwargs = self.build_argument(setting)
 parser.add_argument(*flags, **argument_kwargs)
 
 if add_version and setting.name == "version":
 # Don't want to conflict with the desired setting
 add_version = False
 
 if add_version:
 parser.add_argument(
 "--version", action="version", version="%(prog)s " + self.version
 )
 
 if self.positional:
 for name, options in self.positional:
 parser.add_argument(name, **options)
 
 return parser
 
 def get_config(self, settings, manager=None, parent=None):
 parser = self.build_parser(settings, manager)
 parsed = parser.parse_args(self.arguments)
 
 for setting in settings:
 if hasattr(parsed, setting.name):
 setting.value = getattr(parsed, setting.name)
 
 if self.positional and manager:
 arguments = {}
 for name, _ in self.positional:
 if hasattr(parsed, name):
 arguments[name] = getattr(parsed, name)
 setattr(manager, "arguments", arguments)
 
 return Configuration(settings=settings, parent=parent)
 
 |