Source code for nxpy.command.option

# nxpy.command package -------------------------------------------------------

# Copyright Nicola Musatti 2010 - 2012
# Use, modification, and distribution are subject to the Boost Software
# License, Version 1.0. (See accompanying file LICENSE.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)

# See http://sourceforge.net/nxpy for library home page. ---------------------

r"""
Function argument to command line option conversion.
Provides means to describe commands with complicated syntaxes, which often combine sub-commands, 
options and arguments. Typical examples include subversion and ftp.

"""

import nxpy.core.sequence


[docs]class InvalidOptionError(Exception): r"""Raised when an option is not supported."""
[docs]class Config(object): r""" Command option definitions. Provides a single definition point for all the options supported by a command. """ def __init__(self, prefix="--", separator=" ", bool_opts=(), value_opts=(), iterable_opts=(), format_opts={}, mapped_opts={}, opposite_opts={}): r""" Constructor. Its arguments are used to specify all the valid options. Each option is prefixed by 'prefix'. When an option takes multiple arguments these are separated by a 'separator'. 'bool_opts' must be specified on the command line when they are 'True'. 'value_options' take a single argument; 'iterable_options' take multiple arguments; 'format_options' have their syntax specified by means of a format string; 'mapped_options' require some form of translation, usually because they are not valid Python identifiers; 'opposite_options' must be specified on the command line when they are 'False'. """ self.prefix = prefix self.separator = separator self.bool_opts = bool_opts self.value_opts = value_opts self.iterable_opts = iterable_opts self.format_opts = format_opts self.mapped_opts = mapped_opts self.opposite_opts = opposite_opts self.opts = set(nxpy.core.sequence.make_tuple(bool_opts)) self.opts.update(nxpy.core.sequence.make_tuple(value_opts)) self.opts.update(nxpy.core.sequence.make_tuple(iterable_opts)) self.opts.update(format_opts.keys()) self.opts.difference_update(mapped_opts.keys())
[docs]class Parser(object): r""" Constructs a complex command line from the provided 'command' and its 'options' and 'arguments'. Uses a Config instance, 'config', to provide means to check conditions on the supplied options. """ def __init__(self, config, command, arguments, options, **defaults): invalid = set(options.keys()).difference(defaults.keys()) if len(invalid) > 0: raise InvalidOptionError(", ".join(invalid) + ": invalid option(s)") self.config = config self.command = command self.arguments = arguments self.options = {} self.options.update(defaults) self.options.update(options) self.cmd_line = [] def getCommandLine(self): if not self.cmd_line: self._applyOptions() if self.arguments: self.cmd_line.extend(self.arguments) return " ".join(self.cmd_line) def checkMandatoryOptions(self, *options): if not all([ bool(self.options[o]) for o in options ]): raise InvalidOptionError(", ".join(options) + ": mandatory options") def checkExclusiveOptions(self, *options): if sum([ bool(self.options[o]) for o in options ]) > 1: raise InvalidOptionError(", ".join(options) + ": mutually exclusive options") def checkExactlyOneOption(self, *options): s = sum([ bool(self.options[o]) for o in options ]) if s != 1: raise InvalidOptionError(", ".join(options) + ": only one among these options should be specified") def checkNotBothOptsAndArgs(self, *options): if any([ bool(self.options[o]) for o in options ]) and self.arguments: raise InvalidOptionError(", ".join(options) + ": This/these option(s) is/are invalid when arguments are specified") def checkOneBetweenOptsAndArgs(self, *options): if ( any([ bool(self.options[o]) for o in options ]) + bool(self.arguments) ) != 1: raise InvalidOptionError(", ".join(options) + ": This/these option(s) is/are mutually exclusive with arguments") def _applyOptions(self): if self.command is not None: self.cmd_line.append(self.command) for opt in self.options.keys(): if self.options[opt]: if opt in self.config.opts: self.cmd_line.append(self.config.prefix + opt) elif opt in self.config.mapped_opts: self.cmd_line.append(self.config.mapped_opts[opt]) if opt in self.config.value_opts: self.cmd_line.append(self.options[opt]) elif opt in self.config.iterable_opts: self.cmd_line.append(self.config.separator.join(self.options[opt])) elif opt in self.config.format_opts.keys(): self.cmd_line.append( self.config.format_opts[opt] % self.options[opt]) elif opt in self.config.opposite_opts.keys(): self.cmd_line.append(self.config.opposite_opts[opt])

This Project