Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
optparse.py1672 linesDownload Raw Back to Lib
1"""A powerful, extensible, and easy-to-use option parser.2 3By Greg Ward <gward@python.net>4 5Originally distributed as Optik.6 7For support, use the optik-users@lists.sourceforge.net mailing list8(http://lists.sourceforge.net/lists/listinfo/optik-users).9 10Simple usage example:11 12   from optparse import OptionParser13 14   parser = OptionParser()15   parser.add_option("-f", "--file", dest="filename",16                     help="write report to FILE", metavar="FILE")17   parser.add_option("-q", "--quiet",18                     action="store_false", dest="verbose", default=True,19                     help="don't print status messages to stdout")20 21   (options, args) = parser.parse_args()22"""23 24__version__ = "1.5.3"25 26__all__ = ['Option',27           'make_option',28           'SUPPRESS_HELP',29           'SUPPRESS_USAGE',30           'Values',31           'OptionContainer',32           'OptionGroup',33           'OptionParser',34           'HelpFormatter',35           'IndentedHelpFormatter',36           'TitledHelpFormatter',37           'OptParseError',38           'OptionError',39           'OptionConflictError',40           'OptionValueError',41           'BadOptionError',42           'check_choice']43 44__copyright__ = """45Copyright (c) 2001-2006 Gregory P. Ward.  All rights reserved.46Copyright (c) 2002 Python Software Foundation.  All rights reserved.47 48Redistribution and use in source and binary forms, with or without49modification, are permitted provided that the following conditions are50met:51 52  * Redistributions of source code must retain the above copyright53    notice, this list of conditions and the following disclaimer.54 55  * Redistributions in binary form must reproduce the above copyright56    notice, this list of conditions and the following disclaimer in the57    documentation and/or other materials provided with the distribution.58 59  * Neither the name of the author nor the names of its60    contributors may be used to endorse or promote products derived from61    this software without specific prior written permission.62 63THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS64IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED65TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A66PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR67CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,68EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,69PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR70PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF71LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING72NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS73SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.74"""75 76import sys, os77from gettext import gettext as _, ngettext78 79 80def _repr(self):81    return "<%s at 0x%x: %s>" % (self.__class__.__name__, id(self), self)82 83 84# This file was generated from:85#   Id: option_parser.py 527 2006-07-23 15:21:30Z greg86#   Id: option.py 522 2006-06-11 16:22:03Z gward87#   Id: help.py 527 2006-07-23 15:21:30Z greg88#   Id: errors.py 509 2006-04-20 00:58:24Z gward89 90 91class OptParseError (Exception):92    def __init__(self, msg):93        self.msg = msg94 95    def __str__(self):96        return self.msg97 98 99class OptionError (OptParseError):100    """101    Raised if an Option instance is created with invalid or102    inconsistent arguments.103    """104 105    def __init__(self, msg, option):106        self.msg = msg107        self.option_id = str(option)108 109    def __str__(self):110        if self.option_id:111            return "option %s: %s" % (self.option_id, self.msg)112        else:113            return self.msg114 115class OptionConflictError (OptionError):116    """117    Raised if conflicting options are added to an OptionParser.118    """119 120class OptionValueError (OptParseError):121    """122    Raised if an invalid option value is encountered on the command123    line.124    """125 126class BadOptionError (OptParseError):127    """128    Raised if an invalid option is seen on the command line.129    """130    def __init__(self, opt_str):131        self.opt_str = opt_str132 133    def __str__(self):134        return _("no such option: %s") % self.opt_str135 136class AmbiguousOptionError (BadOptionError):137    """138    Raised if an ambiguous option is seen on the command line.139    """140    def __init__(self, opt_str, possibilities):141        BadOptionError.__init__(self, opt_str)142        self.possibilities = possibilities143 144    def __str__(self):145        return (_("ambiguous option: %s (%s?)")146                % (self.opt_str, ", ".join(self.possibilities)))147 148 149class HelpFormatter:150 151    """152    Abstract base class for formatting option help.  OptionParser153    instances should use one of the HelpFormatter subclasses for154    formatting help; by default IndentedHelpFormatter is used.155 156    Instance attributes:157      parser : OptionParser158        the controlling OptionParser instance159      indent_increment : int160        the number of columns to indent per nesting level161      max_help_position : int162        the maximum starting column for option help text163      help_position : int164        the calculated starting column for option help text;165        initially the same as the maximum166      width : int167        total number of columns for output (pass None to constructor for168        this value to be taken from the $COLUMNS environment variable)169      level : int170        current indentation level171      current_indent : int172        current indentation level (in columns)173      help_width : int174        number of columns available for option help text (calculated)175      default_tag : str176        text to replace with each option's default value, "%default"177        by default.  Set to false value to disable default value expansion.178      option_strings : { Option : str }179        maps Option instances to the snippet of help text explaining180        the syntax of that option, e.g. "-h, --help" or181        "-fFILE, --file=FILE"182      _short_opt_fmt : str183        format string controlling how short options with values are184        printed in help text.  Must be either "%s%s" ("-fFILE") or185        "%s %s" ("-f FILE"), because those are the two syntaxes that186        Optik supports.187      _long_opt_fmt : str188        similar but for long options; must be either "%s %s" ("--file FILE")189        or "%s=%s" ("--file=FILE").190    """191 192    NO_DEFAULT_VALUE = "none"193 194    def __init__(self,195                 indent_increment,196                 max_help_position,197                 width,198                 short_first):199        self.parser = None200        self.indent_increment = indent_increment201        if width is None:202            try:203                width = int(os.environ['COLUMNS'])204            except (KeyError, ValueError):205                width = 80206            width -= 2207        self.width = width208        self.help_position = self.max_help_position = \209                min(max_help_position, max(width - 20, indent_increment * 2))210        self.current_indent = 0211        self.level = 0212        self.help_width = None          # computed later213        self.short_first = short_first214        self.default_tag = "%default"215        self.option_strings = {}216        self._short_opt_fmt = "%s %s"217        self._long_opt_fmt = "%s=%s"218 219    def set_parser(self, parser):220        self.parser = parser221 222    def set_short_opt_delimiter(self, delim):223        if delim not in ("", " "):224            raise ValueError(225                "invalid metavar delimiter for short options: %r" % delim)226        self._short_opt_fmt = "%s" + delim + "%s"227 228    def set_long_opt_delimiter(self, delim):229        if delim not in ("=", " "):230            raise ValueError(231                "invalid metavar delimiter for long options: %r" % delim)232        self._long_opt_fmt = "%s" + delim + "%s"233 234    def indent(self):235        self.current_indent += self.indent_increment236        self.level += 1237 238    def dedent(self):239        self.current_indent -= self.indent_increment240        assert self.current_indent >= 0, "Indent decreased below 0."241        self.level -= 1242 243    def format_usage(self, usage):244        raise NotImplementedError("subclasses must implement")245 246    def format_heading(self, heading):247        raise NotImplementedError("subclasses must implement")248 249    def _format_text(self, text):250        """251        Format a paragraph of free-form text for inclusion in the252        help output at the current indentation level.253        """254        import textwrap255        text_width = max(self.width - self.current_indent, 11)256        indent = " "*self.current_indent257        return textwrap.fill(text,258                             text_width,259                             initial_indent=indent,260                             subsequent_indent=indent)261 262    def format_description(self, description):263        if description:264            return self._format_text(description) + "\n"265        else:266            return ""267 268    def format_epilog(self, epilog):269        if epilog:270            return "\n" + self._format_text(epilog) + "\n"271        else:272            return ""273 274 275    def expand_default(self, option):276        if self.parser is None or not self.default_tag:277            return option.help278 279        default_value = self.parser.defaults.get(option.dest)280        if default_value is NO_DEFAULT or default_value is None:281            default_value = self.NO_DEFAULT_VALUE282 283        return option.help.replace(self.default_tag, str(default_value))284 285    def format_option(self, option):286        # The help for each option consists of two parts:287        #   * the opt strings and metavars288        #     eg. ("-x", or "-fFILENAME, --file=FILENAME")289        #   * the user-supplied help string290        #     eg. ("turn on expert mode", "read data from FILENAME")291        #292        # If possible, we write both of these on the same line:293        #   -x      turn on expert mode294        #295        # But if the opt string list is too long, we put the help296        # string on a second line, indented to the same column it would297        # start in if it fit on the first line.298        #   -fFILENAME, --file=FILENAME299        #           read data from FILENAME300        result = []301        opts = self.option_strings[option]302        opt_width = self.help_position - self.current_indent - 2303        if len(opts) > opt_width:304            opts = "%*s%s\n" % (self.current_indent, "", opts)305            indent_first = self.help_position306        else:                       # start help on same line as opts307            opts = "%*s%-*s  " % (self.current_indent, "", opt_width, opts)308            indent_first = 0309        result.append(opts)310        if option.help:311            import textwrap312            help_text = self.expand_default(option)313            help_lines = textwrap.wrap(help_text, self.help_width)314            result.append("%*s%s\n" % (indent_first, "", help_lines[0]))315            result.extend(["%*s%s\n" % (self.help_position, "", line)316                           for line in help_lines[1:]])317        elif opts[-1] != "\n":318            result.append("\n")319        return "".join(result)320 321    def store_option_strings(self, parser):322        self.indent()323        max_len = 0324        for opt in parser.option_list:325            strings = self.format_option_strings(opt)326            self.option_strings[opt] = strings327            max_len = max(max_len, len(strings) + self.current_indent)328        self.indent()329        for group in parser.option_groups:330            for opt in group.option_list:331                strings = self.format_option_strings(opt)332                self.option_strings[opt] = strings333                max_len = max(max_len, len(strings) + self.current_indent)334        self.dedent()335        self.dedent()336        self.help_position = min(max_len + 2, self.max_help_position)337        self.help_width = max(self.width - self.help_position, 11)338 339    def format_option_strings(self, option):340        """Return a comma-separated list of option strings & metavariables."""341        if option.takes_value():342            metavar = option.metavar or option.dest.upper()343            short_opts = [self._short_opt_fmt % (sopt, metavar)344                          for sopt in option._short_opts]345            long_opts = [self._long_opt_fmt % (lopt, metavar)346                         for lopt in option._long_opts]347        else:348            short_opts = option._short_opts349            long_opts = option._long_opts350 351        if self.short_first:352            opts = short_opts + long_opts353        else:354            opts = long_opts + short_opts355 356        return ", ".join(opts)357 358class IndentedHelpFormatter (HelpFormatter):359    """Format help with indented section bodies.360    """361 362    def __init__(self,363                 indent_increment=2,364                 max_help_position=24,365                 width=None,366                 short_first=1):367        HelpFormatter.__init__(368            self, indent_increment, max_help_position, width, short_first)369 370    def format_usage(self, usage):371        return _("Usage: %s\n") % usage372 373    def format_heading(self, heading):374        return "%*s%s:\n" % (self.current_indent, "", heading)375 376 377class TitledHelpFormatter (HelpFormatter):378    """Format help with underlined section headers.379    """380 381    def __init__(self,382                 indent_increment=0,383                 max_help_position=24,384                 width=None,385                 short_first=0):386        HelpFormatter.__init__ (387            self, indent_increment, max_help_position, width, short_first)388 389    def format_usage(self, usage):390        return "%s  %s\n" % (self.format_heading(_("Usage")), usage)391 392    def format_heading(self, heading):393        return "%s\n%s\n" % (heading, "=-"[self.level] * len(heading))394 395 396def _parse_num(val, type):397    if val[:2].lower() == "0x":         # hexadecimal398        radix = 16399    elif val[:2].lower() == "0b":       # binary400        radix = 2401        val = val[2:] or "0"            # have to remove "0b" prefix402    elif val[:1] == "0":                # octal403        radix = 8404    else:                               # decimal405        radix = 10406 407    return type(val, radix)408 409def _parse_int(val):410    return _parse_num(val, int)411 412_builtin_cvt = { "int" : (_parse_int, _("integer")),413                 "long" : (_parse_int, _("integer")),414                 "float" : (float, _("floating-point")),415                 "complex" : (complex, _("complex")) }416 417def check_builtin(option, opt, value):418    (cvt, what) = _builtin_cvt[option.type]419    try:420        return cvt(value)421    except ValueError:422        raise OptionValueError(423            _("option %s: invalid %s value: %r") % (opt, what, value))424 425def check_choice(option, opt, value):426    if value in option.choices:427        return value428    else:429        choices = ", ".join(map(repr, option.choices))430        raise OptionValueError(431            _("option %s: invalid choice: %r (choose from %s)")432            % (opt, value, choices))433 434# Not supplying a default is different from a default of None,435# so we need an explicit "not supplied" value.436NO_DEFAULT = ("NO", "DEFAULT")437 438 439class Option:440    """441    Instance attributes:442      _short_opts : [string]443      _long_opts : [string]444 445      action : string446      type : string447      dest : string448      default : any449      nargs : int450      const : any451      choices : [string]452      callback : function453      callback_args : (any*)454      callback_kwargs : { string : any }455      help : string456      metavar : string457    """458 459    # The list of instance attributes that may be set through460    # keyword args to the constructor.461    ATTRS = ['action',462             'type',463             'dest',464             'default',465             'nargs',466             'const',467             'choices',468             'callback',469             'callback_args',470             'callback_kwargs',471             'help',472             'metavar']473 474    # The set of actions allowed by option parsers.  Explicitly listed475    # here so the constructor can validate its arguments.476    ACTIONS = ("store",477               "store_const",478               "store_true",479               "store_false",480               "append",481               "append_const",482               "count",483               "callback",484               "help",485               "version")486 487    # The set of actions that involve storing a value somewhere;488    # also listed just for constructor argument validation.  (If489    # the action is one of these, there must be a destination.)490    STORE_ACTIONS = ("store",491                     "store_const",492                     "store_true",493                     "store_false",494                     "append",495                     "append_const",496                     "count")497 498    # The set of actions for which it makes sense to supply a value499    # type, ie. which may consume an argument from the command line.500    TYPED_ACTIONS = ("store",501                     "append",502                     "callback")503 504    # The set of actions which *require* a value type, ie. that505    # always consume an argument from the command line.506    ALWAYS_TYPED_ACTIONS = ("store",507                            "append")508 509    # The set of actions which take a 'const' attribute.510    CONST_ACTIONS = ("store_const",511                     "append_const")512 513    # The set of known types for option parsers.  Again, listed here for514    # constructor argument validation.515    TYPES = ("string", "int", "long", "float", "complex", "choice")516 517    # Dictionary of argument checking functions, which convert and518    # validate option arguments according to the option type.519    #520    # Signature of checking functions is:521    #   check(option : Option, opt : string, value : string) -> any522    # where523    #   option is the Option instance calling the checker524    #   opt is the actual option seen on the command-line525    #     (eg. "-a", "--file")526    #   value is the option argument seen on the command-line527    #528    # The return value should be in the appropriate Python type529    # for option.type -- eg. an integer if option.type == "int".530    #531    # If no checker is defined for a type, arguments will be532    # unchecked and remain strings.533    TYPE_CHECKER = { "int"    : check_builtin,534                     "long"   : check_builtin,535                     "float"  : check_builtin,536                     "complex": check_builtin,537                     "choice" : check_choice,538                   }539 540 541    # CHECK_METHODS is a list of unbound method objects; they are called542    # by the constructor, in order, after all attributes are543    # initialized.  The list is created and filled in later, after all544    # the methods are actually defined.  (I just put it here because I545    # like to define and document all class attributes in the same546    # place.)  Subclasses that add another _check_*() method should547    # define their own CHECK_METHODS list that adds their check method548    # to those from this class.549    CHECK_METHODS = None550 551 552    # -- Constructor/initialization methods ----------------------------553 554    def __init__(self, *opts, **attrs):555        # Set _short_opts, _long_opts attrs from 'opts' tuple.556        # Have to be set now, in case no option strings are supplied.557        self._short_opts = []558        self._long_opts = []559        opts = self._check_opt_strings(opts)560        self._set_opt_strings(opts)561 562        # Set all other attrs (action, type, etc.) from 'attrs' dict563        self._set_attrs(attrs)564 565        # Check all the attributes we just set.  There are lots of566        # complicated interdependencies, but luckily they can be farmed567        # out to the _check_*() methods listed in CHECK_METHODS -- which568        # could be handy for subclasses!  The one thing these all share569        # is that they raise OptionError if they discover a problem.570        for checker in self.CHECK_METHODS:571            checker(self)572 573    def _check_opt_strings(self, opts):574        # Filter out None because early versions of Optik had exactly575        # one short option and one long option, either of which576        # could be None.577        opts = [opt for opt in opts if opt]578        if not opts:579            raise TypeError("at least one option string must be supplied")580        return opts581 582    def _set_opt_strings(self, opts):583        for opt in opts:584            if len(opt) < 2:585                raise OptionError(586                    "invalid option string %r: "587                    "must be at least two characters long" % opt, self)588            elif len(opt) == 2:589                if not (opt[0] == "-" and opt[1] != "-"):590                    raise OptionError(591                        "invalid short option string %r: "592                        "must be of the form -x, (x any non-dash char)" % opt,593                        self)594                self._short_opts.append(opt)595            else:596                if not (opt[0:2] == "--" and opt[2] != "-"):597                    raise OptionError(598                        "invalid long option string %r: "599                        "must start with --, followed by non-dash" % opt,600                        self)601                self._long_opts.append(opt)602 603    def _set_attrs(self, attrs):604        for attr in self.ATTRS:605            if attr in attrs:606                setattr(self, attr, attrs[attr])607                del attrs[attr]608            else:609                if attr == 'default':610                    setattr(self, attr, NO_DEFAULT)611                else:612                    setattr(self, attr, None)613        if attrs:614            attrs = sorted(attrs.keys())615            raise OptionError(616                "invalid keyword arguments: %s" % ", ".join(attrs),617                self)618 619 620    # -- Constructor validation methods --------------------------------621 622    def _check_action(self):623        if self.action is None:624            self.action = "store"625        elif self.action not in self.ACTIONS:626            raise OptionError("invalid action: %r" % self.action, self)627 628    def _check_type(self):629        if self.type is None:630            if self.action in self.ALWAYS_TYPED_ACTIONS:631                if self.choices is not None:632                    # The "choices" attribute implies "choice" type.633                    self.type = "choice"634                else:635                    # No type given?  "string" is the most sensible default.636                    self.type = "string"637        else:638            # Allow type objects or builtin type conversion functions639            # (int, str, etc.) as an alternative to their names.640            if isinstance(self.type, type):641                self.type = self.type.__name__642 643            if self.type == "str":644                self.type = "string"645 646            if self.type not in self.TYPES:647                raise OptionError("invalid option type: %r" % self.type, self)648            if self.action not in self.TYPED_ACTIONS:649                raise OptionError(650                    "must not supply a type for action %r" % self.action, self)651 652    def _check_choice(self):653        if self.type == "choice":654            if self.choices is None:655                raise OptionError(656                    "must supply a list of choices for type 'choice'", self)657            elif not isinstance(self.choices, (tuple, list)):658                raise OptionError(659                    "choices must be a list of strings ('%s' supplied)"660                    % str(type(self.choices)).split("'")[1], self)661        elif self.choices is not None:662            raise OptionError(663                "must not supply choices for type %r" % self.type, self)664 665    def _check_dest(self):666        # No destination given, and we need one for this action.  The667        # self.type check is for callbacks that take a value.668        takes_value = (self.action in self.STORE_ACTIONS or669                       self.type is not None)670        if self.dest is None and takes_value:671 672            # Glean a destination from the first long option string,673            # or from the first short option string if no long options.674            if self._long_opts:675                # eg. "--foo-bar" -> "foo_bar"676                self.dest = self._long_opts[0][2:].replace('-', '_')677            else:678                self.dest = self._short_opts[0][1]679 680    def _check_const(self):681        if self.action not in self.CONST_ACTIONS and self.const is not None:682            raise OptionError(683                "'const' must not be supplied for action %r" % self.action,684                self)685 686    def _check_nargs(self):687        if self.action in self.TYPED_ACTIONS:688            if self.nargs is None:689                self.nargs = 1690        elif self.nargs is not None:691            raise OptionError(692                "'nargs' must not be supplied for action %r" % self.action,693                self)694 695    def _check_callback(self):696        if self.action == "callback":697            if not callable(self.callback):698                raise OptionError(699                    "callback not callable: %r" % self.callback, self)700            if (self.callback_args is not None and701                not isinstance(self.callback_args, tuple)):702                raise OptionError(703                    "callback_args, if supplied, must be a tuple: not %r"704                    % self.callback_args, self)705            if (self.callback_kwargs is not None and706                not isinstance(self.callback_kwargs, dict)):707                raise OptionError(708                    "callback_kwargs, if supplied, must be a dict: not %r"709                    % self.callback_kwargs, self)710        else:711            if self.callback is not None:712                raise OptionError(713                    "callback supplied (%r) for non-callback option"714                    % self.callback, self)715            if self.callback_args is not None:716                raise OptionError(717                    "callback_args supplied for non-callback option", self)718            if self.callback_kwargs is not None:719                raise OptionError(720                    "callback_kwargs supplied for non-callback option", self)721 722 723    CHECK_METHODS = [_check_action,724                     _check_type,725                     _check_choice,726                     _check_dest,727                     _check_const,728                     _check_nargs,729                     _check_callback]730 731 732    # -- Miscellaneous methods -----------------------------------------733 734    def __str__(self):735        return "/".join(self._short_opts + self._long_opts)736 737    __repr__ = _repr738 739    def takes_value(self):740        return self.type is not None741 742    def get_opt_string(self):743        if self._long_opts:744            return self._long_opts[0]745        else:746            return self._short_opts[0]747 748 749    # -- Processing methods --------------------------------------------750 751    def check_value(self, opt, value):752        checker = self.TYPE_CHECKER.get(self.type)753        if checker is None:754            return value755        else:756            return checker(self, opt, value)757 758    def convert_value(self, opt, value):759        if value is not None:760            if self.nargs == 1:761                return self.check_value(opt, value)762            else:763                return tuple([self.check_value(opt, v) for v in value])764 765    def process(self, opt, value, values, parser):766 767        # First, convert the value(s) to the right type.  Howl if any768        # value(s) are bogus.769        value = self.convert_value(opt, value)770 771        # And then take whatever action is expected of us.772        # This is a separate method to make life easier for773        # subclasses to add new actions.774        return self.take_action(775            self.action, self.dest, opt, value, values, parser)776 777    def take_action(self, action, dest, opt, value, values, parser):778        if action == "store":779            setattr(values, dest, value)780        elif action == "store_const":781            setattr(values, dest, self.const)782        elif action == "store_true":783            setattr(values, dest, True)784        elif action == "store_false":785            setattr(values, dest, False)786        elif action == "append":787            values.ensure_value(dest, []).append(value)788        elif action == "append_const":789            values.ensure_value(dest, []).append(self.const)790        elif action == "count":791            setattr(values, dest, values.ensure_value(dest, 0) + 1)792        elif action == "callback":793            args = self.callback_args or ()794            kwargs = self.callback_kwargs or {}795            self.callback(self, opt, value, parser, *args, **kwargs)796        elif action == "help":797            parser.print_help()798            parser.exit()799        elif action == "version":800            parser.print_version()801            parser.exit()802        else:803            raise ValueError("unknown action %r" % self.action)804 805        return 1806 807# class Option808 809 810SUPPRESS_HELP = "SUPPRESS"+"HELP"811SUPPRESS_USAGE = "SUPPRESS"+"USAGE"812 813class Values:814 815    def __init__(self, defaults=None):816        if defaults:817            for (attr, val) in defaults.items():818                setattr(self, attr, val)819 820    def __str__(self):821        return str(self.__dict__)822 823    __repr__ = _repr824 825    def __eq__(self, other):826        if isinstance(other, Values):827            return self.__dict__ == other.__dict__828        elif isinstance(other, dict):829            return self.__dict__ == other830        else:831            return NotImplemented832 833    def _update_careful(self, dict):834        """835        Update the option values from an arbitrary dictionary, but only836        use keys from dict that already have a corresponding attribute837        in self.  Any keys in dict without a corresponding attribute838        are silently ignored.839        """840        for attr in dir(self):841            if attr in dict:842                dval = dict[attr]843                if dval is not None:844                    setattr(self, attr, dval)845 846    def _update_loose(self, dict):847        """848        Update the option values from an arbitrary dictionary,849        using all keys from the dictionary regardless of whether850        they have a corresponding attribute in self or not.851        """852        self.__dict__.update(dict)853 854    def _update(self, dict, mode):855        if mode == "careful":856            self._update_careful(dict)857        elif mode == "loose":858            self._update_loose(dict)859        else:860            raise ValueError("invalid update mode: %r" % mode)861 862    def read_module(self, modname, mode="careful"):863        __import__(modname)864        mod = sys.modules[modname]865        self._update(vars(mod), mode)866 867    def read_file(self, filename, mode="careful"):868        vars = {}869        exec(open(filename).read(), vars)870        self._update(vars, mode)871 872    def ensure_value(self, attr, value):873        if not hasattr(self, attr) or getattr(self, attr) is None:874            setattr(self, attr, value)875        return getattr(self, attr)876 877 878class OptionContainer:879 880    """881    Abstract base class.882 883    Class attributes:884      standard_option_list : [Option]885        list of standard options that will be accepted by all instances886        of this parser class (intended to be overridden by subclasses).887 888    Instance attributes:889      option_list : [Option]890        the list of Option objects contained by this OptionContainer891      _short_opt : { string : Option }892        dictionary mapping short option strings, eg. "-f" or "-X",893        to the Option instances that implement them.  If an Option894        has multiple short option strings, it will appear in this895        dictionary multiple times. [1]896      _long_opt : { string : Option }897        dictionary mapping long option strings, eg. "--file" or898        "--exclude", to the Option instances that implement them.899        Again, a given Option can occur multiple times in this900        dictionary. [1]901      defaults : { string : any }902        dictionary mapping option destination names to default903        values for each destination [1]904 905    [1] These mappings are common to (shared by) all components of the906        controlling OptionParser, where they are initially created.907 908    """909 910    def __init__(self, option_class, conflict_handler, description):911        # Initialize the option list and related data structures.912        # This method must be provided by subclasses, and it must913        # initialize at least the following instance attributes:914        # option_list, _short_opt, _long_opt, defaults.915        self._create_option_list()916 917        self.option_class = option_class918        self.set_conflict_handler(conflict_handler)919        self.set_description(description)920 921    def _create_option_mappings(self):922        # For use by OptionParser constructor -- create the main923        # option mappings used by this OptionParser and all924        # OptionGroups that it owns.925        self._short_opt = {}            # single letter -> Option instance926        self._long_opt = {}             # long option -> Option instance927        self.defaults = {}              # maps option dest -> default value928 929 930    def _share_option_mappings(self, parser):931        # For use by OptionGroup constructor -- use shared option932        # mappings from the OptionParser that owns this OptionGroup.933        self._short_opt = parser._short_opt934        self._long_opt = parser._long_opt935        self.defaults = parser.defaults936 937    def set_conflict_handler(self, handler):938        if handler not in ("error", "resolve"):939            raise ValueError("invalid conflict_resolution value %r" % handler)940        self.conflict_handler = handler941 942    def set_description(self, description):943        self.description = description944 945    def get_description(self):946        return self.description947 948 949    def destroy(self):950        """see OptionParser.destroy()."""951        del self._short_opt952        del self._long_opt953        del self.defaults954 955 956    # -- Option-adding methods -----------------------------------------957 958    def _check_conflict(self, option):959        conflict_opts = []960        for opt in option._short_opts:961            if opt in self._short_opt:962                conflict_opts.append((opt, self._short_opt[opt]))963        for opt in option._long_opts:964            if opt in self._long_opt:965                conflict_opts.append((opt, self._long_opt[opt]))966 967        if conflict_opts:968            handler = self.conflict_handler969            if handler == "error":970                raise OptionConflictError(971                    "conflicting option string(s): %s"972                    % ", ".join([co[0] for co in conflict_opts]),973                    option)974            elif handler == "resolve":975                for (opt, c_option) in conflict_opts:976                    if opt.startswith("--"):977                        c_option._long_opts.remove(opt)978                        del self._long_opt[opt]979                    else:980                        c_option._short_opts.remove(opt)981                        del self._short_opt[opt]982                    if not (c_option._short_opts or c_option._long_opts):983                        c_option.container.option_list.remove(c_option)984 985    def add_option(self, *args, **kwargs):986        """add_option(Option)987           add_option(opt_str, ..., kwarg=val, ...)988        """989        if isinstance(args[0], str):990            option = self.option_class(*args, **kwargs)991        elif len(args) == 1 and not kwargs:992            option = args[0]993            if not isinstance(option, Option):994                raise TypeError("not an Option instance: %r" % option)995        else:996            raise TypeError("invalid arguments")997 998        self._check_conflict(option)999 1000        self.option_list.append(option)1001        option.container = self1002        for opt in option._short_opts:1003            self._short_opt[opt] = option1004        for opt in option._long_opts:1005            self._long_opt[opt] = option1006 1007        if option.dest is not None:     # option has a dest, we need a default1008            if option.default is not NO_DEFAULT:1009                self.defaults[option.dest] = option.default1010            elif option.dest not in self.defaults:1011                self.defaults[option.dest] = None1012 1013        return option1014 1015    def add_options(self, option_list):1016        for option in option_list:1017            self.add_option(option)1018 1019    # -- Option query/removal methods ----------------------------------1020 1021    def get_option(self, opt_str):1022        return (self._short_opt.get(opt_str) or1023                self._long_opt.get(opt_str))1024 1025    def has_option(self, opt_str):1026        return (opt_str in self._short_opt or1027                opt_str in self._long_opt)1028 1029    def remove_option(self, opt_str):1030        option = self._short_opt.get(opt_str)1031        if option is None:1032            option = self._long_opt.get(opt_str)1033        if option is None:1034            raise ValueError("no such option %r" % opt_str)1035 1036        for opt in option._short_opts:1037            del self._short_opt[opt]1038        for opt in option._long_opts:1039            del self._long_opt[opt]1040        option.container.option_list.remove(option)1041 1042 1043    # -- Help-formatting methods ---------------------------------------1044 1045    def format_option_help(self, formatter):1046        if not self.option_list:1047            return ""1048        result = []1049        for option in self.option_list:1050            if not option.help is SUPPRESS_HELP:1051                result.append(formatter.format_option(option))1052        return "".join(result)1053 1054    def format_description(self, formatter):1055        return formatter.format_description(self.get_description())1056 1057    def format_help(self, formatter):1058        result = []1059        if self.description:1060            result.append(self.format_description(formatter))1061        if self.option_list:1062            result.append(self.format_option_help(formatter))1063        return "\n".join(result)1064 1065 1066class OptionGroup (OptionContainer):1067 1068    def __init__(self, parser, title, description=None):1069        self.parser = parser1070        OptionContainer.__init__(1071            self, parser.option_class, parser.conflict_handler, description)1072        self.title = title1073 1074    def _create_option_list(self):1075        self.option_list = []1076        self._share_option_mappings(self.parser)1077 1078    def set_title(self, title):1079        self.title = title1080 1081    def destroy(self):1082        """see OptionParser.destroy()."""1083        OptionContainer.destroy(self)1084        del self.option_list1085 1086    # -- Help-formatting methods ---------------------------------------1087 1088    def format_help(self, formatter):1089        result = formatter.format_heading(self.title)1090        formatter.indent()1091        result += OptionContainer.format_help(self, formatter)1092        formatter.dedent()1093        return result1094 1095 1096class OptionParser (OptionContainer):1097 1098    """1099    Class attributes:1100      standard_option_list : [Option]1101        list of standard options that will be accepted by all instances1102        of this parser class (intended to be overridden by subclasses).1103 1104    Instance attributes:1105      usage : string1106        a usage string for your program.  Before it is displayed1107        to the user, "%prog" will be expanded to the name of1108        your program (self.prog or os.path.basename(sys.argv[0])).1109      prog : string1110        the name of the current program (to override1111        os.path.basename(sys.argv[0])).1112      description : string1113        A paragraph of text giving a brief overview of your program.1114        optparse reformats this paragraph to fit the current terminal1115        width and prints it when the user requests help (after usage,1116        but before the list of options).1117      epilog : string1118        paragraph of help text to print after option help1119 1120      option_groups : [OptionGroup]1121        list of option groups in this parser (option groups are1122        irrelevant for parsing the command-line, but very useful1123        for generating help)1124 1125      allow_interspersed_args : bool = true1126        if true, positional arguments may be interspersed with options.1127        Assuming -a and -b each take a single argument, the command-line1128          -ablah foo bar -bboo baz1129        will be interpreted the same as1130          -ablah -bboo -- foo bar baz1131        If this flag were false, that command line would be interpreted as1132          -ablah -- foo bar -bboo baz1133        -- ie. we stop processing options as soon as we see the first1134        non-option argument.  (This is the tradition followed by1135        Python's getopt module, Perl's Getopt::Std, and other argument-1136        parsing libraries, but it is generally annoying to users.)1137 1138      process_default_values : bool = true1139        if true, option default values are processed similarly to option1140        values from the command line: that is, they are passed to the1141        type-checking function for the option's type (as long as the1142        default value is a string).  (This really only matters if you1143        have defined custom types; see SF bug #955889.)  Set it to false1144        to restore the behaviour of Optik 1.4.1 and earlier.1145 1146      rargs : [string]1147        the argument list currently being parsed.  Only set when1148        parse_args() is active, and continually trimmed down as1149        we consume arguments.  Mainly there for the benefit of1150        callback options.1151      largs : [string]1152        the list of leftover arguments that we have skipped while1153        parsing options.  If allow_interspersed_args is false, this1154        list is always empty.1155      values : Values1156        the set of option values currently being accumulated.  Only1157        set when parse_args() is active.  Also mainly for callbacks.1158 1159    Because of the 'rargs', 'largs', and 'values' attributes,1160    OptionParser is not thread-safe.  If, for some perverse reason, you1161    need to parse command-line arguments simultaneously in different1162    threads, use different OptionParser instances.1163 1164    """1165 1166    standard_option_list = []1167 1168    def __init__(self,1169                 usage=None,1170                 option_list=None,1171                 option_class=Option,1172                 version=None,1173                 conflict_handler="error",1174                 description=None,1175                 formatter=None,1176                 add_help_option=True,1177                 prog=None,1178                 epilog=None):1179        OptionContainer.__init__(1180            self, option_class, conflict_handler, description)1181        self.set_usage(usage)1182        self.prog = prog1183        self.version = version1184        self.allow_interspersed_args = True1185        self.process_default_values = True1186        if formatter is None:1187            formatter = IndentedHelpFormatter()1188        self.formatter = formatter1189        self.formatter.set_parser(self)1190        self.epilog = epilog1191 1192        # Populate the option list; initial sources are the1193        # standard_option_list class attribute, the 'option_list'1194        # argument, and (if applicable) the _add_version_option() and1195        # _add_help_option() methods.1196        self._populate_option_list(option_list,1197                                   add_help=add_help_option)1198 1199        self._init_parsing_state()1200 

Showing the first 1,200 of 1672 lines. Download the file for the rest.

codekingpro/portable-devtools · Team Ai