aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/Lib/argparse.py
diff options
context:
space:
mode:
authorshadchin <shadchin@yandex-team.com>2024-10-27 10:52:33 +0300
committershadchin <shadchin@yandex-team.com>2024-10-27 11:03:47 +0300
commit1529383373617c6d14ad4972afdc46a5eb35f954 (patch)
tree229b7647fafadd4ee4b93d20e606c534ad697365 /contrib/tools/python3/Lib/argparse.py
parent41d598c624442bf6918407466dac3316b8277347 (diff)
downloadydb-1529383373617c6d14ad4972afdc46a5eb35f954.tar.gz
Update Python 3 to 3.12.7
commit_hash:052a122399d67f1ea5dfbc5f6457e3e06200becf
Diffstat (limited to 'contrib/tools/python3/Lib/argparse.py')
-rw-r--r--contrib/tools/python3/Lib/argparse.py139
1 files changed, 70 insertions, 69 deletions
diff --git a/contrib/tools/python3/Lib/argparse.py b/contrib/tools/python3/Lib/argparse.py
index e4892955e4f..3d01415fcf2 100644
--- a/contrib/tools/python3/Lib/argparse.py
+++ b/contrib/tools/python3/Lib/argparse.py
@@ -263,13 +263,12 @@ class HelpFormatter(object):
# find all invocations
get_invocation = self._format_action_invocation
- invocations = [get_invocation(action)]
+ invocation_lengths = [len(get_invocation(action)) + self._current_indent]
for subaction in self._iter_indented_subactions(action):
- invocations.append(get_invocation(subaction))
+ invocation_lengths.append(len(get_invocation(subaction)) + self._current_indent)
# update the maximum item length
- invocation_length = max(map(len, invocations))
- action_length = invocation_length + self._current_indent
+ action_length = max(invocation_lengths)
self._action_max_length = max(self._action_max_length,
action_length)
@@ -1270,7 +1269,8 @@ class _SubParsersAction(Action):
setattr(namespace, key, value)
if arg_strings:
- vars(namespace).setdefault(_UNRECOGNIZED_ARGS_ATTR, [])
+ if not hasattr(namespace, _UNRECOGNIZED_ARGS_ATTR):
+ setattr(namespace, _UNRECOGNIZED_ARGS_ATTR, [])
getattr(namespace, _UNRECOGNIZED_ARGS_ATTR).extend(arg_strings)
class _ExtendAction(_AppendAction):
@@ -1576,9 +1576,8 @@ class _ActionsContainer(object):
# mark positional arguments as required if at least one is
# always required
- if kwargs.get('nargs') not in [OPTIONAL, ZERO_OR_MORE]:
- kwargs['required'] = True
- if kwargs.get('nargs') == ZERO_OR_MORE and 'default' not in kwargs:
+ nargs = kwargs.get('nargs')
+ if nargs not in [OPTIONAL, ZERO_OR_MORE, REMAINDER, SUPPRESS, 0]:
kwargs['required'] = True
# return the keyword arguments with no option strings
@@ -1849,8 +1848,8 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
kwargs.setdefault('parser_class', type(self))
if 'title' in kwargs or 'description' in kwargs:
- title = _(kwargs.pop('title', 'subcommands'))
- description = _(kwargs.pop('description', None))
+ title = kwargs.pop('title', _('subcommands'))
+ description = kwargs.pop('description', None)
self._subparsers = self.add_argument_group(title, description)
else:
self._subparsers = self._positionals
@@ -1972,11 +1971,11 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
# otherwise, add the arg to the arg strings
# and note the index if it was an option
else:
- option_tuple = self._parse_optional(arg_string)
- if option_tuple is None:
+ option_tuples = self._parse_optional(arg_string)
+ if option_tuples is None:
pattern = 'A'
else:
- option_string_indices[i] = option_tuple
+ option_string_indices[i] = option_tuples
pattern = 'O'
arg_string_pattern_parts.append(pattern)
@@ -1992,9 +1991,8 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
argument_values = 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 arguments
+ if action.option_strings or argument_strings:
seen_non_default_actions.add(action)
for conflict_action in action_conflicts.get(action, []):
if conflict_action in seen_non_default_actions:
@@ -2011,8 +2009,16 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
def consume_optional(start_index):
# get the optional identified at this index
- option_tuple = option_string_indices[start_index]
- action, option_string, sep, explicit_arg = option_tuple
+ option_tuples = option_string_indices[start_index]
+ # if multiple actions match, the option string was ambiguous
+ if len(option_tuples) > 1:
+ options = ', '.join([option_string
+ for action, option_string, sep, explicit_arg in option_tuples])
+ args = {'option': arg_string, 'matches': options}
+ msg = _('ambiguous option: %(option)s could match %(matches)s')
+ raise ArgumentError(None, msg % args)
+
+ action, option_string, sep, explicit_arg = option_tuples[0]
# identify additional optionals in the same arg string
# (e.g. -xyz is the same as -x -y -z if no args are required)
@@ -2108,6 +2114,15 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
# and add the Positional and its args to the list
for action, arg_count in zip(positionals, arg_counts):
args = arg_strings[start_index: start_index + arg_count]
+ # Strip out the first '--' if it is not in REMAINDER arg.
+ if action.nargs == PARSER:
+ if arg_strings_pattern[start_index] == '-':
+ assert args[0] == '--'
+ args.remove('--')
+ elif action.nargs != REMAINDER:
+ if (arg_strings_pattern.find('-', start_index,
+ start_index + arg_count) >= 0):
+ args.remove('--')
start_index += arg_count
take_action(action, args)
@@ -2254,18 +2269,19 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
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 = []
for i in range(len(actions), 0, -1):
actions_slice = actions[:i]
pattern = ''.join([self._get_nargs_pattern(action)
for action in actions_slice])
match = _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
+ result = [len(string) for string in match.groups()]
+ if (match.end() < len(arg_strings_pattern)
+ and arg_strings_pattern[match.end()] == 'O'):
+ while result and not result[-1]:
+ del result[-1]
+ return result
+ return []
def _parse_optional(self, arg_string):
# if it's an empty string, it was meant to be a positional
@@ -2279,7 +2295,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
# if the option string is present in the parser, return the action
if arg_string in self._option_string_actions:
action = self._option_string_actions[arg_string]
- return action, arg_string, None, None
+ return [(action, arg_string, None, None)]
# if it's just a single character, it was meant to be positional
if len(arg_string) == 1:
@@ -2289,25 +2305,14 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
option_string, sep, explicit_arg = arg_string.partition('=')
if sep and option_string in self._option_string_actions:
action = self._option_string_actions[option_string]
- return action, option_string, sep, explicit_arg
+ return [(action, option_string, sep, explicit_arg)]
# search through all possible prefixes of the option string
# and all actions in the parser for possible interpretations
option_tuples = self._get_option_tuples(arg_string)
- # if multiple actions match, the option string was ambiguous
- if len(option_tuples) > 1:
- options = ', '.join([option_string
- for action, option_string, sep, explicit_arg in option_tuples])
- args = {'option': arg_string, 'matches': options}
- msg = _('ambiguous option: %(option)s could match %(matches)s')
- raise ArgumentError(None, msg % args)
-
- # if exactly one action matched, this segmentation is good,
- # so return the parsed action
- elif len(option_tuples) == 1:
- option_tuple, = option_tuples
- return option_tuple
+ if option_tuples:
+ return option_tuples
# if it was not found as an option, but it looks like a negative
# number, it was meant to be positional
@@ -2322,7 +2327,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
# 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, None
+ return [(None, arg_string, None, None)]
def _get_option_tuples(self, option_string):
result = []
@@ -2345,7 +2350,9 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
# 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 = option_string
+ option_prefix, sep, explicit_arg = option_string.partition('=')
+ if not sep:
+ sep = explicit_arg = None
short_option_prefix = option_string[:2]
short_explicit_arg = option_string[2:]
@@ -2354,9 +2361,9 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
action = self._option_string_actions[option_string]
tup = action, option_string, '', short_explicit_arg
result.append(tup)
- elif option_string.startswith(option_prefix):
+ elif self.allow_abbrev and option_string.startswith(option_prefix):
action = self._option_string_actions[option_string]
- tup = action, option_string, None, None
+ tup = action, option_string, sep, explicit_arg
result.append(tup)
# shouldn't ever get here
@@ -2370,43 +2377,40 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
# in all examples below, we have to allow for '--' args
# which are represented as '-' in the pattern
nargs = action.nargs
+ # if this is an optional action, -- is not allowed
+ option = action.option_strings
# the default (None) is assumed to be a single argument
if nargs is None:
- nargs_pattern = '(-*A-*)'
+ nargs_pattern = '([A])' if option else '(-*A-*)'
# allow zero or one arguments
elif nargs == OPTIONAL:
- nargs_pattern = '(-*A?-*)'
+ nargs_pattern = '(A?)' if option else '(-*A?-*)'
# allow zero or more arguments
elif nargs == ZERO_OR_MORE:
- nargs_pattern = '(-*[A-]*)'
+ nargs_pattern = '(A*)' if option else '(-*[A-]*)'
# allow one or more arguments
elif nargs == ONE_OR_MORE:
- nargs_pattern = '(-*A[A-]*)'
+ nargs_pattern = '(A+)' if option else '(-*A[A-]*)'
# allow any number of options or arguments
elif nargs == REMAINDER:
- nargs_pattern = '([-AO]*)'
+ nargs_pattern = '([AO]*)' if option else '(.*)'
# allow one argument followed by any number of options or arguments
elif nargs == PARSER:
- nargs_pattern = '(-*A[-AO]*)'
+ nargs_pattern = '(A[AO]*)' if option else '(-*A[-AO]*)'
# suppress action, like nargs=0
elif nargs == SUPPRESS:
- nargs_pattern = '(-*-*)'
+ nargs_pattern = '()' if option else '(-*)'
# all others should be integers
else:
- nargs_pattern = '(-*%s-*)' % '-*'.join('A' * nargs)
-
- # if this is an optional action, -- is not allowed
- if action.option_strings:
- nargs_pattern = nargs_pattern.replace('-*', '')
- nargs_pattern = nargs_pattern.replace('-', '')
+ nargs_pattern = '([AO]{%d})' % nargs if option else '((?:-*A){%d}-*)' % nargs
# return the pattern
return nargs_pattern
@@ -2503,20 +2507,13 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
# Value conversion methods
# ========================
def _get_values(self, action, arg_strings):
- # for everything but PARSER, REMAINDER args, strip out first '--'
- if not action.option_strings and action.nargs not in [PARSER, REMAINDER]:
- try:
- arg_strings.remove('--')
- except ValueError:
- pass
-
# optional argument produces a default when not present
if not arg_strings and action.nargs == OPTIONAL:
if action.option_strings:
value = action.const
else:
value = action.default
- if isinstance(value, str):
+ if isinstance(value, str) and value is not SUPPRESS:
value = self._get_value(action, value)
self._check_value(action, value)
@@ -2587,11 +2584,15 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
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:
- args = {'value': value,
- 'choices': ', '.join(map(repr, action.choices))}
- msg = _('invalid choice: %(value)r (choose from %(choices)s)')
- raise ArgumentError(action, msg % args)
+ choices = action.choices
+ if choices is not None:
+ if isinstance(choices, str):
+ choices = iter(choices)
+ if value not in choices:
+ args = {'value': value,
+ 'choices': ', '.join(map(repr, action.choices))}
+ msg = _('invalid choice: %(value)r (choose from %(choices)s)')
+ raise ArgumentError(action, msg % args)
# =======================
# Help-formatting methods