Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 23 additions & 132 deletions Lib/argparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,16 @@
]


import collections as _collections
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 _, ngettext


SUPPRESS = '==SUPPRESS=='

OPTIONAL = '?'
Expand Down Expand Up @@ -133,16 +137,10 @@ def _get_args(self):
return []


def _copy_items(items):
if items is None:
return []
# The copy module is used only in the 'append' and 'append_const'
# actions, and it is needed only when the default value isn't a list.
# Delay its import for speeding up the common case.
if type(items) is list:
return items[:]
import copy
return copy.copy(items)
def _ensure_value(namespace, name, value):
if getattr(namespace, name, None) is None:
setattr(namespace, name, value)
return getattr(namespace, name)


# ===============
Expand Down Expand Up @@ -589,8 +587,6 @@ def _format_args(self, action, default_metavar):
result = '...'
elif action.nargs == PARSER:
result = '%s ...' % get_metavar(1)
elif action.nargs == SUPPRESS:
result = ''
else:
formats = ['%s' for _ in range(action.nargs)]
result = ' '.join(formats) % get_metavar(action.nargs)
Expand Down Expand Up @@ -621,17 +617,12 @@ def _iter_indented_subactions(self, action):

def _split_lines(self, text, width):
text = self._whitespace_matcher.sub(' ', text).strip()
# The textwrap module is used only for formatting help.
# Delay its import for speeding up the common usage of argparse.
import textwrap
return textwrap.wrap(text, width)
return _textwrap.wrap(text, width)

def _fill_text(self, text, width, indent):
text = self._whitespace_matcher.sub(' ', text).strip()
import textwrap
return textwrap.fill(text, width,
initial_indent=indent,
subsequent_indent=indent)
return _textwrap.fill(text, width, initial_indent=indent,
subsequent_indent=indent)

def _get_help_string(self, action):
return action.help
Expand Down Expand Up @@ -959,8 +950,7 @@ def __init__(self,
metavar=metavar)

def __call__(self, parser, namespace, values, option_string=None):
items = getattr(namespace, self.dest, None)
items = _copy_items(items)
items = _copy.copy(_ensure_value(namespace, self.dest, []))
items.append(values)
setattr(namespace, self.dest, items)

Expand All @@ -986,8 +976,7 @@ def __init__(self,
metavar=metavar)

def __call__(self, parser, namespace, values, option_string=None):
items = getattr(namespace, self.dest, None)
items = _copy_items(items)
items = _copy.copy(_ensure_value(namespace, self.dest, []))
items.append(self.const)
setattr(namespace, self.dest, items)

Expand All @@ -1009,10 +998,8 @@ def __init__(self,
help=help)

def __call__(self, parser, namespace, values, option_string=None):
count = getattr(namespace, self.dest, None)
if count is None:
count = 0
setattr(namespace, self.dest, count + 1)
new_count = _ensure_value(namespace, self.dest, 0) + 1
setattr(namespace, self.dest, new_count)


class _HelpAction(Action):
Expand Down Expand Up @@ -1077,21 +1064,19 @@ def __init__(self,
prog,
parser_class,
dest=SUPPRESS,
required=True,
help=None,
metavar=None):

self._prog_prefix = prog
self._parser_class = parser_class
self._name_parser_map = {}
self._name_parser_map = _collections.OrderedDict()
self._choices_actions = []

super(_SubParsersAction, self).__init__(
option_strings=option_strings,
dest=dest,
nargs=PARSER,
choices=self._name_parser_map,
required=required,
help=help,
metavar=metavar)

Expand Down Expand Up @@ -1362,14 +1347,13 @@ def add_argument(self, *args, **kwargs):

return self._add_action(action)

def add_argument_group(self, *args, **kwargs):
group = _ArgumentGroup(self, *args, **kwargs)
self._action_groups.append(group)
return group

def add_mutually_exclusive_group(self, **kwargs):
group = _MutuallyExclusiveGroup(self, **kwargs)
self._mutually_exclusive_groups.append(group)
def add_argument_group(self, *args, mutually_exclusive=False, **kwargs):
if mutually_exclusive:
group = _MutuallyExclusiveGroup(self, **kwargs)
self._mutually_exclusive_groups.append(group)
else:
group = _ArgumentGroup(self, *args, **kwargs)
self._action_groups.append(group)
return group

def _add_action(self, action):
Expand Down Expand Up @@ -2227,10 +2211,6 @@ def _get_nargs_pattern(self, action):
elif nargs == PARSER:
nargs_pattern = '(-*A[-AO]*)'

# suppress action, like nargs=0
elif nargs == SUPPRESS:
nargs_pattern = '(-*-*)'

# all others should be integers
else:
nargs_pattern = '(-*%s-*)' % '-*'.join('A' * nargs)
Expand All @@ -2243,91 +2223,6 @@ def _get_nargs_pattern(self, action):
# return the pattern
return nargs_pattern

# ========================
# Alt command line argument parsing, allowing free intermix
# ========================

def parse_intermixed_args(self, args=None, namespace=None):
args, argv = self.parse_known_intermixed_args(args, namespace)
if argv:
msg = _('unrecognized arguments: %s')
self.error(msg % ' '.join(argv))
return args

def parse_known_intermixed_args(self, args=None, namespace=None):
# returns a namespace and list of extras
#
# positional can be freely intermixed with optionals. optionals are
# first parsed with all positional arguments deactivated. The 'extras'
# are then parsed. If the parser definition is incompatible with the
# intermixed assumptions (e.g. use of REMAINDER, subparsers) a
# TypeError is raised.
#
# positionals are 'deactivated' by setting nargs and default to
# SUPPRESS. This blocks the addition of that positional to the
# namespace

positionals = self._get_positional_actions()
a = [action for action in positionals
if action.nargs in [PARSER, REMAINDER]]
if a:
raise TypeError('parse_intermixed_args: positional arg'
' with nargs=%s'%a[0].nargs)

if [action.dest for group in self._mutually_exclusive_groups
for action in group._group_actions if action in positionals]:
raise TypeError('parse_intermixed_args: positional in'
' mutuallyExclusiveGroup')

try:
save_usage = self.usage
try:
if self.usage is None:
# capture the full usage for use in error messages
self.usage = self.format_usage()[7:]
for action in positionals:
# deactivate positionals
action.save_nargs = action.nargs
# action.nargs = 0
action.nargs = SUPPRESS
action.save_default = action.default
action.default = SUPPRESS
namespace, remaining_args = self.parse_known_args(args,
namespace)
for action in positionals:
# remove the empty positional values from namespace
if (hasattr(namespace, action.dest)
and getattr(namespace, action.dest)==[]):
from warnings import warn
warn('Do not expect %s in %s' % (action.dest, namespace))
delattr(namespace, action.dest)
finally:
# restore nargs and usage before exiting
for action in positionals:
action.nargs = action.save_nargs
action.default = action.save_default
optionals = self._get_optional_actions()
try:
# parse positionals. optionals aren't normally required, but
# they could be, so make sure they aren't.
for action in optionals:
action.save_required = action.required
action.required = False
for group in self._mutually_exclusive_groups:
group.save_required = group.required
group.required = False
namespace, extras = self.parse_known_args(remaining_args,
namespace)
finally:
# restore parser values before exiting
for action in optionals:
action.required = action.save_required
for group in self._mutually_exclusive_groups:
group.required = group.save_required
finally:
self.usage = save_usage
return namespace, extras

# ========================
# Value conversion methods
# ========================
Expand Down Expand Up @@ -2374,10 +2269,6 @@ def _get_values(self, action, arg_strings):
value = [self._get_value(action, v) for v in arg_strings]
self._check_value(action, value[0])

# SUPPRESS argument does not put anything in the namespace
elif action.nargs == SUPPRESS:
value = SUPPRESS

# all other types of nargs produce a list
else:
value = [self._get_value(action, v) for v in arg_strings]
Expand Down