From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) by finch.gentoo.org (Postfix) with ESMTP id 580AC138204 for ; Tue, 17 Sep 2013 16:41:02 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 3E69DE0C3D; Tue, 17 Sep 2013 16:40:59 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) (using TLSv1 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id 82B6BE0C43 for ; Tue, 17 Sep 2013 16:40:58 +0000 (UTC) Received: from hornbill.gentoo.org (hornbill.gentoo.org [94.100.119.163]) (using TLSv1 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 5AB2733ED04 for ; Tue, 17 Sep 2013 16:40:57 +0000 (UTC) Received: from localhost.localdomain (localhost [127.0.0.1]) by hornbill.gentoo.org (Postfix) with ESMTP id 02A77E545E for ; Tue, 17 Sep 2013 16:40:56 +0000 (UTC) From: "André Erdmann" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "André Erdmann" Message-ID: <1379431568.f2caad3d9b949a0a0ca52219d467fbdc8c75499d.dywi@gentoo> Subject: [gentoo-commits] proj/R_overlay:master commit in: roverlay/ X-VCS-Repository: proj/R_overlay X-VCS-Files: roverlay/argparser.py roverlay/argutil.py X-VCS-Directories: roverlay/ X-VCS-Committer: dywi X-VCS-Committer-Name: André Erdmann X-VCS-Revision: f2caad3d9b949a0a0ca52219d467fbdc8c75499d X-VCS-Branch: master Date: Tue, 17 Sep 2013 16:40:56 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Archives-Salt: e721b273-30e7-4d95-abc4-29b4832951bb X-Archives-Hash: 1c07f1ebb9173a1b072d4ce13fbf3978 commit: f2caad3d9b949a0a0ca52219d467fbdc8c75499d Author: André Erdmann mailerd de> AuthorDate: Tue Sep 17 15:26:08 2013 +0000 Commit: André Erdmann mailerd de> CommitDate: Tue Sep 17 15:26:08 2013 +0000 URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=f2caad3d argparser,argutil: support subparsers --- roverlay/argparser.py | 54 +++++++++++++++++++++++++++++++++++----------- roverlay/argutil.py | 60 +++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 100 insertions(+), 14 deletions(-) diff --git a/roverlay/argparser.py b/roverlay/argparser.py index 5b28d0f..d52a1e2 100644 --- a/roverlay/argparser.py +++ b/roverlay/argparser.py @@ -6,6 +6,7 @@ import argparse import collections +import sys import roverlay.core import roverlay.argutil @@ -566,6 +567,7 @@ class RoverlayArgumentParserBase ( roverlay.argutil.ArgumentParserProxy ): class RoverlayArgumentParser ( RoverlayArgumentParserBase ): MULTIPLE_COMMANDS = False + COMMAND_SUBPARSERS = None COMMAND_DESCRIPTION = None DEFAULT_COMMAND = None @@ -582,6 +584,18 @@ class RoverlayArgumentParser ( RoverlayArgumentParserBase ): assert self.default_command in self.COMMAND_DESCRIPTION # --- end of __init__ (...) --- + def get_args_to_parse ( self ): + if self.__class__.COMMAND_SUBPARSERS is None: + return sys.argv[1:] + else: + args = sys.argv[1:] + + if any ( command in args for command in self.COMMAND_DESCRIPTION ): + return args + else: + return args + [ self.default_command ] + # --- end of get_args_to_parse (...) --- + def get_commands ( self ): if self.MULTIPLE_COMMANDS: return self.command @@ -590,23 +604,39 @@ class RoverlayArgumentParser ( RoverlayArgumentParserBase ): # --- end of get_commands (...) --- def setup_actions ( self ): - arg = self.add_argument_group ( - "actions", title="actions", - description=self.format_command_map ( self.COMMAND_DESCRIPTION ), - ) + if self.__class__.COMMAND_SUBPARSERS is None: + arg = self.add_argument_group ( + "actions", title="actions", + description=self.format_command_map ( self.COMMAND_DESCRIPTION ), + ) - arg ( - 'command', default=self.default_command, metavar='', - nargs=( "*" if self.MULTIPLE_COMMANDS else "?" ), - choices=self.COMMAND_DESCRIPTION.keys(), - flags=self.ARG_HELP_DEFAULT, - help="action to perform" - ) + arg ( + 'command', default=self.default_command, metavar='', + nargs=( "*" if self.MULTIPLE_COMMANDS else "?" ), + choices=self.COMMAND_DESCRIPTION.keys(), + flags=self.ARG_HELP_DEFAULT, + help="action to perform" + ) - return arg + return arg + else: + self.add_subparsers ( + title="commands", + description=self.format_command_map ( self.COMMAND_DESCRIPTION ), + dest="command", + help="action to perform [%(default)s]", + ) + # set_defaults() not necessary due to get_args_to_parse() + self.parser.set_defaults ( command=self.default_command ) + + for command in self.COMMAND_DESCRIPTION: + subparser = self.add_subparser ( command ) + + return None # --- end of setup_actions (...) --- def parse_actions ( self ): + print ( self.parsed ) self.command = self.parsed ['command'] # --- end of parse_actions (...) --- diff --git a/roverlay/argutil.py b/roverlay/argutil.py index c3981e5..7c36980 100644 --- a/roverlay/argutil.py +++ b/roverlay/argutil.py @@ -8,6 +8,7 @@ import os import argparse import pwd import grp +import sys from roverlay.config.entryutil import deref_entry_safe @@ -158,6 +159,9 @@ class ArgumentParserError ( Exception ): class ArgumentGroupExists ( ArgumentParserError ): pass +class SubparserExists ( ArgumentParserError ): + pass + class ArgumentFlagException ( ArgumentParserError ): pass @@ -207,10 +211,54 @@ class ArgumentParserProxy ( object ): self.defaults = dict ( defaults ) self._argument_groups = dict() + self._subparsers = dict() + self._subparser_ctrl = None self.parsed = None # --- end of __init__ (...) --- + def add_subparsers ( self, ignore_exist=False, **kwargs ): + if self._subparser_ctrl is None: + self._subparser_ctrl = self.parser.add_subparsers ( **kwargs ) + elif not ignore_exist: + raise AssertionError ( "add_subparsers() already called!" ) + + return self._subparser_ctrl + # --- end of add_subparsers (...) --- + + def add_subparser ( self, + command, defaults=True, proxy_cls=None, **parser_kwargs + ): + if command in self._subparsers: + raise SubparserExists ( command ) + else: + if proxy_cls is None: + get_proxy = ArgumentParserProxy.wrap + elif proxy_cls is True: + get_proxy = self.__class__.wrap + elif hasattr ( proxy_cls, 'wrap' ): + get_proxy = proxy_cls.wrap + else: + get_proxy = proxy_cls + + parser = ( + self.add_subparsers ( ignore_exist=True ).add_parser ( + command, **parser_kwargs + ) + ) + + proxy = get_proxy ( + parser, + defaults = ( self.defaults if defaults is True else defaults ) + ) + self._subparsers [command] = proxy + return proxy + # --- end of add_subparser (...) --- + + def get_subparser ( self, name ): + return self._subparsers [name] + # --- end of get_subparser (...) --- + def get_options ( self ): return self.parsed # --- end of get_options (...) --- @@ -331,12 +379,20 @@ class ArgumentParserProxy ( object ): ) # --- end of group_arg (...) --- - def parse_args ( self, *args, **kwargs ): - self.parsed = self.parser.parse_args ( *args, **kwargs ) + def get_args_to_parse ( self ): + return sys.argv[1:] + # --- end of get_args_to_parse (...) --- + + def parse_args ( self, args=None, namespace=None ): + self.parsed = self.parser.parse_args ( + args = ( self.get_args_to_parse() if args is None else args ), + namespace = namespace, + ) return self.parsed # --- end of parse_args (...) --- def parse ( self, *args, **kwargs ): + print ( "ArgumentParserProxy.parse() is deprecated. Use parse_args()." ) return self.parse_args ( *args, **kwargs ) # --- end of parse (...) ---