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:
Serhiy Storchaka 2014-01-09 23:14:27 +02:00
parent 32c4915b23
commit f451112413
6 changed files with 103 additions and 6 deletions

View File

@ -165,6 +165,8 @@ class HelpFormatter(object):
self._prog = prog
self._indent_increment = indent_increment
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._current_indent = 0
@ -336,7 +338,7 @@ class HelpFormatter(object):
else:
line_len = len(indent) - 1
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))
line = []
line_len = len(indent) - 1
@ -476,7 +478,7 @@ class HelpFormatter(object):
def _format_text(self, text):
if '%(prog)' in text:
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
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
help_position = min(self._action_max_length + 2,
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_header = self._format_action_invocation(action)

View File

@ -209,7 +209,6 @@ class HelpFormatter:
short_first):
self.parser = None
self.indent_increment = indent_increment
self.help_position = self.max_help_position = max_help_position
if width is None:
try:
width = int(os.environ['COLUMNS'])
@ -217,6 +216,8 @@ class HelpFormatter:
width = 80
width -= 2
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.level = 0
self.help_width = None # computed later
@ -261,7 +262,7 @@ class HelpFormatter:
Format a paragraph of free-form text for inclusion in the
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
return textwrap.fill(text,
text_width,
@ -342,7 +343,7 @@ class HelpFormatter:
self.dedent()
self.dedent()
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):
"""Return a comma-separated list of option strings & metavariables."""

View File

@ -2973,6 +2973,60 @@ class TestHelpBiggerOptionals(HelpTestCase):
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):
"""Make sure that argument help aligns when options are longer"""

View File

@ -1443,6 +1443,39 @@ Options:
-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):
def setUp(self):
self.parser = self.make_parser(80)
@ -1500,6 +1533,8 @@ class TestHelp(BaseTest):
# we look at $COLUMNS.
self.parser = self.make_parser(60)
self.assertHelpEquals(_expected_help_short_lines)
self.parser = self.make_parser(0)
self.assertHelpEquals(_expected_very_help_short_lines)
def test_help_unicode(self):
self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE)

View File

@ -430,6 +430,7 @@ Marius Gedminas
Thomas Gellekum
Gabriel Genellina
Christos Georgiou
Elazar Gershuni
Ben Gertzfield
Nadim Ghaznavi
Dinu Gherman

View File

@ -43,6 +43,10 @@ Core and Builtins
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
asked for.