Update argparse.py from CPython v3.12.0

This commit is contained in:
NakanoMiku committed 2023-12-24 04:04:25 +08:00
1 parent dd0c393b45
commit 44438bffbd
1 file changed
+49 -15
+49 -15
View File
@@ -345,21 +345,22 @@ class HelpFormatter(object):
def get_lines(parts, indent, prefix=None):
lines = []
line = []
indent_length = len(indent)
if prefix is not None:
line_len = len(prefix) - 1
else:
line_len = len(indent) - 1
line_len = indent_length - 1
for part in parts:
if line_len + 1 + len(part) > text_width and line:
lines.append(indent + ' '.join(line))
line = []
line_len = len(indent) - 1
line_len = indent_length - 1
line.append(part)
line_len += len(part) + 1
if line:
lines.append(indent + ' '.join(line))
if prefix is not None:
lines[0] = lines[0][len(indent):]
lines[0] = lines[0][indent_length:]
return lines
# if prog is short, follow it with optionals or positionals
@@ -403,10 +404,18 @@ class HelpFormatter(object):
except ValueError:
continue
else:
end = start + len(group._group_actions)
group_action_count = len(group._group_actions)
end = start + group_action_count
if actions[start:end] == group._group_actions:
suppressed_actions_count = 0
for action in group._group_actions:
group_actions.add(action)
if action.help is SUPPRESS:
suppressed_actions_count += 1
exposed_actions_count = group_action_count - suppressed_actions_count
if not group.required:
if start in inserts:
inserts[start] += ' ['
@@ -416,7 +425,7 @@ class HelpFormatter(object):
inserts[end] += ']'
else:
inserts[end] = ']'
else:
elif exposed_actions_count > 1:
if start in inserts:
inserts[start] += ' ('
else:
@@ -490,7 +499,6 @@ class HelpFormatter(object):
text = _re.sub(r'(%s) ' % open, r'\1', text)
text = _re.sub(r' (%s)' % close, r'\1', text)
text = _re.sub(r'%s *%s' % (open, close), r'', text)
text = _re.sub(r'\(([^|]*)\)', r'\1', text)
text = text.strip()
# return the text
@@ -875,16 +883,19 @@ class Action(_AttributeHolder):
raise NotImplementedError(_('.__call__() not defined'))
# FIXME: remove together with `BooleanOptionalAction` deprecated arguments.
_deprecated_default = object()
class BooleanOptionalAction(Action):
def __init__(self,
option_strings,
dest,
default=None,
type=None,
choices=None,
type=_deprecated_default,
choices=_deprecated_default,
required=False,
help=None,
metavar=None):
metavar=_deprecated_default):
_option_strings = []
for option_string in option_strings:
@@ -894,6 +905,24 @@ class BooleanOptionalAction(Action):
option_string = '--no-' + option_string[2:]
_option_strings.append(option_string)
# We need `_deprecated` special value to ban explicit arguments that
# match default value. Like:
# parser.add_argument('-f', action=BooleanOptionalAction, type=int)
for field_name in ('type', 'choices', 'metavar'):
if locals()[field_name] is not _deprecated_default:
warnings._deprecated(
field_name,
"{name!r} is deprecated as of Python 3.12 and will be "
"removed in Python {remove}.",
remove=(3, 14))
if type is _deprecated_default:
type = None
if choices is _deprecated_default:
choices = None
if metavar is _deprecated_default:
metavar = None
super().__init__(
option_strings=_option_strings,
dest=dest,
@@ -2165,7 +2194,9 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
# replace arguments referencing files with the file content
else:
try:
with open(arg_string[1:]) as args_file:
with open(arg_string[1:],
encoding=_sys.getfilesystemencoding(),
errors=_sys.getfilesystemencodeerrors()) as args_file:
arg_strings = []
for arg_line in args_file.read().splitlines():
for arg in self.convert_arg_line_to_args(arg_line):
@@ -2479,9 +2510,11 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
not action.option_strings):
if action.default is not None:
value = action.default
self._check_value(action, value)
else:
# since arg_strings is always [] at this point
# there is no need to use self._check_value(action, value)
value = arg_strings
self._check_value(action, value)
# single argument or optional argument produces a single value
elif len(arg_strings) == 1 and action.nargs in [None, OPTIONAL]:
@@ -2523,7 +2556,6 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
# ArgumentTypeErrors indicate errors
except ArgumentTypeError as err:
name = getattr(action.type, '__name__', repr(action.type))
msg = str(err)
raise ArgumentError(action, msg)
@@ -2595,9 +2627,11 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
def _print_message(self, message, file=None):
if message:
if file is None:
file = _sys.stderr
file.write(message)
file = file or _sys.stderr
try:
file.write(message)
except (AttributeError, OSError):
pass
# ===============
# Exiting methods