mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
Issue #13107: argparse and optparse no longer raises an exception when output
a help on environment with too small COLUMNS. Based on patch by Elazar Gershuni.
This commit is contained in:
commit
123e6d5b4b
5 changed files with 102 additions and 6 deletions
|
@ -165,6 +165,8 @@ class HelpFormatter(object):
|
||||||
self._prog = prog
|
self._prog = prog
|
||||||
self._indent_increment = indent_increment
|
self._indent_increment = indent_increment
|
||||||
self._max_help_position = max_help_position
|
self._max_help_position = max_help_position
|
||||||
|
self._max_help_position = min(max_help_position,
|
||||||
|
max(width - 20, indent_increment * 2))
|
||||||
self._width = width
|
self._width = width
|
||||||
|
|
||||||
self._current_indent = 0
|
self._current_indent = 0
|
||||||
|
@ -336,7 +338,7 @@ class HelpFormatter(object):
|
||||||
else:
|
else:
|
||||||
line_len = len(indent) - 1
|
line_len = len(indent) - 1
|
||||||
for part in parts:
|
for part in parts:
|
||||||
if line_len + 1 + len(part) > text_width:
|
if line_len + 1 + len(part) > text_width and line:
|
||||||
lines.append(indent + ' '.join(line))
|
lines.append(indent + ' '.join(line))
|
||||||
line = []
|
line = []
|
||||||
line_len = len(indent) - 1
|
line_len = len(indent) - 1
|
||||||
|
@ -476,7 +478,7 @@ class HelpFormatter(object):
|
||||||
def _format_text(self, text):
|
def _format_text(self, text):
|
||||||
if '%(prog)' in text:
|
if '%(prog)' in text:
|
||||||
text = text % dict(prog=self._prog)
|
text = text % dict(prog=self._prog)
|
||||||
text_width = self._width - self._current_indent
|
text_width = max(self._width - self._current_indent, 11)
|
||||||
indent = ' ' * self._current_indent
|
indent = ' ' * self._current_indent
|
||||||
return self._fill_text(text, text_width, indent) + '\n\n'
|
return self._fill_text(text, text_width, indent) + '\n\n'
|
||||||
|
|
||||||
|
@ -484,7 +486,7 @@ class HelpFormatter(object):
|
||||||
# determine the required width and the entry label
|
# determine the required width and the entry label
|
||||||
help_position = min(self._action_max_length + 2,
|
help_position = min(self._action_max_length + 2,
|
||||||
self._max_help_position)
|
self._max_help_position)
|
||||||
help_width = self._width - help_position
|
help_width = max(self._width - help_position, 11)
|
||||||
action_width = help_position - self._current_indent - 2
|
action_width = help_position - self._current_indent - 2
|
||||||
action_header = self._format_action_invocation(action)
|
action_header = self._format_action_invocation(action)
|
||||||
|
|
||||||
|
|
|
@ -209,7 +209,6 @@ class HelpFormatter:
|
||||||
short_first):
|
short_first):
|
||||||
self.parser = None
|
self.parser = None
|
||||||
self.indent_increment = indent_increment
|
self.indent_increment = indent_increment
|
||||||
self.help_position = self.max_help_position = max_help_position
|
|
||||||
if width is None:
|
if width is None:
|
||||||
try:
|
try:
|
||||||
width = int(os.environ['COLUMNS'])
|
width = int(os.environ['COLUMNS'])
|
||||||
|
@ -217,6 +216,8 @@ class HelpFormatter:
|
||||||
width = 80
|
width = 80
|
||||||
width -= 2
|
width -= 2
|
||||||
self.width = width
|
self.width = width
|
||||||
|
self.help_position = self.max_help_position = \
|
||||||
|
min(max_help_position, max(width - 20, indent_increment * 2))
|
||||||
self.current_indent = 0
|
self.current_indent = 0
|
||||||
self.level = 0
|
self.level = 0
|
||||||
self.help_width = None # computed later
|
self.help_width = None # computed later
|
||||||
|
@ -261,7 +262,7 @@ class HelpFormatter:
|
||||||
Format a paragraph of free-form text for inclusion in the
|
Format a paragraph of free-form text for inclusion in the
|
||||||
help output at the current indentation level.
|
help output at the current indentation level.
|
||||||
"""
|
"""
|
||||||
text_width = self.width - self.current_indent
|
text_width = max(self.width - self.current_indent, 11)
|
||||||
indent = " "*self.current_indent
|
indent = " "*self.current_indent
|
||||||
return textwrap.fill(text,
|
return textwrap.fill(text,
|
||||||
text_width,
|
text_width,
|
||||||
|
@ -342,7 +343,7 @@ class HelpFormatter:
|
||||||
self.dedent()
|
self.dedent()
|
||||||
self.dedent()
|
self.dedent()
|
||||||
self.help_position = min(max_len + 2, self.max_help_position)
|
self.help_position = min(max_len + 2, self.max_help_position)
|
||||||
self.help_width = self.width - self.help_position
|
self.help_width = max(self.width - self.help_position, 11)
|
||||||
|
|
||||||
def format_option_strings(self, option):
|
def format_option_strings(self, option):
|
||||||
"""Return a comma-separated list of option strings & metavariables."""
|
"""Return a comma-separated list of option strings & metavariables."""
|
||||||
|
|
|
@ -3005,6 +3005,60 @@ class TestHelpBiggerOptionals(HelpTestCase):
|
||||||
0.1
|
0.1
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
class TestShortColumns(HelpTestCase):
|
||||||
|
'''Test extremely small number of columns.
|
||||||
|
|
||||||
|
TestCase prevents "COLUMNS" from being too small in the tests themselves,
|
||||||
|
but we don't want any exceptions thrown in such case. Only ugly representation.
|
||||||
|
'''
|
||||||
|
def setUp(self):
|
||||||
|
env = support.EnvironmentVarGuard()
|
||||||
|
env.set("COLUMNS", '15')
|
||||||
|
self.addCleanup(env.__exit__)
|
||||||
|
|
||||||
|
parser_signature = TestHelpBiggerOptionals.parser_signature
|
||||||
|
argument_signatures = TestHelpBiggerOptionals.argument_signatures
|
||||||
|
argument_group_signatures = TestHelpBiggerOptionals.argument_group_signatures
|
||||||
|
usage = '''\
|
||||||
|
usage: PROG
|
||||||
|
[-h]
|
||||||
|
[-v]
|
||||||
|
[-x]
|
||||||
|
[--y Y]
|
||||||
|
foo
|
||||||
|
bar
|
||||||
|
'''
|
||||||
|
help = usage + '''\
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
|
||||||
|
positional arguments:
|
||||||
|
foo
|
||||||
|
FOO HELP
|
||||||
|
bar
|
||||||
|
BAR HELP
|
||||||
|
|
||||||
|
optional arguments:
|
||||||
|
-h, --help
|
||||||
|
show this
|
||||||
|
help
|
||||||
|
message and
|
||||||
|
exit
|
||||||
|
-v, --version
|
||||||
|
show
|
||||||
|
program's
|
||||||
|
version
|
||||||
|
number and
|
||||||
|
exit
|
||||||
|
-x
|
||||||
|
X HELP
|
||||||
|
--y Y
|
||||||
|
Y HELP
|
||||||
|
|
||||||
|
EPILOG
|
||||||
|
'''
|
||||||
|
version = TestHelpBiggerOptionals.version
|
||||||
|
|
||||||
|
|
||||||
class TestHelpBiggerOptionalGroups(HelpTestCase):
|
class TestHelpBiggerOptionalGroups(HelpTestCase):
|
||||||
"""Make sure that argument help aligns when options are longer"""
|
"""Make sure that argument help aligns when options are longer"""
|
||||||
|
|
|
@ -1443,6 +1443,39 @@ Options:
|
||||||
-h, --help show this help message and exit
|
-h, --help show this help message and exit
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
_expected_very_help_short_lines = """\
|
||||||
|
Usage: bar.py [options]
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-a APPLE
|
||||||
|
throw
|
||||||
|
APPLEs at
|
||||||
|
basket
|
||||||
|
-b NUM, --boo=NUM
|
||||||
|
shout
|
||||||
|
"boo!" NUM
|
||||||
|
times (in
|
||||||
|
order to
|
||||||
|
frighten
|
||||||
|
away all
|
||||||
|
the evil
|
||||||
|
spirits
|
||||||
|
that cause
|
||||||
|
trouble and
|
||||||
|
mayhem)
|
||||||
|
--foo=FOO
|
||||||
|
store FOO
|
||||||
|
in the foo
|
||||||
|
list for
|
||||||
|
later
|
||||||
|
fooing
|
||||||
|
-h, --help
|
||||||
|
show this
|
||||||
|
help
|
||||||
|
message and
|
||||||
|
exit
|
||||||
|
"""
|
||||||
|
|
||||||
class TestHelp(BaseTest):
|
class TestHelp(BaseTest):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.parser = self.make_parser(80)
|
self.parser = self.make_parser(80)
|
||||||
|
@ -1500,6 +1533,8 @@ class TestHelp(BaseTest):
|
||||||
# we look at $COLUMNS.
|
# we look at $COLUMNS.
|
||||||
self.parser = self.make_parser(60)
|
self.parser = self.make_parser(60)
|
||||||
self.assertHelpEquals(_expected_help_short_lines)
|
self.assertHelpEquals(_expected_help_short_lines)
|
||||||
|
self.parser = self.make_parser(0)
|
||||||
|
self.assertHelpEquals(_expected_very_help_short_lines)
|
||||||
|
|
||||||
def test_help_unicode(self):
|
def test_help_unicode(self):
|
||||||
self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE)
|
self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE)
|
||||||
|
|
|
@ -25,6 +25,10 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #13107: argparse and optparse no longer raises an exception when output
|
||||||
|
a help on environment with too small COLUMNS. Based on patch by
|
||||||
|
Elazar Gershuni.
|
||||||
|
|
||||||
- Issue #20207: Always disable SSLv2 except when PROTOCOL_SSLv2 is explicitly
|
- Issue #20207: Always disable SSLv2 except when PROTOCOL_SSLv2 is explicitly
|
||||||
asked for.
|
asked for.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue