Commit f4511124 authored by Serhiy Storchaka's avatar Serhiy Storchaka

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.
parent 32c4915b
......@@ -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)
......
......@@ -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."""
......
......@@ -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"""
......
......@@ -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)
......
......@@ -430,6 +430,7 @@ Marius Gedminas
Thomas Gellekum
Gabriel Genellina
Christos Georgiou
Elazar Gershuni
Ben Gertzfield
Nadim Ghaznavi
Dinu Gherman
......
......@@ -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.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment