1 class CommandParser(ArgumentParser): 2 """ 3 Customized ArgumentParser class to improve some error messages and prevent 4 SystemExit in several occasions, as SystemExit is unacceptable when a 5 command is called programmatically. 6 """ 7 def __init__(self, cmd, **kwargs): 8 self.cmd = cmd 9 super(CommandParser, self).__init__(**kwargs) 10 11 def parse_args(self, args=None, namespace=None): 12 # Catch missing argument for a better error message 13 if (hasattr(self.cmd, 'missing_args_message') and 14 not (args or any(not arg.startswith('-') for arg in args))): 15 self.error(self.cmd.missing_args_message) 16 return super(CommandParser, self).parse_args(args, namespace) 17 18 class ArgumentParser(_AttributeHolder, _ActionsContainer): 19 """Object for parsing command line strings into Python objects. 20 21 Keyword Arguments: 22 - prog -- The name of the program (default: sys.argv[0]) 23 - usage -- A usage message (default: auto-generated from arguments) 24 - description -- A description of what the program does 25 - epilog -- Text following the argument descriptions 26 - parents -- Parsers whose arguments should be copied into this one 27 - formatter_class -- HelpFormatter class for printing help messages 28 - prefix_chars -- Characters that prefix optional arguments 29 - fromfile_prefix_chars -- Characters that prefix files containing 30 additional arguments 31 - argument_default -- The default value for all arguments 32 - conflict_handler -- String indicating how to handle conflicts 33 - add_help -- Add a -h/-help option 34 - allow_abbrev -- Allow long options to be abbreviated unambiguously 35 """ 36 37 def __init__(self, 38 prog=None, 39 usage=None, 40 description=None, 41 epilog=None, 42 parents=[], 43 formatter_class=HelpFormatter, 44 prefix_chars='-', 45 fromfile_prefix_chars=None, 46 argument_default=None, 47 conflict_handler='error', 48 add_help=True, 49 allow_abbrev=True): 50 51 superinit = super(ArgumentParser, self).__init__ 52 superinit(description=description, 53 prefix_chars=prefix_chars, 54 argument_default=argument_default, 55 conflict_handler=conflict_handler) 56 57 58 # default setting for prog 59 if prog is None: 60 prog = _os.path.basename(_sys.argv[0]) 61 62 self.prog = prog 63 self.usage = usage 64 self.epilog = epilog 65 self.formatter_class = formatter_class 66 self.fromfile_prefix_chars = fromfile_prefix_chars 67 self.add_help = add_help 68 self.allow_abbrev = allow_abbrev 69 70 add_group = self.add_argument_group 71 self._positionals = add_group(_('positional arguments')) 72 self._optionals = add_group(_('optional arguments')) 73 self._subparsers = None 74 75 # register types 76 def identity(string): 77 return string 78 self.register('type', None, identity) 79 80 # add help argument if necessary 81 # (using explicit default to override global argument_default) 显式覆盖全局 82 default_prefix = '-' if '-' in prefix_chars else prefix_chars[0] 83 if self.add_help: 84 self.add_argument( 85 default_prefix+'h', default_prefix*2+'help', 86 action='help', default=SUPPRESS, 87 help=_('show this help message and exit')) 88 89 # add parent arguments and defaults 90 for parent in parents: 91 self._add_container_actions(parent) 92 try: 93 defaults = parent._defaults 94 except AttributeError: 95 pass 96 else: 97 self._defaults.update(defaults) 98 99 def parse_args(self, args=None, namespace=None): 100 args, argv = self.parse_known_args(args, namespace) 101 if argv: 102 msg = _('unrecognized arguments: %s') 103 self.error(msg % ' '.join(argv)) 104 return args