From nobody Mon Apr 29 10:22:49 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1528481919951655.2598022861432; Fri, 8 Jun 2018 11:18:39 -0700 (PDT) Received: from localhost ([::1]:37508 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fRLyB-0001Mq-1U for importer@patchew.org; Fri, 08 Jun 2018 14:18:39 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49395) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fRLaZ-0007Xc-3Z for qemu-devel@nongnu.org; Fri, 08 Jun 2018 13:54:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fRLaS-0003dw-8Q for qemu-devel@nongnu.org; Fri, 08 Jun 2018 13:54:15 -0400 Received: from mx1.redhat.com ([209.132.183.28]:55464) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fRLaR-0003dd-QG for qemu-devel@nongnu.org; Fri, 08 Jun 2018 13:54:08 -0400 Received: from smtp.corp.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 06E36308213E; Fri, 8 Jun 2018 17:54:07 +0000 (UTC) Received: from localhost (ovpn-116-19.gru2.redhat.com [10.97.116.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 91F0B931E8; Fri, 8 Jun 2018 17:54:03 +0000 (UTC) From: Eduardo Habkost To: qemu-devel@nongnu.org Date: Fri, 8 Jun 2018 14:52:51 -0300 Message-Id: <20180608175252.25110-2-ehabkost@redhat.com> In-Reply-To: <20180608175252.25110-1-ehabkost@redhat.com> References: <20180608175252.25110-1-ehabkost@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.42]); Fri, 08 Jun 2018 17:54:07 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v2 1/2] python: Remove scripts/argparse.py X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Stefan Hajnoczi , Cleber Rosa Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Python 2.7 (the minimum Python version we require) already provides the argparse module on the standard library. Signed-off-by: Eduardo Habkost Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- scripts/argparse.py | 2406 ------------------------------------------- 1 file changed, 2406 deletions(-) delete mode 100644 scripts/argparse.py diff --git a/scripts/argparse.py b/scripts/argparse.py deleted file mode 100644 index 27d1f28935..0000000000 --- a/scripts/argparse.py +++ /dev/null @@ -1,2406 +0,0 @@ -# This is a local copy of the standard library argparse module taken from = PyPI. -# It is licensed under the Python Software Foundation License. This is a -# fallback for Python 2.6 which does not include this module. Python 2.7+= and -# 3+ will never load this module because built-in modules are loaded before -# anything in sys.path. -# -# If your script is not located in the same directory as this file, import= it -# like this: -# -# import os -# import sys -# sys.path.append(os.path.join(os.path.dirname(__file__), ..., 'scripts'= )) -# import argparse - -# Author: Steven J. Bethard . -# Maintainer: Thomas Waldmann - -"""Command-line parsing library - -This module is an optparse-inspired command-line parsing library that: - - - handles both optional and positional arguments - - produces highly informative usage messages - - supports parsers that dispatch to sub-parsers - -The following is a simple usage example that sums integers from the -command-line and writes the result to a file:: - - parser =3D argparse.ArgumentParser( - description=3D'sum the integers at the command line') - parser.add_argument( - 'integers', metavar=3D'int', nargs=3D'+', type=3Dint, - help=3D'an integer to be summed') - parser.add_argument( - '--log', default=3Dsys.stdout, type=3Dargparse.FileType('w'), - help=3D'the file where the sum should be written') - args =3D parser.parse_args() - args.log.write('%s' % sum(args.integers)) - args.log.close() - -The module contains the following public classes: - - - ArgumentParser -- The main entry point for command-line parsing. As = the - example above shows, the add_argument() method is used to populate - the parser with actions for optional and positional arguments. Then - the parse_args() method is invoked to convert the args at the - command-line into an object with attributes. - - - ArgumentError -- The exception raised by ArgumentParser objects when - there are errors with the parser's actions. Errors raised while - parsing the command-line are caught by ArgumentParser and emitted - as command-line messages. - - - FileType -- A factory for defining types of files to be created. As = the - example above shows, instances of FileType are typically passed as - the type=3D argument of add_argument() calls. - - - Action -- The base class for parser actions. Typically actions are - selected by passing strings like 'store_true' or 'append_const' to - the action=3D argument of add_argument(). However, for greater - customization of ArgumentParser actions, subclasses of Action may - be defined and passed as the action=3D argument. - - - HelpFormatter, RawDescriptionHelpFormatter, RawTextHelpFormatter, - ArgumentDefaultsHelpFormatter -- Formatter classes which - may be passed as the formatter_class=3D argument to the - ArgumentParser constructor. HelpFormatter is the default, - RawDescriptionHelpFormatter and RawTextHelpFormatter tell the pars= er - not to change the formatting for help text, and - ArgumentDefaultsHelpFormatter adds information about argument defa= ults - to the help. - -All other classes in this module are considered implementation details. -(Also note that HelpFormatter and RawDescriptionHelpFormatter are only -considered public as object names -- the API of the formatter objects is -still considered an implementation detail.) -""" - -__version__ =3D '1.4.0' # we use our own version number independent of the - # one in stdlib and we release this on pypi. - -__external_lib__ =3D True # to make sure the tests really test THIS lib, - # not the builtin one in Python stdlib - -__all__ =3D [ - 'ArgumentParser', - 'ArgumentError', - 'ArgumentTypeError', - 'FileType', - 'HelpFormatter', - 'ArgumentDefaultsHelpFormatter', - 'RawDescriptionHelpFormatter', - 'RawTextHelpFormatter', - 'Namespace', - 'Action', - 'ONE_OR_MORE', - 'OPTIONAL', - 'PARSER', - 'REMAINDER', - 'SUPPRESS', - 'ZERO_OR_MORE', -] - - -import copy as _copy -import os as _os -import re as _re -import sys as _sys -import textwrap as _textwrap - -from gettext import gettext as _ - -try: - set -except NameError: - # for python < 2.4 compatibility (sets module is there since 2.3): - from sets import Set as set - -try: - basestring -except NameError: - basestring =3D str - -try: - sorted -except NameError: - # for python < 2.4 compatibility: - def sorted(iterable, reverse=3DFalse): - result =3D list(iterable) - result.sort() - if reverse: - result.reverse() - return result - - -def _callable(obj): - return hasattr(obj, '__call__') or hasattr(obj, '__bases__') - - -SUPPRESS =3D '=3D=3DSUPPRESS=3D=3D' - -OPTIONAL =3D '?' -ZERO_OR_MORE =3D '*' -ONE_OR_MORE =3D '+' -PARSER =3D 'A...' -REMAINDER =3D '...' -_UNRECOGNIZED_ARGS_ATTR =3D '_unrecognized_args' - -# =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D -# Utility functions and classes -# =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D - -class _AttributeHolder(object): - """Abstract base class that provides __repr__. - - The __repr__ method returns a string in the format:: - ClassName(attr=3Dname, attr=3Dname, ...) - The attributes are determined either by a class-level attribute, - '_kwarg_names', or by inspecting the instance __dict__. - """ - - def __repr__(self): - type_name =3D type(self).__name__ - arg_strings =3D [] - for arg in self._get_args(): - arg_strings.append(repr(arg)) - for name, value in self._get_kwargs(): - arg_strings.append('%s=3D%r' % (name, value)) - return '%s(%s)' % (type_name, ', '.join(arg_strings)) - - def _get_kwargs(self): - return sorted(self.__dict__.items()) - - def _get_args(self): - return [] - - -def _ensure_value(namespace, name, value): - if getattr(namespace, name, None) is None: - setattr(namespace, name, value) - return getattr(namespace, name) - - -# =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -# Formatting Help -# =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -class HelpFormatter(object): - """Formatter for generating usage messages and argument help strings. - - Only the name of this class is considered a public API. All the methods - provided by the class are considered an implementation detail. - """ - - def __init__(self, - prog, - indent_increment=3D2, - max_help_position=3D24, - width=3DNone): - - # default setting for width - if width is None: - try: - width =3D int(_os.environ['COLUMNS']) - except (KeyError, ValueError): - width =3D 80 - width -=3D 2 - - self._prog =3D prog - self._indent_increment =3D indent_increment - self._max_help_position =3D max_help_position - self._width =3D width - - self._current_indent =3D 0 - self._level =3D 0 - self._action_max_length =3D 0 - - self._root_section =3D self._Section(self, None) - self._current_section =3D self._root_section - - self._whitespace_matcher =3D _re.compile(r'\s+') - self._long_break_matcher =3D _re.compile(r'\n\n\n+') - - # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D - # Section and indentation methods - # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D - def _indent(self): - self._current_indent +=3D self._indent_increment - self._level +=3D 1 - - def _dedent(self): - self._current_indent -=3D self._indent_increment - assert self._current_indent >=3D 0, 'Indent decreased below 0.' - self._level -=3D 1 - - class _Section(object): - - def __init__(self, formatter, parent, heading=3DNone): - self.formatter =3D formatter - self.parent =3D parent - self.heading =3D heading - self.items =3D [] - - def format_help(self): - # format the indented section - if self.parent is not None: - self.formatter._indent() - join =3D self.formatter._join_parts - for func, args in self.items: - func(*args) - item_help =3D join([func(*args) for func, args in self.items]) - if self.parent is not None: - self.formatter._dedent() - - # return nothing if the section was empty - if not item_help: - return '' - - # add the heading if the section was non-empty - if self.heading is not SUPPRESS and self.heading is not None: - current_indent =3D self.formatter._current_indent - heading =3D '%*s%s:\n' % (current_indent, '', self.heading) - else: - heading =3D '' - - # join the section-initial newline, the heading and the help - return join(['\n', heading, item_help, '\n']) - - def _add_item(self, func, args): - self._current_section.items.append((func, args)) - - # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D - # Message building methods - # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D - def start_section(self, heading): - self._indent() - section =3D self._Section(self, self._current_section, heading) - self._add_item(section.format_help, []) - self._current_section =3D section - - def end_section(self): - self._current_section =3D self._current_section.parent - self._dedent() - - def add_text(self, text): - if text is not SUPPRESS and text is not None: - self._add_item(self._format_text, [text]) - - def add_usage(self, usage, actions, groups, prefix=3DNone): - if usage is not SUPPRESS: - args =3D usage, actions, groups, prefix - self._add_item(self._format_usage, args) - - def add_argument(self, action): - if action.help is not SUPPRESS: - - # find all invocations - get_invocation =3D self._format_action_invocation - invocations =3D [get_invocation(action)] - for subaction in self._iter_indented_subactions(action): - invocations.append(get_invocation(subaction)) - - # update the maximum item length - invocation_length =3D max([len(s) for s in invocations]) - action_length =3D invocation_length + self._current_indent - self._action_max_length =3D max(self._action_max_length, - action_length) - - # add the item to the list - self._add_item(self._format_action, [action]) - - def add_arguments(self, actions): - for action in actions: - self.add_argument(action) - - # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D - # Help-formatting methods - # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D - def format_help(self): - help =3D self._root_section.format_help() - if help: - help =3D self._long_break_matcher.sub('\n\n', help) - help =3D help.strip('\n') + '\n' - return help - - def _join_parts(self, part_strings): - return ''.join([part - for part in part_strings - if part and part is not SUPPRESS]) - - def _format_usage(self, usage, actions, groups, prefix): - if prefix is None: - prefix =3D _('usage: ') - - # if usage is specified, use that - if usage is not None: - usage =3D usage % dict(prog=3Dself._prog) - - # if no optionals or positionals are available, usage is just prog - elif usage is None and not actions: - usage =3D '%(prog)s' % dict(prog=3Dself._prog) - - # if optionals and positionals are available, calculate usage - elif usage is None: - prog =3D '%(prog)s' % dict(prog=3Dself._prog) - - # split optionals from positionals - optionals =3D [] - positionals =3D [] - for action in actions: - if action.option_strings: - optionals.append(action) - else: - positionals.append(action) - - # build full usage string - format =3D self._format_actions_usage - action_usage =3D format(optionals + positionals, groups) - usage =3D ' '.join([s for s in [prog, action_usage] if s]) - - # wrap the usage parts if it's too long - text_width =3D self._width - self._current_indent - if len(prefix) + len(usage) > text_width: - - # break usage into wrappable parts - part_regexp =3D r'\(.*?\)+|\[.*?\]+|\S+' - opt_usage =3D format(optionals, groups) - pos_usage =3D format(positionals, groups) - opt_parts =3D _re.findall(part_regexp, opt_usage) - pos_parts =3D _re.findall(part_regexp, pos_usage) - assert ' '.join(opt_parts) =3D=3D opt_usage - assert ' '.join(pos_parts) =3D=3D pos_usage - - # helper for wrapping lines - def get_lines(parts, indent, prefix=3DNone): - lines =3D [] - line =3D [] - if prefix is not None: - line_len =3D len(prefix) - 1 - else: - line_len =3D len(indent) - 1 - for part in parts: - if line_len + 1 + len(part) > text_width: - lines.append(indent + ' '.join(line)) - line =3D [] - line_len =3D len(indent) - 1 - line.append(part) - line_len +=3D len(part) + 1 - if line: - lines.append(indent + ' '.join(line)) - if prefix is not None: - lines[0] =3D lines[0][len(indent):] - return lines - - # if prog is short, follow it with optionals or positionals - if len(prefix) + len(prog) <=3D 0.75 * text_width: - indent =3D ' ' * (len(prefix) + len(prog) + 1) - if opt_parts: - lines =3D get_lines([prog] + opt_parts, indent, pr= efix) - lines.extend(get_lines(pos_parts, indent)) - elif pos_parts: - lines =3D get_lines([prog] + pos_parts, indent, pr= efix) - else: - lines =3D [prog] - - # if prog is long, put it on its own line - else: - indent =3D ' ' * len(prefix) - parts =3D opt_parts + pos_parts - lines =3D get_lines(parts, indent) - if len(lines) > 1: - lines =3D [] - lines.extend(get_lines(opt_parts, indent)) - lines.extend(get_lines(pos_parts, indent)) - lines =3D [prog] + lines - - # join lines into usage - usage =3D '\n'.join(lines) - - # prefix with 'usage:' - return '%s%s\n\n' % (prefix, usage) - - def _format_actions_usage(self, actions, groups): - # find group indices and identify actions in groups - group_actions =3D set() - inserts =3D {} - for group in groups: - try: - start =3D actions.index(group._group_actions[0]) - except ValueError: - continue - else: - end =3D start + len(group._group_actions) - if actions[start:end] =3D=3D group._group_actions: - for action in group._group_actions: - group_actions.add(action) - if not group.required: - if start in inserts: - inserts[start] +=3D ' [' - else: - inserts[start] =3D '[' - inserts[end] =3D ']' - else: - if start in inserts: - inserts[start] +=3D ' (' - else: - inserts[start] =3D '(' - inserts[end] =3D ')' - for i in range(start + 1, end): - inserts[i] =3D '|' - - # collect all actions format strings - parts =3D [] - for i, action in enumerate(actions): - - # suppressed arguments are marked with None - # remove | separators for suppressed arguments - if action.help is SUPPRESS: - parts.append(None) - if inserts.get(i) =3D=3D '|': - inserts.pop(i) - elif inserts.get(i + 1) =3D=3D '|': - inserts.pop(i + 1) - - # produce all arg strings - elif not action.option_strings: - part =3D self._format_args(action, action.dest) - - # if it's in a group, strip the outer [] - if action in group_actions: - if part[0] =3D=3D '[' and part[-1] =3D=3D ']': - part =3D part[1:-1] - - # add the action string to the list - parts.append(part) - - # produce the first way to invoke the option in brackets - else: - option_string =3D action.option_strings[0] - - # if the Optional doesn't take a value, format is: - # -s or --long - if action.nargs =3D=3D 0: - part =3D '%s' % option_string - - # if the Optional takes a value, format is: - # -s ARGS or --long ARGS - else: - default =3D action.dest.upper() - args_string =3D self._format_args(action, default) - part =3D '%s %s' % (option_string, args_string) - - # make it look optional if it's not required or in a group - if not action.required and action not in group_actions: - part =3D '[%s]' % part - - # add the action string to the list - parts.append(part) - - # insert things at the necessary indices - for i in sorted(inserts, reverse=3DTrue): - parts[i:i] =3D [inserts[i]] - - # join all the action items with spaces - text =3D ' '.join([item for item in parts if item is not None]) - - # clean up separators for mutually exclusive groups - open =3D r'[\[(]' - close =3D r'[\])]' - text =3D _re.sub(r'(%s) ' % open, r'\1', text) - text =3D _re.sub(r' (%s)' % close, r'\1', text) - text =3D _re.sub(r'%s *%s' % (open, close), r'', text) - text =3D _re.sub(r'\(([^|]*)\)', r'\1', text) - text =3D text.strip() - - # return the text - return text - - def _format_text(self, text): - if '%(prog)' in text: - text =3D text % dict(prog=3Dself._prog) - text_width =3D self._width - self._current_indent - indent =3D ' ' * self._current_indent - return self._fill_text(text, text_width, indent) + '\n\n' - - def _format_action(self, action): - # determine the required width and the entry label - help_position =3D min(self._action_max_length + 2, - self._max_help_position) - help_width =3D self._width - help_position - action_width =3D help_position - self._current_indent - 2 - action_header =3D self._format_action_invocation(action) - - # ho nelp; start on same line and add a final newline - if not action.help: - tup =3D self._current_indent, '', action_header - action_header =3D '%*s%s\n' % tup - - # short action name; start on the same line and pad two spaces - elif len(action_header) <=3D action_width: - tup =3D self._current_indent, '', action_width, action_header - action_header =3D '%*s%-*s ' % tup - indent_first =3D 0 - - # long action name; start on the next line - else: - tup =3D self._current_indent, '', action_header - action_header =3D '%*s%s\n' % tup - indent_first =3D help_position - - # collect the pieces of the action help - parts =3D [action_header] - - # if there was help for the action, add lines of help text - if action.help: - help_text =3D self._expand_help(action) - help_lines =3D self._split_lines(help_text, help_width) - parts.append('%*s%s\n' % (indent_first, '', help_lines[0])) - for line in help_lines[1:]: - parts.append('%*s%s\n' % (help_position, '', line)) - - # or add a newline if the description doesn't end with one - elif not action_header.endswith('\n'): - parts.append('\n') - - # if there are any sub-actions, add their help as well - for subaction in self._iter_indented_subactions(action): - parts.append(self._format_action(subaction)) - - # return a single string - return self._join_parts(parts) - - def _format_action_invocation(self, action): - if not action.option_strings: - metavar, =3D self._metavar_formatter(action, action.dest)(1) - return metavar - - else: - parts =3D [] - - # if the Optional doesn't take a value, format is: - # -s, --long - if action.nargs =3D=3D 0: - parts.extend(action.option_strings) - - # if the Optional takes a value, format is: - # -s ARGS, --long ARGS - else: - default =3D action.dest.upper() - args_string =3D self._format_args(action, default) - for option_string in action.option_strings: - parts.append('%s %s' % (option_string, args_string)) - - return ', '.join(parts) - - def _metavar_formatter(self, action, default_metavar): - if action.metavar is not None: - result =3D action.metavar - elif action.choices is not None: - choice_strs =3D [str(choice) for choice in action.choices] - result =3D '{%s}' % ','.join(choice_strs) - else: - result =3D default_metavar - - def format(tuple_size): - if isinstance(result, tuple): - return result - else: - return (result, ) * tuple_size - return format - - def _format_args(self, action, default_metavar): - get_metavar =3D self._metavar_formatter(action, default_metavar) - if action.nargs is None: - result =3D '%s' % get_metavar(1) - elif action.nargs =3D=3D OPTIONAL: - result =3D '[%s]' % get_metavar(1) - elif action.nargs =3D=3D ZERO_OR_MORE: - result =3D '[%s [%s ...]]' % get_metavar(2) - elif action.nargs =3D=3D ONE_OR_MORE: - result =3D '%s [%s ...]' % get_metavar(2) - elif action.nargs =3D=3D REMAINDER: - result =3D '...' - elif action.nargs =3D=3D PARSER: - result =3D '%s ...' % get_metavar(1) - else: - formats =3D ['%s' for _ in range(action.nargs)] - result =3D ' '.join(formats) % get_metavar(action.nargs) - return result - - def _expand_help(self, action): - params =3D dict(vars(action), prog=3Dself._prog) - for name in list(params): - if params[name] is SUPPRESS: - del params[name] - for name in list(params): - if hasattr(params[name], '__name__'): - params[name] =3D params[name].__name__ - if params.get('choices') is not None: - choices_str =3D ', '.join([str(c) for c in params['choices']]) - params['choices'] =3D choices_str - return self._get_help_string(action) % params - - def _iter_indented_subactions(self, action): - try: - get_subactions =3D action._get_subactions - except AttributeError: - pass - else: - self._indent() - for subaction in get_subactions(): - yield subaction - self._dedent() - - def _split_lines(self, text, width): - text =3D self._whitespace_matcher.sub(' ', text).strip() - return _textwrap.wrap(text, width) - - def _fill_text(self, text, width, indent): - text =3D self._whitespace_matcher.sub(' ', text).strip() - return _textwrap.fill(text, width, initial_indent=3Dindent, - subsequent_indent=3Dindent) - - def _get_help_string(self, action): - return action.help - - -class RawDescriptionHelpFormatter(HelpFormatter): - """Help message formatter which retains any formatting in descriptions. - - Only the name of this class is considered a public API. All the methods - provided by the class are considered an implementation detail. - """ - - def _fill_text(self, text, width, indent): - return ''.join([indent + line for line in text.splitlines(True)]) - - -class RawTextHelpFormatter(RawDescriptionHelpFormatter): - """Help message formatter which retains formatting of all help text. - - Only the name of this class is considered a public API. All the methods - provided by the class are considered an implementation detail. - """ - - def _split_lines(self, text, width): - return text.splitlines() - - -class ArgumentDefaultsHelpFormatter(HelpFormatter): - """Help message formatter which adds default values to argument help. - - Only the name of this class is considered a public API. All the methods - provided by the class are considered an implementation detail. - """ - - def _get_help_string(self, action): - help =3D action.help - if '%(default)' not in action.help: - if action.default is not SUPPRESS: - defaulting_nargs =3D [OPTIONAL, ZERO_OR_MORE] - if action.option_strings or action.nargs in defaulting_nar= gs: - help +=3D ' (default: %(default)s)' - return help - - -# =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -# Options and Arguments -# =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -def _get_action_name(argument): - if argument is None: - return None - elif argument.option_strings: - return '/'.join(argument.option_strings) - elif argument.metavar not in (None, SUPPRESS): - return argument.metavar - elif argument.dest not in (None, SUPPRESS): - return argument.dest - else: - return None - - -class ArgumentError(Exception): - """An error from creating or using an argument (optional or positional= ). - - The string value of this exception is the message, augmented with - information about the argument that caused it. - """ - - def __init__(self, argument, message): - self.argument_name =3D _get_action_name(argument) - self.message =3D message - - def __str__(self): - if self.argument_name is None: - format =3D '%(message)s' - else: - format =3D 'argument %(argument_name)s: %(message)s' - return format % dict(message=3Dself.message, - argument_name=3Dself.argument_name) - - -class ArgumentTypeError(Exception): - """An error from trying to convert a command line string to a type.""" - pass - - -# =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -# Action classes -# =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -class Action(_AttributeHolder): - """Information about how to convert command line strings to Python obj= ects. - - Action objects are used by an ArgumentParser to represent the informat= ion - needed to parse a single argument from one or more strings from the - command line. The keyword arguments to the Action constructor are also - all attributes of Action instances. - - Keyword Arguments: - - - option_strings -- A list of command-line option strings which - should be associated with this action. - - - dest -- The name of the attribute to hold the created object(s) - - - nargs -- The number of command-line arguments that should be - consumed. By default, one argument will be consumed and a sing= le - value will be produced. Other values include: - - N (an integer) consumes N arguments (and produces a list) - - '?' consumes zero or one arguments - - '*' consumes zero or more arguments (and produces a list) - - '+' consumes one or more arguments (and produces a list) - Note that the difference between the default and nargs=3D1 is = that - with the default, a single value will be produced, while with - nargs=3D1, a list containing a single value will be produced. - - - const -- The value to be produced if the option is specified and= the - option uses an action that takes no values. - - - default -- The value to be produced if the option is not specifi= ed. - - - type -- The type which the command-line arguments should be conv= erted - to, should be one of 'string', 'int', 'float', 'complex' or a - callable object that accepts a single string argument. If None, - 'string' is assumed. - - - choices -- A container of values that should be allowed. If not = None, - after a command-line argument has been converted to the approp= riate - type, an exception will be raised if it is not a member of this - collection. - - - required -- True if the action must always be specified at the - command line. This is only meaningful for optional command-line - arguments. - - - help -- The help string describing the argument. - - - metavar -- The name to be used for the option's argument with the - help string. If None, the 'dest' value will be used as the nam= e. - """ - - def __init__(self, - option_strings, - dest, - nargs=3DNone, - const=3DNone, - default=3DNone, - type=3DNone, - choices=3DNone, - required=3DFalse, - help=3DNone, - metavar=3DNone): - self.option_strings =3D option_strings - self.dest =3D dest - self.nargs =3D nargs - self.const =3D const - self.default =3D default - self.type =3D type - self.choices =3D choices - self.required =3D required - self.help =3D help - self.metavar =3D metavar - - def _get_kwargs(self): - names =3D [ - 'option_strings', - 'dest', - 'nargs', - 'const', - 'default', - 'type', - 'choices', - 'help', - 'metavar', - ] - return [(name, getattr(self, name)) for name in names] - - def __call__(self, parser, namespace, values, option_string=3DNone): - raise NotImplementedError(_('.__call__() not defined')) - - -class _StoreAction(Action): - - def __init__(self, - option_strings, - dest, - nargs=3DNone, - const=3DNone, - default=3DNone, - type=3DNone, - choices=3DNone, - required=3DFalse, - help=3DNone, - metavar=3DNone): - if nargs =3D=3D 0: - raise ValueError('nargs for store actions must be > 0; if you ' - 'have nothing to store, actions such as store= ' - 'true or store const may be more appropriate') - if const is not None and nargs !=3D OPTIONAL: - raise ValueError('nargs must be %r to supply const' % OPTIONAL) - super(_StoreAction, self).__init__( - option_strings=3Doption_strings, - dest=3Ddest, - nargs=3Dnargs, - const=3Dconst, - default=3Ddefault, - type=3Dtype, - choices=3Dchoices, - required=3Drequired, - help=3Dhelp, - metavar=3Dmetavar) - - def __call__(self, parser, namespace, values, option_string=3DNone): - setattr(namespace, self.dest, values) - - -class _StoreConstAction(Action): - - def __init__(self, - option_strings, - dest, - const, - default=3DNone, - required=3DFalse, - help=3DNone, - metavar=3DNone): - super(_StoreConstAction, self).__init__( - option_strings=3Doption_strings, - dest=3Ddest, - nargs=3D0, - const=3Dconst, - default=3Ddefault, - required=3Drequired, - help=3Dhelp) - - def __call__(self, parser, namespace, values, option_string=3DNone): - setattr(namespace, self.dest, self.const) - - -class _StoreTrueAction(_StoreConstAction): - - def __init__(self, - option_strings, - dest, - default=3DFalse, - required=3DFalse, - help=3DNone): - super(_StoreTrueAction, self).__init__( - option_strings=3Doption_strings, - dest=3Ddest, - const=3DTrue, - default=3Ddefault, - required=3Drequired, - help=3Dhelp) - - -class _StoreFalseAction(_StoreConstAction): - - def __init__(self, - option_strings, - dest, - default=3DTrue, - required=3DFalse, - help=3DNone): - super(_StoreFalseAction, self).__init__( - option_strings=3Doption_strings, - dest=3Ddest, - const=3DFalse, - default=3Ddefault, - required=3Drequired, - help=3Dhelp) - - -class _AppendAction(Action): - - def __init__(self, - option_strings, - dest, - nargs=3DNone, - const=3DNone, - default=3DNone, - type=3DNone, - choices=3DNone, - required=3DFalse, - help=3DNone, - metavar=3DNone): - if nargs =3D=3D 0: - raise ValueError('nargs for append actions must be > 0; if arg= ' - 'strings are not supplying the value to appen= d, ' - 'the append const action may be more appropri= ate') - if const is not None and nargs !=3D OPTIONAL: - raise ValueError('nargs must be %r to supply const' % OPTIONAL) - super(_AppendAction, self).__init__( - option_strings=3Doption_strings, - dest=3Ddest, - nargs=3Dnargs, - const=3Dconst, - default=3Ddefault, - type=3Dtype, - choices=3Dchoices, - required=3Drequired, - help=3Dhelp, - metavar=3Dmetavar) - - def __call__(self, parser, namespace, values, option_string=3DNone): - items =3D _copy.copy(_ensure_value(namespace, self.dest, [])) - items.append(values) - setattr(namespace, self.dest, items) - - -class _AppendConstAction(Action): - - def __init__(self, - option_strings, - dest, - const, - default=3DNone, - required=3DFalse, - help=3DNone, - metavar=3DNone): - super(_AppendConstAction, self).__init__( - option_strings=3Doption_strings, - dest=3Ddest, - nargs=3D0, - const=3Dconst, - default=3Ddefault, - required=3Drequired, - help=3Dhelp, - metavar=3Dmetavar) - - def __call__(self, parser, namespace, values, option_string=3DNone): - items =3D _copy.copy(_ensure_value(namespace, self.dest, [])) - items.append(self.const) - setattr(namespace, self.dest, items) - - -class _CountAction(Action): - - def __init__(self, - option_strings, - dest, - default=3DNone, - required=3DFalse, - help=3DNone): - super(_CountAction, self).__init__( - option_strings=3Doption_strings, - dest=3Ddest, - nargs=3D0, - default=3Ddefault, - required=3Drequired, - help=3Dhelp) - - def __call__(self, parser, namespace, values, option_string=3DNone): - new_count =3D _ensure_value(namespace, self.dest, 0) + 1 - setattr(namespace, self.dest, new_count) - - -class _HelpAction(Action): - - def __init__(self, - option_strings, - dest=3DSUPPRESS, - default=3DSUPPRESS, - help=3DNone): - super(_HelpAction, self).__init__( - option_strings=3Doption_strings, - dest=3Ddest, - default=3Ddefault, - nargs=3D0, - help=3Dhelp) - - def __call__(self, parser, namespace, values, option_string=3DNone): - parser.print_help() - parser.exit() - - -class _VersionAction(Action): - - def __init__(self, - option_strings, - version=3DNone, - dest=3DSUPPRESS, - default=3DSUPPRESS, - help=3D"show program's version number and exit"): - super(_VersionAction, self).__init__( - option_strings=3Doption_strings, - dest=3Ddest, - default=3Ddefault, - nargs=3D0, - help=3Dhelp) - self.version =3D version - - def __call__(self, parser, namespace, values, option_string=3DNone): - version =3D self.version - if version is None: - version =3D parser.version - formatter =3D parser._get_formatter() - formatter.add_text(version) - parser.exit(message=3Dformatter.format_help()) - - -class _SubParsersAction(Action): - - class _ChoicesPseudoAction(Action): - - def __init__(self, name, aliases, help): - metavar =3D dest =3D name - if aliases: - metavar +=3D ' (%s)' % ', '.join(aliases) - sup =3D super(_SubParsersAction._ChoicesPseudoAction, self) - sup.__init__(option_strings=3D[], dest=3Ddest, help=3Dhelp, - metavar=3Dmetavar) - - def __init__(self, - option_strings, - prog, - parser_class, - dest=3DSUPPRESS, - help=3DNone, - metavar=3DNone): - - self._prog_prefix =3D prog - self._parser_class =3D parser_class - self._name_parser_map =3D {} - self._choices_actions =3D [] - - super(_SubParsersAction, self).__init__( - option_strings=3Doption_strings, - dest=3Ddest, - nargs=3DPARSER, - choices=3Dself._name_parser_map, - help=3Dhelp, - metavar=3Dmetavar) - - def add_parser(self, name, **kwargs): - # set prog from the existing prefix - if kwargs.get('prog') is None: - kwargs['prog'] =3D '%s %s' % (self._prog_prefix, name) - - aliases =3D kwargs.pop('aliases', ()) - - # create a pseudo-action to hold the choice help - if 'help' in kwargs: - help =3D kwargs.pop('help') - choice_action =3D self._ChoicesPseudoAction(name, aliases, hel= p) - self._choices_actions.append(choice_action) - - # create the parser and add it to the map - parser =3D self._parser_class(**kwargs) - self._name_parser_map[name] =3D parser - - # make parser available under aliases also - for alias in aliases: - self._name_parser_map[alias] =3D parser - - return parser - - def _get_subactions(self): - return self._choices_actions - - def __call__(self, parser, namespace, values, option_string=3DNone): - parser_name =3D values[0] - arg_strings =3D values[1:] - - # set the parser name if requested - if self.dest is not SUPPRESS: - setattr(namespace, self.dest, parser_name) - - # select the parser - try: - parser =3D self._name_parser_map[parser_name] - except KeyError: - tup =3D parser_name, ', '.join(self._name_parser_map) - msg =3D _('unknown parser %r (choices: %s)' % tup) - raise ArgumentError(self, msg) - - # parse all the remaining options into the namespace - # store any unrecognized options on the object, so that the top - # level parser can decide what to do with them - namespace, arg_strings =3D parser.parse_known_args(arg_strings, na= mespace) - if arg_strings: - vars(namespace).setdefault(_UNRECOGNIZED_ARGS_ATTR, []) - getattr(namespace, _UNRECOGNIZED_ARGS_ATTR).extend(arg_strings) - - -# =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -# Type classes -# =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -class FileType(object): - """Factory for creating file object types - - Instances of FileType are typically passed as type=3D arguments to the - ArgumentParser add_argument() method. - - Keyword Arguments: - - mode -- A string indicating how the file is to be opened. Accept= s the - same values as the builtin open() function. - - bufsize -- The file's desired buffer size. Accepts the same valu= es as - the builtin open() function. - """ - - def __init__(self, mode=3D'r', bufsize=3DNone): - self._mode =3D mode - self._bufsize =3D bufsize - - def __call__(self, string): - # the special argument "-" means sys.std{in,out} - if string =3D=3D '-': - if 'r' in self._mode: - return _sys.stdin - elif 'w' in self._mode: - return _sys.stdout - else: - msg =3D _('argument "-" with mode %r' % self._mode) - raise ValueError(msg) - - try: - # all other arguments are used as file names - if self._bufsize: - return open(string, self._mode, self._bufsize) - else: - return open(string, self._mode) - except IOError: - err =3D _sys.exc_info()[1] - message =3D _("can't open '%s': %s") - raise ArgumentTypeError(message % (string, err)) - - def __repr__(self): - args =3D [self._mode, self._bufsize] - args_str =3D ', '.join([repr(arg) for arg in args if arg is not No= ne]) - return '%s(%s)' % (type(self).__name__, args_str) - -# =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D -# Optional and Positional Parsing -# =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D - -class Namespace(_AttributeHolder): - """Simple object for storing attributes. - - Implements equality by attribute names and values, and provides a simp= le - string representation. - """ - - def __init__(self, **kwargs): - for name in kwargs: - setattr(self, name, kwargs[name]) - - __hash__ =3D None - - def __eq__(self, other): - return vars(self) =3D=3D vars(other) - - def __ne__(self, other): - return not (self =3D=3D other) - - def __contains__(self, key): - return key in self.__dict__ - - -class _ActionsContainer(object): - - def __init__(self, - description, - prefix_chars, - argument_default, - conflict_handler): - super(_ActionsContainer, self).__init__() - - self.description =3D description - self.argument_default =3D argument_default - self.prefix_chars =3D prefix_chars - self.conflict_handler =3D conflict_handler - - # set up registries - self._registries =3D {} - - # register actions - self.register('action', None, _StoreAction) - self.register('action', 'store', _StoreAction) - self.register('action', 'store_const', _StoreConstAction) - self.register('action', 'store_true', _StoreTrueAction) - self.register('action', 'store_false', _StoreFalseAction) - self.register('action', 'append', _AppendAction) - self.register('action', 'append_const', _AppendConstAction) - self.register('action', 'count', _CountAction) - self.register('action', 'help', _HelpAction) - self.register('action', 'version', _VersionAction) - self.register('action', 'parsers', _SubParsersAction) - - # raise an exception if the conflict handler is invalid - self._get_handler() - - # action storage - self._actions =3D [] - self._option_string_actions =3D {} - - # groups - self._action_groups =3D [] - self._mutually_exclusive_groups =3D [] - - # defaults storage - self._defaults =3D {} - - # determines whether an "option" looks like a negative number - self._negative_number_matcher =3D _re.compile(r'^-\d+$|^-\d*\.\d+$= ') - - # whether or not there are any optionals that look like negative - # numbers -- uses a list so it can be shared and edited - self._has_negative_number_optionals =3D [] - - # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - # Registration methods - # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - def register(self, registry_name, value, object): - registry =3D self._registries.setdefault(registry_name, {}) - registry[value] =3D object - - def _registry_get(self, registry_name, value, default=3DNone): - return self._registries[registry_name].get(value, default) - - # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - # Namespace default accessor methods - # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - def set_defaults(self, **kwargs): - self._defaults.update(kwargs) - - # if these defaults match any existing arguments, replace - # the previous default on the object with the new one - for action in self._actions: - if action.dest in kwargs: - action.default =3D kwargs[action.dest] - - def get_default(self, dest): - for action in self._actions: - if action.dest =3D=3D dest and action.default is not None: - return action.default - return self._defaults.get(dest, None) - - - # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D - # Adding argument actions - # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D - def add_argument(self, *args, **kwargs): - """ - add_argument(dest, ..., name=3Dvalue, ...) - add_argument(option_string, option_string, ..., name=3Dvalue, ...) - """ - - # if no positional args are supplied or only one is supplied and - # it doesn't look like an option string, parse a positional - # argument - chars =3D self.prefix_chars - if not args or len(args) =3D=3D 1 and args[0][0] not in chars: - if args and 'dest' in kwargs: - raise ValueError('dest supplied twice for positional argum= ent') - kwargs =3D self._get_positional_kwargs(*args, **kwargs) - - # otherwise, we're adding an optional argument - else: - kwargs =3D self._get_optional_kwargs(*args, **kwargs) - - # if no default was supplied, use the parser-level default - if 'default' not in kwargs: - dest =3D kwargs['dest'] - if dest in self._defaults: - kwargs['default'] =3D self._defaults[dest] - elif self.argument_default is not None: - kwargs['default'] =3D self.argument_default - - # create the action object, and add it to the parser - action_class =3D self._pop_action_class(kwargs) - if not _callable(action_class): - raise ValueError('unknown action "%s"' % action_class) - action =3D action_class(**kwargs) - - # raise an error if the action type is not callable - type_func =3D self._registry_get('type', action.type, action.type) - if not _callable(type_func): - raise ValueError('%r is not callable' % type_func) - - return self._add_action(action) - - def add_argument_group(self, *args, **kwargs): - group =3D _ArgumentGroup(self, *args, **kwargs) - self._action_groups.append(group) - return group - - def add_mutually_exclusive_group(self, **kwargs): - group =3D _MutuallyExclusiveGroup(self, **kwargs) - self._mutually_exclusive_groups.append(group) - return group - - def _add_action(self, action): - # resolve any conflicts - self._check_conflict(action) - - # add to actions list - self._actions.append(action) - action.container =3D self - - # index the action by any option strings it has - for option_string in action.option_strings: - self._option_string_actions[option_string] =3D action - - # set the flag if any option strings look like negative numbers - for option_string in action.option_strings: - if self._negative_number_matcher.match(option_string): - if not self._has_negative_number_optionals: - self._has_negative_number_optionals.append(True) - - # return the created action - return action - - def _remove_action(self, action): - self._actions.remove(action) - - def _add_container_actions(self, container): - # collect groups by titles - title_group_map =3D {} - for group in self._action_groups: - if group.title in title_group_map: - msg =3D _('cannot merge actions - two groups are named %r') - raise ValueError(msg % (group.title)) - title_group_map[group.title] =3D group - - # map each action to its group - group_map =3D {} - for group in container._action_groups: - - # if a group with the title exists, use that, otherwise - # create a new group matching the container's group - if group.title not in title_group_map: - title_group_map[group.title] =3D self.add_argument_group( - title=3Dgroup.title, - description=3Dgroup.description, - conflict_handler=3Dgroup.conflict_handler) - - # map the actions to their new group - for action in group._group_actions: - group_map[action] =3D title_group_map[group.title] - - # add container's mutually exclusive groups - # NOTE: if add_mutually_exclusive_group ever gains title=3D and - # description=3D then this code will need to be expanded as above - for group in container._mutually_exclusive_groups: - mutex_group =3D self.add_mutually_exclusive_group( - required=3Dgroup.required) - - # map the actions to their new mutex group - for action in group._group_actions: - group_map[action] =3D mutex_group - - # add all actions to this container or their group - for action in container._actions: - group_map.get(action, self)._add_action(action) - - def _get_positional_kwargs(self, dest, **kwargs): - # make sure required is not specified - if 'required' in kwargs: - msg =3D _("'required' is an invalid argument for positionals") - raise TypeError(msg) - - # mark positional arguments as required if at least one is - # always required - if kwargs.get('nargs') not in [OPTIONAL, ZERO_OR_MORE]: - kwargs['required'] =3D True - if kwargs.get('nargs') =3D=3D ZERO_OR_MORE and 'default' not in kw= args: - kwargs['required'] =3D True - - # return the keyword arguments with no option strings - return dict(kwargs, dest=3Ddest, option_strings=3D[]) - - def _get_optional_kwargs(self, *args, **kwargs): - # determine short and long option strings - option_strings =3D [] - long_option_strings =3D [] - for option_string in args: - # error on strings that don't start with an appropriate prefix - if not option_string[0] in self.prefix_chars: - msg =3D _('invalid option string %r: ' - 'must start with a character %r') - tup =3D option_string, self.prefix_chars - raise ValueError(msg % tup) - - # strings starting with two prefix characters are long options - option_strings.append(option_string) - if option_string[0] in self.prefix_chars: - if len(option_string) > 1: - if option_string[1] in self.prefix_chars: - long_option_strings.append(option_string) - - # infer destination, '--foo-bar' -> 'foo_bar' and '-x' -> 'x' - dest =3D kwargs.pop('dest', None) - if dest is None: - if long_option_strings: - dest_option_string =3D long_option_strings[0] - else: - dest_option_string =3D option_strings[0] - dest =3D dest_option_string.lstrip(self.prefix_chars) - if not dest: - msg =3D _('dest=3D is required for options like %r') - raise ValueError(msg % option_string) - dest =3D dest.replace('-', '_') - - # return the updated keyword arguments - return dict(kwargs, dest=3Ddest, option_strings=3Doption_strings) - - def _pop_action_class(self, kwargs, default=3DNone): - action =3D kwargs.pop('action', default) - return self._registry_get('action', action, action) - - def _get_handler(self): - # determine function from conflict handler string - handler_func_name =3D '_handle_conflict_%s' % self.conflict_handler - try: - return getattr(self, handler_func_name) - except AttributeError: - msg =3D _('invalid conflict_resolution value: %r') - raise ValueError(msg % self.conflict_handler) - - def _check_conflict(self, action): - - # find all options that conflict with this option - confl_optionals =3D [] - for option_string in action.option_strings: - if option_string in self._option_string_actions: - confl_optional =3D self._option_string_actions[option_stri= ng] - confl_optionals.append((option_string, confl_optional)) - - # resolve any conflicts - if confl_optionals: - conflict_handler =3D self._get_handler() - conflict_handler(action, confl_optionals) - - def _handle_conflict_error(self, action, conflicting_actions): - message =3D _('conflicting option string(s): %s') - conflict_string =3D ', '.join([option_string - for option_string, action - in conflicting_actions]) - raise ArgumentError(action, message % conflict_string) - - def _handle_conflict_resolve(self, action, conflicting_actions): - - # remove all conflicting options - for option_string, action in conflicting_actions: - - # remove the conflicting option - action.option_strings.remove(option_string) - self._option_string_actions.pop(option_string, None) - - # if the option now has no option string, remove it from the - # container holding it - if not action.option_strings: - action.container._remove_action(action) - - -class _ArgumentGroup(_ActionsContainer): - - def __init__(self, container, title=3DNone, description=3DNone, **kwar= gs): - # add any missing keyword arguments by checking the container - update =3D kwargs.setdefault - update('conflict_handler', container.conflict_handler) - update('prefix_chars', container.prefix_chars) - update('argument_default', container.argument_default) - super_init =3D super(_ArgumentGroup, self).__init__ - super_init(description=3Ddescription, **kwargs) - - # group attributes - self.title =3D title - self._group_actions =3D [] - - # share most attributes with the container - self._registries =3D container._registries - self._actions =3D container._actions - self._option_string_actions =3D container._option_string_actions - self._defaults =3D container._defaults - self._has_negative_number_optionals =3D \ - container._has_negative_number_optionals - - def _add_action(self, action): - action =3D super(_ArgumentGroup, self)._add_action(action) - self._group_actions.append(action) - return action - - def _remove_action(self, action): - super(_ArgumentGroup, self)._remove_action(action) - self._group_actions.remove(action) - - -class _MutuallyExclusiveGroup(_ArgumentGroup): - - def __init__(self, container, required=3DFalse): - super(_MutuallyExclusiveGroup, self).__init__(container) - self.required =3D required - self._container =3D container - - def _add_action(self, action): - if action.required: - msg =3D _('mutually exclusive arguments must be optional') - raise ValueError(msg) - action =3D self._container._add_action(action) - self._group_actions.append(action) - return action - - def _remove_action(self, action): - self._container._remove_action(action) - self._group_actions.remove(action) - - -class ArgumentParser(_AttributeHolder, _ActionsContainer): - """Object for parsing command line strings into Python objects. - - Keyword Arguments: - - prog -- The name of the program (default: sys.argv[0]) - - usage -- A usage message (default: auto-generated from arguments) - - description -- A description of what the program does - - epilog -- Text following the argument descriptions - - parents -- Parsers whose arguments should be copied into this one - - formatter_class -- HelpFormatter class for printing help messages - - prefix_chars -- Characters that prefix optional arguments - - fromfile_prefix_chars -- Characters that prefix files containing - additional arguments - - argument_default -- The default value for all arguments - - conflict_handler -- String indicating how to handle conflicts - - add_help -- Add a -h/-help option - """ - - def __init__(self, - prog=3DNone, - usage=3DNone, - description=3DNone, - epilog=3DNone, - version=3DNone, - parents=3D[], - formatter_class=3DHelpFormatter, - prefix_chars=3D'-', - fromfile_prefix_chars=3DNone, - argument_default=3DNone, - conflict_handler=3D'error', - add_help=3DTrue): - - if version is not None: - import warnings - warnings.warn( - """The "version" argument to ArgumentParser is deprecated.= """ - """Please use """ - """"add_argument(..., action=3D'version', version=3D"N", .= ..)" """ - """instead""", DeprecationWarning) - - superinit =3D super(ArgumentParser, self).__init__ - superinit(description=3Ddescription, - prefix_chars=3Dprefix_chars, - argument_default=3Dargument_default, - conflict_handler=3Dconflict_handler) - - # default setting for prog - if prog is None: - prog =3D _os.path.basename(_sys.argv[0]) - - self.prog =3D prog - self.usage =3D usage - self.epilog =3D epilog - self.version =3D version - self.formatter_class =3D formatter_class - self.fromfile_prefix_chars =3D fromfile_prefix_chars - self.add_help =3D add_help - - add_group =3D self.add_argument_group - self._positionals =3D add_group(_('positional arguments')) - self._optionals =3D add_group(_('optional arguments')) - self._subparsers =3D None - - # register types - def identity(string): - return string - self.register('type', None, identity) - - # add help and version arguments if necessary - # (using explicit default to override global argument_default) - if '-' in prefix_chars: - default_prefix =3D '-' - else: - default_prefix =3D prefix_chars[0] - if self.add_help: - self.add_argument( - default_prefix+'h', default_prefix*2+'help', - action=3D'help', default=3DSUPPRESS, - help=3D_('show this help message and exit')) - if self.version: - self.add_argument( - default_prefix+'v', default_prefix*2+'version', - action=3D'version', default=3DSUPPRESS, - version=3Dself.version, - help=3D_("show program's version number and exit")) - - # add parent arguments and defaults - for parent in parents: - self._add_container_actions(parent) - try: - defaults =3D parent._defaults - except AttributeError: - pass - else: - self._defaults.update(defaults) - - # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D - # Pretty __repr__ methods - # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D - def _get_kwargs(self): - names =3D [ - 'prog', - 'usage', - 'description', - 'version', - 'formatter_class', - 'conflict_handler', - 'add_help', - ] - return [(name, getattr(self, name)) for name in names] - - # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - # Optional/Positional adding methods - # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - def add_subparsers(self, **kwargs): - if self._subparsers is not None: - self.error(_('cannot have multiple subparser arguments')) - - # add the parser class to the arguments if it's not present - kwargs.setdefault('parser_class', type(self)) - - if 'title' in kwargs or 'description' in kwargs: - title =3D _(kwargs.pop('title', 'subcommands')) - description =3D _(kwargs.pop('description', None)) - self._subparsers =3D self.add_argument_group(title, descriptio= n) - else: - self._subparsers =3D self._positionals - - # prog defaults to the usage message of this parser, skipping - # optional arguments and with no "usage:" prefix - if kwargs.get('prog') is None: - formatter =3D self._get_formatter() - positionals =3D self._get_positional_actions() - groups =3D self._mutually_exclusive_groups - formatter.add_usage(self.usage, positionals, groups, '') - kwargs['prog'] =3D formatter.format_help().strip() - - # create the parsers action and add it to the positionals list - parsers_class =3D self._pop_action_class(kwargs, 'parsers') - action =3D parsers_class(option_strings=3D[], **kwargs) - self._subparsers._add_action(action) - - # return the created parsers action - return action - - def _add_action(self, action): - if action.option_strings: - self._optionals._add_action(action) - else: - self._positionals._add_action(action) - return action - - def _get_optional_actions(self): - return [action - for action in self._actions - if action.option_strings] - - def _get_positional_actions(self): - return [action - for action in self._actions - if not action.option_strings] - - # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - # Command line argument parsing methods - # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - def parse_args(self, args=3DNone, namespace=3DNone): - args, argv =3D self.parse_known_args(args, namespace) - if argv: - msg =3D _('unrecognized arguments: %s') - self.error(msg % ' '.join(argv)) - return args - - def parse_known_args(self, args=3DNone, namespace=3DNone): - # args default to the system args - if args is None: - args =3D _sys.argv[1:] - - # default Namespace built from parser defaults - if namespace is None: - namespace =3D Namespace() - - # add any action defaults that aren't present - for action in self._actions: - if action.dest is not SUPPRESS: - if not hasattr(namespace, action.dest): - if action.default is not SUPPRESS: - setattr(namespace, action.dest, action.default) - - # add any parser defaults that aren't present - for dest in self._defaults: - if not hasattr(namespace, dest): - setattr(namespace, dest, self._defaults[dest]) - - # parse the arguments and exit if there are any errors - try: - namespace, args =3D self._parse_known_args(args, namespace) - if hasattr(namespace, _UNRECOGNIZED_ARGS_ATTR): - args.extend(getattr(namespace, _UNRECOGNIZED_ARGS_ATTR)) - delattr(namespace, _UNRECOGNIZED_ARGS_ATTR) - return namespace, args - except ArgumentError: - err =3D _sys.exc_info()[1] - self.error(str(err)) - - def _parse_known_args(self, arg_strings, namespace): - # replace arg strings that are file references - if self.fromfile_prefix_chars is not None: - arg_strings =3D self._read_args_from_files(arg_strings) - - # map all mutually exclusive arguments to the other arguments - # they can't occur with - action_conflicts =3D {} - for mutex_group in self._mutually_exclusive_groups: - group_actions =3D mutex_group._group_actions - for i, mutex_action in enumerate(mutex_group._group_actions): - conflicts =3D action_conflicts.setdefault(mutex_action, []) - conflicts.extend(group_actions[:i]) - conflicts.extend(group_actions[i + 1:]) - - # find all option indices, and determine the arg_string_pattern - # which has an 'O' if there is an option at an index, - # an 'A' if there is an argument, or a '-' if there is a '--' - option_string_indices =3D {} - arg_string_pattern_parts =3D [] - arg_strings_iter =3D iter(arg_strings) - for i, arg_string in enumerate(arg_strings_iter): - - # all args after -- are non-options - if arg_string =3D=3D '--': - arg_string_pattern_parts.append('-') - for arg_string in arg_strings_iter: - arg_string_pattern_parts.append('A') - - # otherwise, add the arg to the arg strings - # and note the index if it was an option - else: - option_tuple =3D self._parse_optional(arg_string) - if option_tuple is None: - pattern =3D 'A' - else: - option_string_indices[i] =3D option_tuple - pattern =3D 'O' - arg_string_pattern_parts.append(pattern) - - # join the pieces together to form the pattern - arg_strings_pattern =3D ''.join(arg_string_pattern_parts) - - # converts arg strings to the appropriate and then takes the action - seen_actions =3D set() - seen_non_default_actions =3D set() - - def take_action(action, argument_strings, option_string=3DNone): - seen_actions.add(action) - argument_values =3D self._get_values(action, argument_strings) - - # error if this argument is not allowed with other previously - # seen arguments, assuming that actions that use the default - # value don't really count as "present" - if argument_values is not action.default: - seen_non_default_actions.add(action) - for conflict_action in action_conflicts.get(action, []): - if conflict_action in seen_non_default_actions: - msg =3D _('not allowed with argument %s') - action_name =3D _get_action_name(conflict_action) - raise ArgumentError(action, msg % action_name) - - # take the action if we didn't receive a SUPPRESS value - # (e.g. from a default) - if argument_values is not SUPPRESS: - action(self, namespace, argument_values, option_string) - - # function to convert arg_strings into an optional action - def consume_optional(start_index): - - # get the optional identified at this index - option_tuple =3D option_string_indices[start_index] - action, option_string, explicit_arg =3D option_tuple - - # identify additional optionals in the same arg string - # (e.g. -xyz is the same as -x -y -z if no args are required) - match_argument =3D self._match_argument - action_tuples =3D [] - while True: - - # if we found no optional action, skip it - if action is None: - extras.append(arg_strings[start_index]) - return start_index + 1 - - # if there is an explicit argument, try to match the - # optional's string arguments to only this - if explicit_arg is not None: - arg_count =3D match_argument(action, 'A') - - # if the action is a single-dash option and takes no - # arguments, try to parse more single-dash options out - # of the tail of the option string - chars =3D self.prefix_chars - if arg_count =3D=3D 0 and option_string[1] not in char= s: - action_tuples.append((action, [], option_string)) - char =3D option_string[0] - option_string =3D char + explicit_arg[0] - new_explicit_arg =3D explicit_arg[1:] or None - optionals_map =3D self._option_string_actions - if option_string in optionals_map: - action =3D optionals_map[option_string] - explicit_arg =3D new_explicit_arg - else: - msg =3D _('ignored explicit argument %r') - raise ArgumentError(action, msg % explicit_arg) - - # if the action expect exactly one argument, we've - # successfully matched the option; exit the loop - elif arg_count =3D=3D 1: - stop =3D start_index + 1 - args =3D [explicit_arg] - action_tuples.append((action, args, option_string)) - break - - # error if a double-dash option did not use the - # explicit argument - else: - msg =3D _('ignored explicit argument %r') - raise ArgumentError(action, msg % explicit_arg) - - # if there is no explicit argument, try to match the - # optional's string arguments with the following strings - # if successful, exit the loop - else: - start =3D start_index + 1 - selected_patterns =3D arg_strings_pattern[start:] - arg_count =3D match_argument(action, selected_patterns) - stop =3D start + arg_count - args =3D arg_strings[start:stop] - action_tuples.append((action, args, option_string)) - break - - # add the Optional to the list and return the index at which - # the Optional's string args stopped - assert action_tuples - for action, args, option_string in action_tuples: - take_action(action, args, option_string) - return stop - - # the list of Positionals left to be parsed; this is modified - # by consume_positionals() - positionals =3D self._get_positional_actions() - - # function to convert arg_strings into positional actions - def consume_positionals(start_index): - # match as many Positionals as possible - match_partial =3D self._match_arguments_partial - selected_pattern =3D arg_strings_pattern[start_index:] - arg_counts =3D match_partial(positionals, selected_pattern) - - # slice off the appropriate arg strings for each Positional - # and add the Positional and its args to the list - for action, arg_count in zip(positionals, arg_counts): - args =3D arg_strings[start_index: start_index + arg_count] - start_index +=3D arg_count - take_action(action, args) - - # slice off the Positionals that we just parsed and return the - # index at which the Positionals' string args stopped - positionals[:] =3D positionals[len(arg_counts):] - return start_index - - # consume Positionals and Optionals alternately, until we have - # passed the last option string - extras =3D [] - start_index =3D 0 - if option_string_indices: - max_option_string_index =3D max(option_string_indices) - else: - max_option_string_index =3D -1 - while start_index <=3D max_option_string_index: - - # consume any Positionals preceding the next option - next_option_string_index =3D min([ - index - for index in option_string_indices - if index >=3D start_index]) - if start_index !=3D next_option_string_index: - positionals_end_index =3D consume_positionals(start_index) - - # only try to parse the next optional if we didn't consume - # the option string during the positionals parsing - if positionals_end_index > start_index: - start_index =3D positionals_end_index - continue - else: - start_index =3D positionals_end_index - - # if we consumed all the positionals we could and we're not - # at the index of an option string, there were extra arguments - if start_index not in option_string_indices: - strings =3D arg_strings[start_index:next_option_string_ind= ex] - extras.extend(strings) - start_index =3D next_option_string_index - - # consume the next optional and any arguments for it - start_index =3D consume_optional(start_index) - - # consume any positionals following the last Optional - stop_index =3D consume_positionals(start_index) - - # if we didn't consume all the argument strings, there were extras - extras.extend(arg_strings[stop_index:]) - - # if we didn't use all the Positional objects, there were too few - # arg strings supplied. - if positionals: - self.error(_('too few arguments')) - - # make sure all required actions were present, and convert default= s. - for action in self._actions: - if action not in seen_actions: - if action.required: - name =3D _get_action_name(action) - self.error(_('argument %s is required') % name) - else: - # Convert action default now instead of doing it before - # parsing arguments to avoid calling convert functions - # twice (which may fail) if the argument was given, but - # only if it was defined already in the namespace - if (action.default is not None and - isinstance(action.default, basestring) and - hasattr(namespace, action.dest) and - action.default is getattr(namespace, action.de= st)): - setattr(namespace, action.dest, - self._get_value(action, action.default)) - - # make sure all required groups had one option present - for group in self._mutually_exclusive_groups: - if group.required: - for action in group._group_actions: - if action in seen_non_default_actions: - break - - # if no actions were used, report the error - else: - names =3D [_get_action_name(action) - for action in group._group_actions - if action.help is not SUPPRESS] - msg =3D _('one of the arguments %s is required') - self.error(msg % ' '.join(names)) - - # return the updated namespace and the extra arguments - return namespace, extras - - def _read_args_from_files(self, arg_strings): - # expand arguments referencing files - new_arg_strings =3D [] - for arg_string in arg_strings: - - # for regular arguments, just add them back into the list - if arg_string[0] not in self.fromfile_prefix_chars: - new_arg_strings.append(arg_string) - - # replace arguments referencing files with the file content - else: - try: - args_file =3D open(arg_string[1:]) - try: - arg_strings =3D [] - for arg_line in args_file.read().splitlines(): - for arg in self.convert_arg_line_to_args(arg_l= ine): - arg_strings.append(arg) - arg_strings =3D self._read_args_from_files(arg_str= ings) - new_arg_strings.extend(arg_strings) - finally: - args_file.close() - except IOError: - err =3D _sys.exc_info()[1] - self.error(str(err)) - - # return the modified argument list - return new_arg_strings - - def convert_arg_line_to_args(self, arg_line): - return [arg_line] - - def _match_argument(self, action, arg_strings_pattern): - # match the pattern for this action to the arg strings - nargs_pattern =3D self._get_nargs_pattern(action) - match =3D _re.match(nargs_pattern, arg_strings_pattern) - - # raise an exception if we weren't able to find a match - if match is None: - nargs_errors =3D { - None: _('expected one argument'), - OPTIONAL: _('expected at most one argument'), - ONE_OR_MORE: _('expected at least one argument'), - } - default =3D _('expected %s argument(s)') % action.nargs - msg =3D nargs_errors.get(action.nargs, default) - raise ArgumentError(action, msg) - - # return the number of arguments matched - return len(match.group(1)) - - def _match_arguments_partial(self, actions, arg_strings_pattern): - # progressively shorten the actions list by slicing off the - # final actions until we find a match - result =3D [] - for i in range(len(actions), 0, -1): - actions_slice =3D actions[:i] - pattern =3D ''.join([self._get_nargs_pattern(action) - for action in actions_slice]) - match =3D _re.match(pattern, arg_strings_pattern) - if match is not None: - result.extend([len(string) for string in match.groups()]) - break - - # return the list of arg string counts - return result - - def _parse_optional(self, arg_string): - # if it's an empty string, it was meant to be a positional - if not arg_string: - return None - - # if it doesn't start with a prefix, it was meant to be positional - if not arg_string[0] in self.prefix_chars: - return None - - # if the option string is present in the parser, return the action - if arg_string in self._option_string_actions: - action =3D self._option_string_actions[arg_string] - return action, arg_string, None - - # if it's just a single character, it was meant to be positional - if len(arg_string) =3D=3D 1: - return None - - # if the option string before the "=3D" is present, return the act= ion - if '=3D' in arg_string: - option_string, explicit_arg =3D arg_string.split('=3D', 1) - if option_string in self._option_string_actions: - action =3D self._option_string_actions[option_string] - return action, option_string, explicit_arg - - # search through all possible prefixes of the option string - # and all actions in the parser for possible interpretations - option_tuples =3D self._get_option_tuples(arg_string) - - # if multiple actions match, the option string was ambiguous - if len(option_tuples) > 1: - options =3D ', '.join([option_string - for action, option_string, explicit_arg in option_tuples]) - tup =3D arg_string, options - self.error(_('ambiguous option: %s could match %s') % tup) - - # if exactly one action matched, this segmentation is good, - # so return the parsed action - elif len(option_tuples) =3D=3D 1: - option_tuple, =3D option_tuples - return option_tuple - - # if it was not found as an option, but it looks like a negative - # number, it was meant to be positional - # unless there are negative-number-like options - if self._negative_number_matcher.match(arg_string): - if not self._has_negative_number_optionals: - return None - - # if it contains a space, it was meant to be a positional - if ' ' in arg_string: - return None - - # it was meant to be an optional but there is no such option - # in this parser (though it might be a valid option in a subparser) - return None, arg_string, None - - def _get_option_tuples(self, option_string): - result =3D [] - - # option strings starting with two prefix characters are only - # split at the '=3D' - chars =3D self.prefix_chars - if option_string[0] in chars and option_string[1] in chars: - if '=3D' in option_string: - option_prefix, explicit_arg =3D option_string.split('=3D',= 1) - else: - option_prefix =3D option_string - explicit_arg =3D None - for option_string in self._option_string_actions: - if option_string.startswith(option_prefix): - action =3D self._option_string_actions[option_string] - tup =3D action, option_string, explicit_arg - result.append(tup) - - # single character options can be concatenated with their arguments - # but multiple character options always have to have their argument - # separate - elif option_string[0] in chars and option_string[1] not in chars: - option_prefix =3D option_string - explicit_arg =3D None - short_option_prefix =3D option_string[:2] - short_explicit_arg =3D option_string[2:] - - for option_string in self._option_string_actions: - if option_string =3D=3D short_option_prefix: - action =3D self._option_string_actions[option_string] - tup =3D action, option_string, short_explicit_arg - result.append(tup) - elif option_string.startswith(option_prefix): - action =3D self._option_string_actions[option_string] - tup =3D action, option_string, explicit_arg - result.append(tup) - - # shouldn't ever get here - else: - self.error(_('unexpected option string: %s') % option_string) - - # return the collected option tuples - return result - - def _get_nargs_pattern(self, action): - # in all examples below, we have to allow for '--' args - # which are represented as '-' in the pattern - nargs =3D action.nargs - - # the default (None) is assumed to be a single argument - if nargs is None: - nargs_pattern =3D '(-*A-*)' - - # allow zero or one arguments - elif nargs =3D=3D OPTIONAL: - nargs_pattern =3D '(-*A?-*)' - - # allow zero or more arguments - elif nargs =3D=3D ZERO_OR_MORE: - nargs_pattern =3D '(-*[A-]*)' - - # allow one or more arguments - elif nargs =3D=3D ONE_OR_MORE: - nargs_pattern =3D '(-*A[A-]*)' - - # allow any number of options or arguments - elif nargs =3D=3D REMAINDER: - nargs_pattern =3D '([-AO]*)' - - # allow one argument followed by any number of options or arguments - elif nargs =3D=3D PARSER: - nargs_pattern =3D '(-*A[-AO]*)' - - # all others should be integers - else: - nargs_pattern =3D '(-*%s-*)' % '-*'.join('A' * nargs) - - # if this is an optional action, -- is not allowed - if action.option_strings: - nargs_pattern =3D nargs_pattern.replace('-*', '') - nargs_pattern =3D nargs_pattern.replace('-', '') - - # return the pattern - return nargs_pattern - - # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D - # Value conversion methods - # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D - def _get_values(self, action, arg_strings): - # for everything but PARSER args, strip out '--' - if action.nargs not in [PARSER, REMAINDER]: - arg_strings =3D [s for s in arg_strings if s !=3D '--'] - - # optional argument produces a default when not present - if not arg_strings and action.nargs =3D=3D OPTIONAL: - if action.option_strings: - value =3D action.const - else: - value =3D action.default - if isinstance(value, basestring): - value =3D self._get_value(action, value) - self._check_value(action, value) - - # when nargs=3D'*' on a positional, if there were no command-line - # args, use the default if it is anything other than None - elif (not arg_strings and action.nargs =3D=3D ZERO_OR_MORE and - not action.option_strings): - if action.default is not None: - value =3D action.default - else: - value =3D arg_strings - self._check_value(action, value) - - # single argument or optional argument produces a single value - elif len(arg_strings) =3D=3D 1 and action.nargs in [None, OPTIONAL= ]: - arg_string, =3D arg_strings - value =3D self._get_value(action, arg_string) - self._check_value(action, value) - - # REMAINDER arguments convert all values, checking none - elif action.nargs =3D=3D REMAINDER: - value =3D [self._get_value(action, v) for v in arg_strings] - - # PARSER arguments convert all values, but check only the first - elif action.nargs =3D=3D PARSER: - value =3D [self._get_value(action, v) for v in arg_strings] - self._check_value(action, value[0]) - - # all other types of nargs produce a list - else: - value =3D [self._get_value(action, v) for v in arg_strings] - for v in value: - self._check_value(action, v) - - # return the converted value - return value - - def _get_value(self, action, arg_string): - type_func =3D self._registry_get('type', action.type, action.type) - if not _callable(type_func): - msg =3D _('%r is not callable') - raise ArgumentError(action, msg % type_func) - - # convert the value to the appropriate type - try: - result =3D type_func(arg_string) - - # ArgumentTypeErrors indicate errors - except ArgumentTypeError: - name =3D getattr(action.type, '__name__', repr(action.type)) - msg =3D str(_sys.exc_info()[1]) - raise ArgumentError(action, msg) - - # TypeErrors or ValueErrors also indicate errors - except (TypeError, ValueError): - name =3D getattr(action.type, '__name__', repr(action.type)) - msg =3D _('invalid %s value: %r') - raise ArgumentError(action, msg % (name, arg_string)) - - # return the converted value - return result - - def _check_value(self, action, value): - # converted value must be one of the choices (if specified) - if action.choices is not None and value not in action.choices: - tup =3D value, ', '.join(map(repr, action.choices)) - msg =3D _('invalid choice: %r (choose from %s)') % tup - raise ArgumentError(action, msg) - - # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D - # Help-formatting methods - # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D - def format_usage(self): - formatter =3D self._get_formatter() - formatter.add_usage(self.usage, self._actions, - self._mutually_exclusive_groups) - return formatter.format_help() - - def format_help(self): - formatter =3D self._get_formatter() - - # usage - formatter.add_usage(self.usage, self._actions, - self._mutually_exclusive_groups) - - # description - formatter.add_text(self.description) - - # positionals, optionals and user-defined groups - for action_group in self._action_groups: - formatter.start_section(action_group.title) - formatter.add_text(action_group.description) - formatter.add_arguments(action_group._group_actions) - formatter.end_section() - - # epilog - formatter.add_text(self.epilog) - - # determine help from format above - return formatter.format_help() - - def format_version(self): - import warnings - warnings.warn( - 'The format_version method is deprecated -- the "version" ' - 'argument to ArgumentParser is no longer supported.', - DeprecationWarning) - formatter =3D self._get_formatter() - formatter.add_text(self.version) - return formatter.format_help() - - def _get_formatter(self): - return self.formatter_class(prog=3Dself.prog) - - # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - # Help-printing methods - # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - def print_usage(self, file=3DNone): - if file is None: - file =3D _sys.stdout - self._print_message(self.format_usage(), file) - - def print_help(self, file=3DNone): - if file is None: - file =3D _sys.stdout - self._print_message(self.format_help(), file) - - def print_version(self, file=3DNone): - import warnings - warnings.warn( - 'The print_version method is deprecated -- the "version" ' - 'argument to ArgumentParser is no longer supported.', - DeprecationWarning) - self._print_message(self.format_version(), file) - - def _print_message(self, message, file=3DNone): - if message: - if file is None: - file =3D _sys.stderr - file.write(message) - - # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - # Exiting methods - # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - def exit(self, status=3D0, message=3DNone): - if message: - self._print_message(message, _sys.stderr) - _sys.exit(status) - - def error(self, message): - """error(message: string) - - Prints a usage message incorporating the message to stderr and - exits. - - If you override this in a subclass, it should not return -- it - should either exit or raise an exception. - """ - self.print_usage(_sys.stderr) - self.exit(2, _('%s: error: %s\n') % (self.prog, message)) --=20 2.18.0.rc1.1.g3f1ff2140 From nobody Mon Apr 29 10:22:49 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1528481745893843.7807892008033; Fri, 8 Jun 2018 11:15:45 -0700 (PDT) Received: from localhost ([::1]:37493 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fRLvN-0007s0-3T for importer@patchew.org; Fri, 08 Jun 2018 14:15:45 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49351) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fRLaK-0007KP-0a for qemu-devel@nongnu.org; Fri, 08 Jun 2018 13:54:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fRLaH-0003bw-78 for qemu-devel@nongnu.org; Fri, 08 Jun 2018 13:53:59 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:49542 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fRLaH-0003bp-2p for qemu-devel@nongnu.org; Fri, 08 Jun 2018 13:53:57 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8E0AC4022931; Fri, 8 Jun 2018 17:53:56 +0000 (UTC) Received: from localhost (ovpn-116-19.gru2.redhat.com [10.97.116.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 09D71202699A; Fri, 8 Jun 2018 17:53:55 +0000 (UTC) From: Eduardo Habkost To: qemu-devel@nongnu.org Date: Fri, 8 Jun 2018 14:52:52 -0300 Message-Id: <20180608175252.25110-3-ehabkost@redhat.com> In-Reply-To: <20180608175252.25110-1-ehabkost@redhat.com> References: <20180608175252.25110-1-ehabkost@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Fri, 08 Jun 2018 17:53:56 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Fri, 08 Jun 2018 17:53:56 +0000 (UTC) for IP:'10.11.54.4' DOMAIN:'int-mx04.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'ehabkost@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH v2 2/2] python: Remove scripts/ordereddict.py X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Stefan Hajnoczi , Cleber Rosa Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Python 2.7 (the minimum Python version we require) provides collections.OrderedDict on the standard library, so we don't need to carry our own implementation. Signed-off-by: Eduardo Habkost Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- Changes v1 -> v2: * Remove ordereddict.py reference from Makefiles --- Makefile | 1 - scripts/ordereddict.py | 128 ----------------------------------------- scripts/qapi/common.py | 5 +- tests/Makefile.include | 1 - 4 files changed, 1 insertion(+), 134 deletions(-) delete mode 100644 scripts/ordereddict.py diff --git a/Makefile b/Makefile index 023b3437ec..6c6664d9a3 100644 --- a/Makefile +++ b/Makefile @@ -567,7 +567,6 @@ $(SRC_PATH)/scripts/qapi/types.py \ $(SRC_PATH)/scripts/qapi/visit.py \ $(SRC_PATH)/scripts/qapi/common.py \ $(SRC_PATH)/scripts/qapi/doc.py \ -$(SRC_PATH)/scripts/ordereddict.py \ $(SRC_PATH)/scripts/qapi-gen.py =20 qga/qapi-generated/qga-qapi-types.c qga/qapi-generated/qga-qapi-types.h \ diff --git a/scripts/ordereddict.py b/scripts/ordereddict.py deleted file mode 100644 index 68ed340b33..0000000000 --- a/scripts/ordereddict.py +++ /dev/null @@ -1,128 +0,0 @@ -# Copyright (c) 2009 Raymond Hettinger -# -# Permission is hereby granted, free of charge, to any person -# obtaining a copy of this software and associated documentation files -# (the "Software"), to deal in the Software without restriction, -# including without limitation the rights to use, copy, modify, merge, -# publish, distribute, sublicense, and/or sell copies of the Software, -# and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -# OTHER DEALINGS IN THE SOFTWARE. - -from UserDict import DictMixin - - -class OrderedDict(dict, DictMixin): - - def __init__(self, *args, **kwds): - if len(args) > 1: - raise TypeError('expected at most 1 arguments, got %d' % len(a= rgs)) - try: - self.__end - except AttributeError: - self.clear() - self.update(*args, **kwds) - - def clear(self): - self.__end =3D end =3D [] - end +=3D [None, end, end] # sentinel node for doubly linke= d list - self.__map =3D {} # key --> [key, prev, next] - dict.clear(self) - - def __setitem__(self, key, value): - if key not in self: - end =3D self.__end - curr =3D end[1] - curr[2] =3D end[1] =3D self.__map[key] =3D [key, curr, end] - dict.__setitem__(self, key, value) - - def __delitem__(self, key): - dict.__delitem__(self, key) - key, prev, next =3D self.__map.pop(key) - prev[2] =3D next - next[1] =3D prev - - def __iter__(self): - end =3D self.__end - curr =3D end[2] - while curr is not end: - yield curr[0] - curr =3D curr[2] - - def __reversed__(self): - end =3D self.__end - curr =3D end[1] - while curr is not end: - yield curr[0] - curr =3D curr[1] - - def popitem(self, last=3DTrue): - if not self: - raise KeyError('dictionary is empty') - if last: - key =3D next(reversed(self)) - else: - key =3D next(iter(self)) - value =3D self.pop(key) - return key, value - - def __reduce__(self): - items =3D [[k, self[k]] for k in self] - tmp =3D self.__map, self.__end - del self.__map, self.__end - inst_dict =3D vars(self).copy() - self.__map, self.__end =3D tmp - if inst_dict: - return (self.__class__, (items,), inst_dict) - return self.__class__, (items,) - - def keys(self): - return list(self) - - setdefault =3D DictMixin.setdefault - update =3D DictMixin.update - pop =3D DictMixin.pop - values =3D DictMixin.values - items =3D DictMixin.items - iterkeys =3D DictMixin.iterkeys - itervalues =3D DictMixin.itervalues - iteritems =3D DictMixin.iteritems - - def __repr__(self): - if not self: - return '%s()' % (self.__class__.__name__,) - return '%s(%r)' % (self.__class__.__name__, self.items()) - - def copy(self): - return self.__class__(self) - - @classmethod - def fromkeys(cls, iterable, value=3DNone): - d =3D cls() - for key in iterable: - d[key] =3D value - return d - - def __eq__(self, other): - if isinstance(other, OrderedDict): - if len(self) !=3D len(other): - return False - for p, q in zip(self.items(), other.items()): - if p !=3D q: - return False - return True - return dict.__eq__(self, other) - - def __ne__(self, other): - return not self =3D=3D other diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index e82990f0f2..2462fc0291 100644 --- a/scripts/qapi/common.py +++ b/scripts/qapi/common.py @@ -16,10 +16,7 @@ import errno import os import re import string -try: - from collections import OrderedDict -except: - from ordereddict import OrderedDict +from collections import OrderedDict =20 builtin_types =3D { 'null': 'QTYPE_QNULL', diff --git a/tests/Makefile.include b/tests/Makefile.include index 400d8890e7..ccedacebd5 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -31,7 +31,6 @@ $(SRC_PATH)/scripts/qapi/types.py \ $(SRC_PATH)/scripts/qapi/visit.py \ $(SRC_PATH)/scripts/qapi/common.py \ $(SRC_PATH)/scripts/qapi/doc.py \ -$(SRC_PATH)/scripts/ordereddict.py \ $(SRC_PATH)/scripts/qapi-gen.py =20 # Get the list of all supported sysemu targets --=20 2.18.0.rc1.1.g3f1ff2140